@stellar-expert/ui-framework 1.16.8 → 1.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +35 -0
- package/README.md +1125 -3
- package/account/account-address.js +127 -127
- package/account/available-balance.js +22 -22
- package/account/identicon.js +90 -90
- package/account/signer-key.js +65 -64
- package/api/explorer-api-hooks.js +209 -202
- package/api/explorer-api-paginated-list-hooks.js +441 -440
- package/api/explorer-batch-info-loader.js +111 -85
- package/api/explorer-tx-api.js +28 -28
- package/api/ledger-stream.js +15 -0
- package/asset/amount.js +56 -56
- package/asset/asset-icon.js +41 -41
- package/asset/asset-issuer.js +21 -21
- package/asset/asset-link.js +107 -107
- package/asset/asset-list-hooks.js +59 -59
- package/asset/asset-meta-hooks.js +88 -88
- package/asset/asset-selector.js +72 -71
- package/claimable-balance/claimable-balance-claimants.js +23 -18
- package/contract/contract-api.js +15 -0
- package/contract/invocation-info-view.js +10 -2
- package/contract/sc-val.js +131 -107
- package/controls/button-group.js +25 -19
- package/controls/button.js +93 -78
- package/controls/code-block.js +42 -34
- package/controls/dropdown.js +318 -287
- package/controls/external-link.js +10 -4
- package/controls/info-tooltip.js +23 -16
- package/controls/slider.js +29 -19
- package/controls/tabs.js +94 -94
- package/controls/tooltip.js +244 -240
- package/controls/update-highlighter.js +32 -27
- package/date/date-selector.js +56 -54
- package/date/elapsed-time.js +28 -21
- package/dex/price-dynamic.js +53 -44
- package/directory/directory-hooks.js +109 -97
- package/effect/effect-description.js +346 -344
- package/errors/error-boundary.js +110 -97
- package/horizon/horizon-account-helpers.js +104 -104
- package/horizon/horizon-ledger-helpers.js +35 -35
- package/horizon/horizon-trades-helper.js +88 -88
- package/horizon/horizon-transaction-helpers.js +36 -36
- package/index.d.ts +1241 -0
- package/interaction/accordion.js +43 -35
- package/interaction/autofocus.js +13 -9
- package/interaction/block-select.js +64 -53
- package/interaction/copy-to-clipboard.js +25 -18
- package/interaction/inline-progress.js +20 -15
- package/interaction/qr-code.js +34 -34
- package/interaction/responsive.js +20 -20
- package/interaction/spoiler.js +52 -39
- package/interaction/theme-selector.js +13 -10
- package/ledger/ledger-entry-href-formatter.js +27 -26
- package/ledger/ledger-entry-link.js +93 -58
- package/ledger/ledger-info-parser.js +46 -18
- package/meta/page-meta-tags.js +243 -238
- package/module/dynamic-module.js +47 -47
- package/package.json +41 -40
- package/state/on-screen-hooks.js +22 -22
- package/state/page-visibility-helpers.js +29 -16
- package/state/page-visibility-hooks.js +13 -11
- package/state/screen-orientation-hooks.js +19 -15
- package/state/state-hooks.js +76 -76
- package/state/stellar-network-hooks.js +56 -44
- package/state/theme.js +29 -28
- package/stellar/key-type.js +92 -91
- package/stellar/ledger-generic-id.js +39 -39
- package/stellar/signature-hint-utils.js +65 -65
- package/toast/toast-notifications-block.js +59 -59
- package/tx/op-description-view.js +945 -942
- package/tx/op-icon.js +98 -98
- package/tx/parser/op-balance-changes.js +66 -66
- package/tx/parser/op-descriptor.js +51 -48
- package/tx/parser/tx-details-parser.js +81 -81
- package/tx/parser/tx-matcher.js +371 -371
- package/tx/parser/type-filter-matcher.js +126 -126
- package/tx/tx-list-hooks.js +32 -18
- package/tx/tx-operations-list.js +117 -116
|
@@ -1,942 +1,945 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import {Networks, AuthRequiredFlag, AuthRevocableFlag, AuthClawbackEnabledFlag, AuthImmutableFlag} from '@stellar/stellar-base'
|
|
3
|
-
import {AssetDescriptor} from '@stellar-expert/asset-descriptor'
|
|
4
|
-
import {formatPrice, formatWithAutoPrecision, fromStroops, toStroops, shortenString} from '@stellar-expert/formatter'
|
|
5
|
-
import {xdrParserUtils, contractPreimageEncoder} from '@stellar-expert/tx-meta-effects-parser'
|
|
6
|
-
import {AccountAddress} from '../account/account-address'
|
|
7
|
-
import {AccountIdenticon} from '../account/identicon'
|
|
8
|
-
import {SignerKey} from '../account/signer-key'
|
|
9
|
-
import {Amount} from '../asset/amount'
|
|
10
|
-
import {AssetLink} from '../asset/asset-link'
|
|
11
|
-
import {useAssetMeta} from '../asset/asset-meta-hooks'
|
|
12
|
-
import {OfferLink} from '../ledger/ledger-entry-link'
|
|
13
|
-
import {formatExplorerLink} from '../ledger/ledger-entry-href-formatter'
|
|
14
|
-
import {ClaimableBalanceClaimants} from '../claimable-balance/claimable-balance-claimants'
|
|
15
|
-
import {CopyToClipboard} from '../interaction/copy-to-clipboard'
|
|
16
|
-
import {useStellarNetwork} from '../state/stellar-network-hooks'
|
|
17
|
-
import InvocationInfoView from '../contract/invocation-info-view'
|
|
18
|
-
import {ClaimableBalanceId} from '../claimable-balance/claimable-balance-id'
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
<
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
{
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
</div>
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
if (
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
}
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
}
|
|
702
|
-
const
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
}
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import {Networks, AuthRequiredFlag, AuthRevocableFlag, AuthClawbackEnabledFlag, AuthImmutableFlag} from '@stellar/stellar-base'
|
|
3
|
+
import {AssetDescriptor} from '@stellar-expert/asset-descriptor'
|
|
4
|
+
import {formatPrice, formatWithAutoPrecision, fromStroops, toStroops, shortenString} from '@stellar-expert/formatter'
|
|
5
|
+
import {xdrParserUtils, contractPreimageEncoder} from '@stellar-expert/tx-meta-effects-parser'
|
|
6
|
+
import {AccountAddress} from '../account/account-address'
|
|
7
|
+
import {AccountIdenticon} from '../account/identicon'
|
|
8
|
+
import {SignerKey} from '../account/signer-key'
|
|
9
|
+
import {Amount} from '../asset/amount'
|
|
10
|
+
import {AssetLink} from '../asset/asset-link'
|
|
11
|
+
import {useAssetMeta} from '../asset/asset-meta-hooks'
|
|
12
|
+
import {OfferLink} from '../ledger/ledger-entry-link'
|
|
13
|
+
import {formatExplorerLink} from '../ledger/ledger-entry-href-formatter'
|
|
14
|
+
import {ClaimableBalanceClaimants} from '../claimable-balance/claimable-balance-claimants'
|
|
15
|
+
import {CopyToClipboard} from '../interaction/copy-to-clipboard'
|
|
16
|
+
import {useStellarNetwork} from '../state/stellar-network-hooks'
|
|
17
|
+
import InvocationInfoView from '../contract/invocation-info-view'
|
|
18
|
+
import {ClaimableBalanceId} from '../claimable-balance/claimable-balance-id'
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Detailed operation description within a transaction
|
|
22
|
+
* @param {OperationDescriptor} op
|
|
23
|
+
* @param {boolean} [compact]
|
|
24
|
+
* @constructor
|
|
25
|
+
*/
|
|
26
|
+
export const OpDescriptionView = React.memo(function OpDescriptionView({op, compact = false}) {
|
|
27
|
+
const render = typeMapping[op.operation.type]
|
|
28
|
+
if (!render) {
|
|
29
|
+
console.warn(`No operation text type mapping for operation ${op.operation.type}`)
|
|
30
|
+
return null
|
|
31
|
+
}
|
|
32
|
+
return React.createElement(render, {op, compact})
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Renders operation source account
|
|
37
|
+
* @param {OperationDescriptor} op
|
|
38
|
+
* @param {boolean} compact
|
|
39
|
+
* @constructor
|
|
40
|
+
*/
|
|
41
|
+
function OpSourceAccount({op, compact}) {
|
|
42
|
+
const network = useStellarNetwork()
|
|
43
|
+
const {source} = op.operation
|
|
44
|
+
const txSource = op.tx.tx.source
|
|
45
|
+
if (op.isEphemeral && (!source || source === txSource))
|
|
46
|
+
return null
|
|
47
|
+
const predefined = getAccountPredefinedDisplayName(source)
|
|
48
|
+
const accountItem = predefined ?
|
|
49
|
+
<a href={formatExplorerLink('account', source, network)} target="_blank" rel="nofollow noreferrer">
|
|
50
|
+
<AccountIdenticon address={source}/> {predefined}
|
|
51
|
+
</a> :
|
|
52
|
+
<AccountAddress account={source}/>
|
|
53
|
+
|
|
54
|
+
if (!op.isEphemeral)
|
|
55
|
+
return accountItem
|
|
56
|
+
return <> for account {accountItem}</>
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* CreateAccount operation (type 0)
|
|
62
|
+
* @param {OperationDescriptor} op
|
|
63
|
+
* @param {boolean} compact
|
|
64
|
+
* @constructor
|
|
65
|
+
*/
|
|
66
|
+
function CreateAccountDescriptionView({op, compact}) {
|
|
67
|
+
const {destination, startingBalance} = op.operation
|
|
68
|
+
return op.isEphemeral ? <>
|
|
69
|
+
<b>Create account</b> <AccountAddress account={destination}/>{' '}
|
|
70
|
+
with starting balance <Amount amount={startingBalance} asset="XLM" issuer={!compact}/>
|
|
71
|
+
<OpSourceAccount op={op}/>
|
|
72
|
+
</> : <>
|
|
73
|
+
<OpSourceAccount op={op}/> created account <AccountAddress account={destination}/>{' '}
|
|
74
|
+
with starting balance <Amount amount={startingBalance} asset="XLM" issuer={!compact}/>
|
|
75
|
+
</>
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Payment operation (type 1)
|
|
80
|
+
* @param {OperationDescriptor} op
|
|
81
|
+
* @param {boolean} compact
|
|
82
|
+
* @constructor
|
|
83
|
+
*/
|
|
84
|
+
function PaymentDescriptionView({op, compact}) {
|
|
85
|
+
const {destination, asset, amount} = op.operation
|
|
86
|
+
return op.isEphemeral ? <>
|
|
87
|
+
<b>Send</b> <Amount amount={amount} asset={asset}/> to <AccountAddress account={destination}/>
|
|
88
|
+
<OpSourceAccount op={op}/>
|
|
89
|
+
</> : <>
|
|
90
|
+
<OpSourceAccount op={op}/> sent{' '}
|
|
91
|
+
<Amount amount={amount} asset={AssetDescriptor.parse(asset)} issuer={!compact}/> to{' '}
|
|
92
|
+
<AccountAddress account={destination}/>
|
|
93
|
+
</>
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Description view for PathPayment operations (types 2, 13)
|
|
98
|
+
* @param {OperationDescriptor} op
|
|
99
|
+
* @param {boolean} compact
|
|
100
|
+
* @constructor
|
|
101
|
+
*/
|
|
102
|
+
function PathPaymentDescriptionView({op, compact}) {
|
|
103
|
+
let {source, destination, sendAsset, sendMax, sendAmount, destAsset, destAmount, destMin, path, effects} = op.operation
|
|
104
|
+
const isSwap = source === destination
|
|
105
|
+
let src = sendAmount || sendMax
|
|
106
|
+
let dst = destAmount || destMin
|
|
107
|
+
sendAsset = AssetDescriptor.parse(sendAsset)
|
|
108
|
+
destAsset = AssetDescriptor.parse(destAsset)
|
|
109
|
+
const sendAssetId = sendAsset.toFQAN()
|
|
110
|
+
const destAssetId = destAsset.toFQAN()
|
|
111
|
+
const pathData = <>
|
|
112
|
+
<i className="icon icon-shuffle color-primary"/>{' '}
|
|
113
|
+
{!compact && path.map((asset, i) => <span key={i + '-' + asset.toString()}>
|
|
114
|
+
<AssetLink asset={asset}/> <i className="icon icon-shuffle color-primary"/>{' '}
|
|
115
|
+
</span>)}
|
|
116
|
+
</>
|
|
117
|
+
if (op.isEphemeral)
|
|
118
|
+
return <>
|
|
119
|
+
<b>{isSwap ? 'Swap' : 'Send'}</b> <Amount amount={src} asset={sendAsset} issuer={!compact}/>{' '}
|
|
120
|
+
{pathData}
|
|
121
|
+
<Amount amount={dst} asset={destAsset} issuer={!compact}/>
|
|
122
|
+
{!isSwap && <> to <AccountAddress account={destination}/></>}
|
|
123
|
+
<OpSourceAccount op={op}/>
|
|
124
|
+
</>
|
|
125
|
+
if (sendMax !== undefined) {
|
|
126
|
+
if (isSwap && sendAssetId === destAssetId && effects.length) { //circular trades yield accountCredited/Debited effect
|
|
127
|
+
const changeEffect = effects.find(e => e.source === source && e.asset === sendAssetId && (e.type === 'accountCredited' || e.type === 'accountDebited'))
|
|
128
|
+
if (changeEffect) { //arbitrage successful, otherwise src = dst and no account changes happened
|
|
129
|
+
const change = BigInt(changeEffect.amount)
|
|
130
|
+
src = fromStroops(toStroops(destAmount) + (changeEffect.type === 'accountCredited' ? -change : change))
|
|
131
|
+
}
|
|
132
|
+
} else {
|
|
133
|
+
const debitedEffect = effects.find(e => e.source === source && e.type === 'accountDebited' && e.asset === sendAssetId)
|
|
134
|
+
if (debitedEffect) {
|
|
135
|
+
src = fromStroops(debitedEffect.amount)
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if (destMin !== undefined) {
|
|
140
|
+
if (isSwap && sendAssetId === destAssetId && effects.length) { //circular trades yield accountCredited/Debited effect
|
|
141
|
+
const changeEffect = effects.find(e => e.source === source && e.asset === destAssetId && (e.type === 'accountCredited' || e.type === 'accountDebited'))
|
|
142
|
+
if (changeEffect) { //arbitrage successful, otherwise src = dst and no account changes happened
|
|
143
|
+
const change = BigInt(changeEffect.amount)
|
|
144
|
+
dst = fromStroops(toStroops(sendAmount) + (changeEffect.type === 'accountCredited' ? change : -change))
|
|
145
|
+
}
|
|
146
|
+
} else {
|
|
147
|
+
const creditedEffect = effects.find(e => e.source === destination && e.type === 'accountCredited' && e.asset === destAssetId)
|
|
148
|
+
if (creditedEffect) {
|
|
149
|
+
dst = fromStroops(creditedEffect.amount)
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return <>
|
|
154
|
+
<OpSourceAccount op={op}/> {isSwap ? 'swapped ' : 'sent '}
|
|
155
|
+
<Amount amount={src} asset={sendAsset} issuer={!compact}/>{' '}
|
|
156
|
+
{!compact && sendMax > 0 && op.successful && <><span className="dimmed nowrap">
|
|
157
|
+
(max <Amount amount={sendMax} asset={AssetDescriptor.parse(sendAsset)}/>)
|
|
158
|
+
</span> </>}
|
|
159
|
+
{pathData}
|
|
160
|
+
<Amount amount={dst} asset={destAsset} issuer={!compact}/>{' '}
|
|
161
|
+
{!compact && destMin > 0 && op.successful && <><span className="dimmed nowrap">
|
|
162
|
+
(min <Amount amount={destMin} asset={destAsset}/>)
|
|
163
|
+
</span> </>}
|
|
164
|
+
{!isSwap && <>to <AccountAddress account={destination}/></>}
|
|
165
|
+
</>
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Description view for ManageSellOffer/ManageBuyOffer/CreatePassiveSellOffer operations (types 3, 4, 12)
|
|
170
|
+
* @param {OperationDescriptor} op
|
|
171
|
+
* @param {boolean} compact
|
|
172
|
+
* @constructor
|
|
173
|
+
*/
|
|
174
|
+
function ManageOfferDescriptionView({op, compact}) {
|
|
175
|
+
let {offerId, amount, buyAmount, selling, buying, price, type} = op.operation
|
|
176
|
+
const passive = type === 'createPassiveSellOffer'
|
|
177
|
+
const isCancelled = !passive && offerId > 0 && parseFloat(amount || buyAmount) === 0
|
|
178
|
+
|
|
179
|
+
const direction = type === 'manageBuyOffer' ? ' buy' : ' sell'
|
|
180
|
+
let description = ''
|
|
181
|
+
if (offerId > 0) { //manage existing offer
|
|
182
|
+
description = 'Update'
|
|
183
|
+
} else {
|
|
184
|
+
description = 'Create'
|
|
185
|
+
}
|
|
186
|
+
if (!op.isEphemeral) {
|
|
187
|
+
description += 'd'
|
|
188
|
+
}
|
|
189
|
+
if (passive) {
|
|
190
|
+
description += ' passive'
|
|
191
|
+
}
|
|
192
|
+
description += direction + ' offer'
|
|
193
|
+
const amountInfo = <>
|
|
194
|
+
{amount !== undefined ?
|
|
195
|
+
<Amount amount={amount} asset={selling} issuer={!compact}/> :
|
|
196
|
+
<AssetLink asset={selling} issuer={!compact}/>}{' '}
|
|
197
|
+
<i className="icon icon-shuffle color-primary"/>{' '}
|
|
198
|
+
{buyAmount !== undefined ?
|
|
199
|
+
<Amount amount={buyAmount} asset={buying} issuer={!compact}/> :
|
|
200
|
+
<AssetLink asset={buying} issuer={!compact}/>}{' '}
|
|
201
|
+
at <span className="nowrap">
|
|
202
|
+
{formatWithAutoPrecision(parseFloat(price))} {AssetDescriptor.parse(buying).toCurrency()}/{AssetDescriptor.parse(selling).toCurrency()}
|
|
203
|
+
</span>
|
|
204
|
+
</>
|
|
205
|
+
if (op.isEphemeral) {
|
|
206
|
+
if (isCancelled)
|
|
207
|
+
return <>
|
|
208
|
+
<b>Cancel DEX offer</b> #<OfferLink offer={offerId}/><OpSourceAccount op={op}/>
|
|
209
|
+
</>
|
|
210
|
+
return <>
|
|
211
|
+
<b>{description}</b> {offerId > 0 && <>#<OfferLink offer={offerId}/></>} {amountInfo}<OpSourceAccount op={op}/>
|
|
212
|
+
</>
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (isCancelled)
|
|
216
|
+
return <>
|
|
217
|
+
<OpSourceAccount op={op}/> cancelled DEX offer <OfferLink offer={offerId}/>
|
|
218
|
+
</>
|
|
219
|
+
return <>
|
|
220
|
+
<OpSourceAccount op={op}/> {description.toLowerCase()} {offerId > 0 && <OfferLink offer={offerId}/>} {amountInfo}
|
|
221
|
+
</>
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function AccountFlags({flags}) {
|
|
225
|
+
if (!flags)
|
|
226
|
+
return null
|
|
227
|
+
const res = []
|
|
228
|
+
if (flags & AuthRequiredFlag) {
|
|
229
|
+
res.push('auth_required')
|
|
230
|
+
}
|
|
231
|
+
if (flags & AuthRevocableFlag) {
|
|
232
|
+
res.push('auth_revocable')
|
|
233
|
+
}
|
|
234
|
+
if (flags & AuthImmutableFlag) {
|
|
235
|
+
res.push('auth_immutable')
|
|
236
|
+
}
|
|
237
|
+
if (flags & AuthClawbackEnabledFlag) {
|
|
238
|
+
res.push('auth_clawback_enabled')
|
|
239
|
+
}
|
|
240
|
+
return <>
|
|
241
|
+
{res.map((f, i) => <span key={f}>{i > 0 && <>, </>}<code>{f}</code></span>)} flag{res.length > 1 && <>s</>}
|
|
242
|
+
</>
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* SetOptions operation (type 5)
|
|
247
|
+
* @param {OperationDescriptor} op
|
|
248
|
+
* @param {boolean} compact
|
|
249
|
+
* @constructor
|
|
250
|
+
*/
|
|
251
|
+
function SetOptionsDescriptionView({op, compact}) {
|
|
252
|
+
const {
|
|
253
|
+
setFlags,
|
|
254
|
+
clearFlags,
|
|
255
|
+
homeDomain,
|
|
256
|
+
inflationDest,
|
|
257
|
+
lowThreshold,
|
|
258
|
+
medThreshold,
|
|
259
|
+
highThreshold,
|
|
260
|
+
signer,
|
|
261
|
+
masterWeight,
|
|
262
|
+
order,
|
|
263
|
+
txHash
|
|
264
|
+
} = op.operation
|
|
265
|
+
|
|
266
|
+
const settings = []
|
|
267
|
+
if (!!setFlags) {
|
|
268
|
+
settings.push(<>Set <AccountFlags flags={setFlags}/></>)
|
|
269
|
+
}
|
|
270
|
+
if (!!clearFlags) {
|
|
271
|
+
settings.push(<>Unset <AccountFlags flags={clearFlags}/></>)
|
|
272
|
+
}
|
|
273
|
+
if (homeDomain !== undefined) {
|
|
274
|
+
settings.push(homeDomain ? <>Set home domain <code className="nowrap">{homeDomain}</code></> : <>Reset home domain</>)
|
|
275
|
+
}
|
|
276
|
+
if (inflationDest !== undefined) {
|
|
277
|
+
settings.push(<>Set inflation destination to <AccountAddress account={inflationDest}/></>)
|
|
278
|
+
}
|
|
279
|
+
if (lowThreshold !== undefined || medThreshold !== undefined || highThreshold !== undefined) {
|
|
280
|
+
const thresholds = []
|
|
281
|
+
if (lowThreshold !== undefined) {
|
|
282
|
+
thresholds.push('low=' + lowThreshold)
|
|
283
|
+
}
|
|
284
|
+
if (medThreshold !== undefined) {
|
|
285
|
+
thresholds.push('medium=' + medThreshold)
|
|
286
|
+
}
|
|
287
|
+
if (highThreshold !== undefined) {
|
|
288
|
+
thresholds.push('high=' + highThreshold)
|
|
289
|
+
}
|
|
290
|
+
settings.push(<>Set thresholds {thresholds.map((t, i) => <span key={i + t}>{i > 0 && <>, </>}<code>{t}</code></span>)}</>)
|
|
291
|
+
}
|
|
292
|
+
if (masterWeight !== undefined) {
|
|
293
|
+
settings.push(<>Set master key weight to <code>{masterWeight}</code></>)
|
|
294
|
+
}
|
|
295
|
+
if (signer !== undefined) {
|
|
296
|
+
if (signer.weight > 0) {
|
|
297
|
+
settings.push(<>Add account signer <SignerKey signer={signer}/></>)
|
|
298
|
+
} else {
|
|
299
|
+
settings.push(<>Remove account signer <SignerKey signer={signer} showWeight={false}/></>)
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
const details = <div className="block-indent text-small">
|
|
303
|
+
{settings.map((s, i) => <div key={txHash + order + i}>{s}</div>)}
|
|
304
|
+
</div>
|
|
305
|
+
if (op.isEphemeral)
|
|
306
|
+
return <>
|
|
307
|
+
<b>Set account options</b><OpSourceAccount op={op}/>
|
|
308
|
+
{details}
|
|
309
|
+
</>
|
|
310
|
+
return <>
|
|
311
|
+
<OpSourceAccount op={op}/> updated account options.
|
|
312
|
+
<div className="block-indent">
|
|
313
|
+
{details}
|
|
314
|
+
</div>
|
|
315
|
+
</>
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* ChangeTrust operation (type 6)
|
|
320
|
+
* @param {OperationDescriptor} op
|
|
321
|
+
* @param {boolean} compact
|
|
322
|
+
* @constructor
|
|
323
|
+
*/
|
|
324
|
+
function ChangeTrustDescriptionView({op, compact}) {
|
|
325
|
+
const {line, limit, effects} = op.operation
|
|
326
|
+
const trustAsset = AssetDescriptor.parse(line)
|
|
327
|
+
const established = limit > 0
|
|
328
|
+
if (op.isEphemeral) {
|
|
329
|
+
if (established)
|
|
330
|
+
return <>
|
|
331
|
+
<b>Establish trustline</b> to <AssetLink asset={trustAsset} issuer={!compact}/>
|
|
332
|
+
{limit !== '922337203685.4775807' && <> with limit <Amount amount={limit} asset={trustAsset} issuer={!compact}/></>}
|
|
333
|
+
<OpSourceAccount op={op}/>
|
|
334
|
+
</>
|
|
335
|
+
return <>
|
|
336
|
+
<b>Remove trustline</b> to <AssetLink asset={trustAsset} issuer={!compact}/><OpSourceAccount op={op}/>
|
|
337
|
+
</>
|
|
338
|
+
}
|
|
339
|
+
if (established) {
|
|
340
|
+
const description = effects.some(e => e.type === 'trustlineCreated') ? 'established' : 'updated'
|
|
341
|
+
return <>
|
|
342
|
+
<OpSourceAccount op={op}/> {description} trustline to <AssetLink asset={line} issuer={!compact}/>
|
|
343
|
+
{limit !== '922337203685.4775807' && <> with limit <Amount amount={limit} asset={line} issuer={!compact}/></>}
|
|
344
|
+
</>
|
|
345
|
+
}
|
|
346
|
+
return <>
|
|
347
|
+
<OpSourceAccount op={op}/> removed trustline to <AssetLink asset={line} issuer={!compact}/>
|
|
348
|
+
</>
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* AllowTrust operation (type 7)
|
|
353
|
+
* @param {OperationDescriptor} op
|
|
354
|
+
* @param {boolean} compact
|
|
355
|
+
* @constructor
|
|
356
|
+
*/
|
|
357
|
+
function AllowTrustDescriptionView({op, compact}) {
|
|
358
|
+
const {source, assetCode, trustor, authorize} = op.operation
|
|
359
|
+
const asset = AssetDescriptor.parse({code: assetCode, issuer: source})
|
|
360
|
+
|
|
361
|
+
let description = authorize ? 'Authorize' : 'Deauthorize'
|
|
362
|
+
if (op.isEphemeral)
|
|
363
|
+
return <>
|
|
364
|
+
<b>{description} trustline</b> <AssetLink asset={asset} issuer={!compact}/> for account <AccountAddress account={trustor}/>
|
|
365
|
+
<OpSourceAccount op={op}/>
|
|
366
|
+
</>
|
|
367
|
+
return <>
|
|
368
|
+
<OpSourceAccount op={op}/> {description.toLowerCase() + 'd'} trustline{' '}
|
|
369
|
+
<AssetLink asset={asset} issuer={!compact}/> for account <AccountAddress account={trustor}/>
|
|
370
|
+
</>
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* AccountMerge operation (type 8)
|
|
375
|
+
* @param {OperationDescriptor} op
|
|
376
|
+
* @param {boolean} compact
|
|
377
|
+
* @constructor
|
|
378
|
+
*/
|
|
379
|
+
function MergeAccountDescriptionView({op, compact}) {
|
|
380
|
+
const {destination} = op.operation
|
|
381
|
+
if (op.isEphemeral)
|
|
382
|
+
return <>
|
|
383
|
+
<b>Merge account</b> <OpSourceAccount op={op}/> into account <AccountAddress account={destination}/>
|
|
384
|
+
<OpSourceAccount op={op}/>
|
|
385
|
+
</>
|
|
386
|
+
return <>
|
|
387
|
+
<OpSourceAccount op={op}/> merged into account <AccountAddress account={destination}/>
|
|
388
|
+
</>
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Inflation operation (type 9)
|
|
393
|
+
* @param {OperationDescriptor} op
|
|
394
|
+
* @param {boolean} compact
|
|
395
|
+
* @constructor
|
|
396
|
+
*/
|
|
397
|
+
function InflationDescriptionView({op, compact}) {
|
|
398
|
+
if (op.isEphemeral)
|
|
399
|
+
return <>
|
|
400
|
+
<b>Initiate inflation</b><OpSourceAccount op={op}/>
|
|
401
|
+
</>
|
|
402
|
+
return <>
|
|
403
|
+
<OpSourceAccount op={op}/> initiated inflation
|
|
404
|
+
</>
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* ManageData operation (type 10)
|
|
409
|
+
* @param {OperationDescriptor} op
|
|
410
|
+
* @param {boolean} compact
|
|
411
|
+
* @constructor
|
|
412
|
+
*/
|
|
413
|
+
function ManageDataDescriptionView({op, compact}) {
|
|
414
|
+
const {name, value, effects} = op.operation
|
|
415
|
+
const dataEntryDesc = <span className="word-break condensed text-small">
|
|
416
|
+
<code>"{name}"</code>
|
|
417
|
+
{!!value && <> = <code>"{value.toString()}"</code></>}
|
|
418
|
+
</span>
|
|
419
|
+
|
|
420
|
+
if (op.isEphemeral) {
|
|
421
|
+
const descr = !value ? 'Delete' : 'Set'
|
|
422
|
+
return <>
|
|
423
|
+
<b>{descr} data entry</b> {dataEntryDesc}<OpSourceAccount op={op}/>
|
|
424
|
+
</>
|
|
425
|
+
}
|
|
426
|
+
let descr = !value ? 'deleted' : 'set'
|
|
427
|
+
if (effects.some(e => e.type === 'dataEntryUpdated')) {
|
|
428
|
+
descr = 'updated'
|
|
429
|
+
}
|
|
430
|
+
return <>
|
|
431
|
+
<OpSourceAccount op={op}/> {descr} data entry {dataEntryDesc}
|
|
432
|
+
</>
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* BumpSequence operation (type 11)
|
|
437
|
+
* @param {OperationDescriptor} op
|
|
438
|
+
* @param {boolean} compact
|
|
439
|
+
* @constructor
|
|
440
|
+
*/
|
|
441
|
+
function BumpSequenceDescriptionView({op, compact}) {
|
|
442
|
+
const {bumpTo} = op.operation
|
|
443
|
+
if (op.isEphemeral)
|
|
444
|
+
return <>
|
|
445
|
+
<b>Bump account sequence</b> to {bumpTo}<OpSourceAccount op={op}/>
|
|
446
|
+
</>
|
|
447
|
+
return <>
|
|
448
|
+
<OpSourceAccount op={op}/> bumped account sequence to {bumpTo}
|
|
449
|
+
</>
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* CreateClaimableBalance operation (type 14)
|
|
454
|
+
* @param {OperationDescriptor} op
|
|
455
|
+
* @param {boolean} compact
|
|
456
|
+
* @constructor
|
|
457
|
+
*/
|
|
458
|
+
function CreateClaimableBalanceDescriptionView({op, compact}) {
|
|
459
|
+
const {asset, amount, claimants, effects} = op.operation
|
|
460
|
+
const balanceId = effects.find(e => e.type === 'claimableBalanceCreated')?.balance
|
|
461
|
+
if (op.isEphemeral)
|
|
462
|
+
return <>
|
|
463
|
+
<b>Create claimable balance</b> <Amount amount={amount} asset={AssetDescriptor.parse(asset)} issuer={!compact}/>
|
|
464
|
+
<ClaimableBalanceId balance={balanceId}/>
|
|
465
|
+
<OpSourceAccount op={op}/>{' '}
|
|
466
|
+
claimable by <ClaimableBalanceClaimants claimants={claimants}/>
|
|
467
|
+
|
|
468
|
+
</>
|
|
469
|
+
return <>
|
|
470
|
+
<OpSourceAccount op={op}/> created claimable balance
|
|
471
|
+
<ClaimableBalanceId balance={balanceId}/>{' '}
|
|
472
|
+
<Amount amount={amount} asset={AssetDescriptor.parse(asset)} issuer={!compact}/>{' '}
|
|
473
|
+
claimable by <ClaimableBalanceClaimants claimants={claimants}/>
|
|
474
|
+
</>
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* ClaimClaimableBalance operation (type 15)
|
|
479
|
+
* @param {OperationDescriptor} op
|
|
480
|
+
* @param {boolean} compact
|
|
481
|
+
* @constructor
|
|
482
|
+
*/
|
|
483
|
+
function ClaimClaimableBalanceDescriptionView({op, compact}) {
|
|
484
|
+
const {balanceId} = op.operation
|
|
485
|
+
if (op.isEphemeral)
|
|
486
|
+
return <>
|
|
487
|
+
<b>Claim balance</b> <ClaimableBalanceId balance={balanceId}/>
|
|
488
|
+
<OpSourceAccount op={op}/>
|
|
489
|
+
</>
|
|
490
|
+
return <>
|
|
491
|
+
<OpSourceAccount op={op}/> claimed balance <ClaimableBalanceId balance={balanceId}/>
|
|
492
|
+
</>
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
/**
|
|
496
|
+
* BeginSponsoringFutureReserves operation (type 16)
|
|
497
|
+
* @param {OperationDescriptor} op
|
|
498
|
+
* @param {boolean} compact
|
|
499
|
+
* @constructor
|
|
500
|
+
*/
|
|
501
|
+
function BeginSponsoringFutureReservesDescriptionView({op, compact}) {
|
|
502
|
+
const {sponsoredId} = op.operation
|
|
503
|
+
if (op.isEphemeral)
|
|
504
|
+
return <>
|
|
505
|
+
<b>Sponsor reserves</b> for <AccountAddress account={sponsoredId}/><OpSourceAccount op={op}/>
|
|
506
|
+
</>
|
|
507
|
+
return <>
|
|
508
|
+
<OpSourceAccount op={op}/> sponsored reserves for <AccountAddress account={sponsoredId}/>
|
|
509
|
+
</>
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/**
|
|
513
|
+
* EndSponsoringFutureReserves operation (type 17)
|
|
514
|
+
* @param {OperationDescriptor} op
|
|
515
|
+
* @param {boolean} compact
|
|
516
|
+
* @constructor
|
|
517
|
+
*/
|
|
518
|
+
function EndSponsoringFutureReservesDescriptionView({op, compact}) {
|
|
519
|
+
if (op.isEphemeral)
|
|
520
|
+
return <>
|
|
521
|
+
<b>Finish sponsoring reserves</b><OpSourceAccount op={op}/>
|
|
522
|
+
</>
|
|
523
|
+
return <>
|
|
524
|
+
Finished sponsoring reserves for <OpSourceAccount op={op}/>
|
|
525
|
+
</>
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
/**
|
|
529
|
+
* RevokeAccountSponsorship operation (type 18)
|
|
530
|
+
* @param {OperationDescriptor} op
|
|
531
|
+
* @param {boolean} compact
|
|
532
|
+
* @constructor
|
|
533
|
+
*/
|
|
534
|
+
function RevokeAccountSponsorshipDescriptionView({op, compact}) {
|
|
535
|
+
const {account} = op.operation
|
|
536
|
+
if (op.isEphemeral)
|
|
537
|
+
return <>
|
|
538
|
+
<b>Revoke sponsorship</b> for account <AccountAddress account={account}/><OpSourceAccount op={op}/>
|
|
539
|
+
</>
|
|
540
|
+
return <>
|
|
541
|
+
<OpSourceAccount op={op}/> revoked sponsorship for account <AccountAddress account={account}/>
|
|
542
|
+
</>
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
/**
|
|
546
|
+
* RevokeSignerSponsorship operation (type 18)
|
|
547
|
+
* @param {OperationDescriptor} op
|
|
548
|
+
* @param {boolean} compact
|
|
549
|
+
* @constructor
|
|
550
|
+
*/
|
|
551
|
+
function RevokeSignerSponsorshipDescriptionView({op, compact}) {
|
|
552
|
+
const {account, signer} = op.operation
|
|
553
|
+
if (op.isEphemeral)
|
|
554
|
+
return <>
|
|
555
|
+
<b>Revoke sponsorship</b> on signer <SignerKey signer={signer} showWeight={false}/>{' '}
|
|
556
|
+
for account <AccountAddress account={account}/>
|
|
557
|
+
<OpSourceAccount op={op}/>
|
|
558
|
+
</>
|
|
559
|
+
return <>
|
|
560
|
+
<OpSourceAccount op={op}/> revoked sponsorship on signer <SignerKey signer={signer} showWeight={false}/>
|
|
561
|
+
{' '}for account <AccountAddress account={account}/>
|
|
562
|
+
</>
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
/**
|
|
566
|
+
* RevokeTrustlineSponsorship operation (type 18)
|
|
567
|
+
* @param {OperationDescriptor} op
|
|
568
|
+
* @param {boolean} compact
|
|
569
|
+
* @constructor
|
|
570
|
+
*/
|
|
571
|
+
function RevokeTrustlineSponsorshipDescriptionView({op, compact}) {
|
|
572
|
+
const {account, asset} = op.operation
|
|
573
|
+
if (op.isEphemeral)
|
|
574
|
+
return <>
|
|
575
|
+
<b>Revoke sponsorship</b> on <AssetLink asset={asset} issuer={!compact}/> trustline for account{' '}
|
|
576
|
+
<AccountAddress account={account}/><OpSourceAccount op={op}/>
|
|
577
|
+
</>
|
|
578
|
+
return <>
|
|
579
|
+
<OpSourceAccount op={op}/> revoked sponsorship on <AssetLink asset={asset} issuer={!compact}/> trustline for account{' '}
|
|
580
|
+
<AccountAddress account={account}/>
|
|
581
|
+
</>
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
/**
|
|
585
|
+
* RevokeOfferSponsorship operation (type 18)
|
|
586
|
+
* @param {OperationDescriptor} op
|
|
587
|
+
* @param {boolean} compact
|
|
588
|
+
* @constructor
|
|
589
|
+
*/
|
|
590
|
+
function RevokeOfferSponsorshipDescriptionView({op, compact}) {
|
|
591
|
+
const {seller, offerId} = op.operation
|
|
592
|
+
if (op.isEphemeral)
|
|
593
|
+
return <>
|
|
594
|
+
<b>Revoke sponsorship</b> on offer <OfferLink offer={offerId}/> for account <AccountAddress account={seller}/>
|
|
595
|
+
<OpSourceAccount op={op}/>
|
|
596
|
+
</>
|
|
597
|
+
return <>
|
|
598
|
+
<OpSourceAccount op={op}/> revoked sponsorship on offer <OfferLink offer={offerId}/>{' '}
|
|
599
|
+
for account <AccountAddress account={seller}/>
|
|
600
|
+
</>
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
/**
|
|
604
|
+
* RevokeDataSponsorship operation (type 18)
|
|
605
|
+
* @param {OperationDescriptor} op
|
|
606
|
+
* @param {boolean} compact
|
|
607
|
+
* @constructor
|
|
608
|
+
*/
|
|
609
|
+
function RevokeDataSponsorshipDescriptionView({op, compact}) {
|
|
610
|
+
const {account, name} = op.operation
|
|
611
|
+
if (op.isEphemeral)
|
|
612
|
+
return <>
|
|
613
|
+
<b>Revoke sponsorship</b> on data entry <code>{name}</code> for account <AccountAddress account={account}/>
|
|
614
|
+
<OpSourceAccount op={op}/>
|
|
615
|
+
</>
|
|
616
|
+
return <>
|
|
617
|
+
<OpSourceAccount op={op}/> revoked sponsorship on data entry <code>{name}</code> for account{' '}
|
|
618
|
+
<AccountAddress account={account}/>
|
|
619
|
+
</>
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
/**
|
|
623
|
+
* RevokeClaimableBalanceSponsorship operation (type 18)
|
|
624
|
+
* @param {OperationDescriptor} op
|
|
625
|
+
* @param {boolean} compact
|
|
626
|
+
* @constructor
|
|
627
|
+
*/
|
|
628
|
+
function RevokeClaimableBalanceSponsorshipDescriptionView({op, compact}) {
|
|
629
|
+
const {balanceId} = op.operation
|
|
630
|
+
if (op.isEphemeral)
|
|
631
|
+
return <>
|
|
632
|
+
<b>Revoke sponsorship</b> on claimable balance <ClaimableBalanceId balance={balanceId}/>
|
|
633
|
+
<OpSourceAccount op={op}/>
|
|
634
|
+
</>
|
|
635
|
+
return <>
|
|
636
|
+
<OpSourceAccount op={op}/> revoked sponsorship on claimable balance <ClaimableBalanceId balance={balanceId}/>
|
|
637
|
+
</>
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
/**
|
|
641
|
+
* RevokeLiquidityPoolSponsorship operation (type 18)
|
|
642
|
+
* @param {OperationDescriptor} op
|
|
643
|
+
* @param {boolean} compact
|
|
644
|
+
* @constructor
|
|
645
|
+
*/
|
|
646
|
+
function RevokeLiquidityPoolSponsorshipDescriptionView({op, compact}) {
|
|
647
|
+
const {liquidityPoolId} = op.operation
|
|
648
|
+
if (op.isEphemeral)
|
|
649
|
+
return <>
|
|
650
|
+
<b>Revoke sponsorship</b> on liquidity pool <AssetLink asset={liquidityPoolId} issuer={!compact}/>
|
|
651
|
+
<OpSourceAccount op={op}/>
|
|
652
|
+
</>
|
|
653
|
+
return <>
|
|
654
|
+
<OpSourceAccount op={op}/> revoked sponsorship on liquidity pool <AssetLink asset={liquidityPoolId} issuer={!compact}/>
|
|
655
|
+
</>
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
/**
|
|
659
|
+
* Clawback operation (type 19)
|
|
660
|
+
* @param {OperationDescriptor} op
|
|
661
|
+
* @param {boolean} compact
|
|
662
|
+
* @constructor
|
|
663
|
+
*/
|
|
664
|
+
function ClawbackDescriptionView({op, compact}) {
|
|
665
|
+
const {from, amount, asset} = op.operation
|
|
666
|
+
if (op.isEphemeral)
|
|
667
|
+
return <>
|
|
668
|
+
<b>Clawback</b> <Amount amount={amount} asset={asset} issuer={!compact}/> from <AccountAddress account={from}/>
|
|
669
|
+
<OpSourceAccount op={op}/>
|
|
670
|
+
</>
|
|
671
|
+
return <>
|
|
672
|
+
<OpSourceAccount op={op}/> clawedback <Amount asset={asset} amount={amount} issuer={!compact}/> from <AccountAddress
|
|
673
|
+
account={from}/>
|
|
674
|
+
</>
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
/**
|
|
678
|
+
* ClawbackClaimableBalance operation (type 20)
|
|
679
|
+
* @param {OperationDescriptor} op
|
|
680
|
+
* @param {boolean} compact
|
|
681
|
+
* @constructor
|
|
682
|
+
*/
|
|
683
|
+
function ClawbackClaimableBalanceDescriptionView({op, compact}) {
|
|
684
|
+
const {balanceId} = op.operation
|
|
685
|
+
if (op.isEphemeral)
|
|
686
|
+
return <>
|
|
687
|
+
<b>Clawback claimable balance</b> <ClaimableBalanceId balance={balanceId}/><OpSourceAccount op={op}/>
|
|
688
|
+
</>
|
|
689
|
+
return <>
|
|
690
|
+
<OpSourceAccount op={op}/> clawedback claimable balance <ClaimableBalanceId balance={balanceId}/>
|
|
691
|
+
</>
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
/**
|
|
695
|
+
* SetTrustLineFlags operation (type 21)
|
|
696
|
+
* @param {OperationDescriptor} op
|
|
697
|
+
* @param {boolean} compact
|
|
698
|
+
* @constructor
|
|
699
|
+
*/
|
|
700
|
+
function SetTrustLineFlagsDescriptionView({op, compact}) {
|
|
701
|
+
const {trustor, asset, flags} = op.operation
|
|
702
|
+
const flagsMapping = {
|
|
703
|
+
authorized: 'authorized',
|
|
704
|
+
authorizedToMaintainLiabilities: 'authorized to maintain liabilities',
|
|
705
|
+
clawbackEnabled: 'clawback enabled'
|
|
706
|
+
}
|
|
707
|
+
const setFlags = []
|
|
708
|
+
const clearFlags = []
|
|
709
|
+
for (let flag of Object.keys(flagsMapping)) {
|
|
710
|
+
const container = flags[flag] ? setFlags : clearFlags
|
|
711
|
+
container.push(flagsMapping[flag])
|
|
712
|
+
}
|
|
713
|
+
const flagsInfo = <>
|
|
714
|
+
<code>[{setFlags.join(', ')}]</code>
|
|
715
|
+
{clearFlags.length > 0 && <span>, clear{!op.isEphemeral && 'ed'} flags <code>[{clearFlags.join(', ')}]</code></span>}{' '}
|
|
716
|
+
on asset <AssetLink asset={asset} issuer={!compact}/> for account <AccountAddress account={trustor}/>
|
|
717
|
+
</>
|
|
718
|
+
if (op.isEphemeral)
|
|
719
|
+
return <>
|
|
720
|
+
<b>Set trustline flags</b> {flagsInfo}<OpSourceAccount op={op}/>
|
|
721
|
+
</>
|
|
722
|
+
return <>
|
|
723
|
+
<OpSourceAccount op={op}/> set trustline flags {flagsInfo}
|
|
724
|
+
</>
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
/**
|
|
728
|
+
* LiquidityPoolDeposit operation (type 22)
|
|
729
|
+
* @param {OperationDescriptor} op
|
|
730
|
+
* @param {boolean} compact
|
|
731
|
+
* @constructor
|
|
732
|
+
*/
|
|
733
|
+
function DepositLiquidityDescriptionView({op, compact}) {
|
|
734
|
+
const {liquidityPoolId, maxAmountA, maxAmountB, minPrice, maxPrice} = op.operation
|
|
735
|
+
const meta = useAssetMeta(liquidityPoolId)
|
|
736
|
+
const [assetA, assetB] = meta?.assets.map(a => a.asset) || ['tokens A', 'tokens B']
|
|
737
|
+
const depositInfo = <>
|
|
738
|
+
<Amount asset={assetA} amount={maxAmountA} issuer={!compact}/> and {' '}
|
|
739
|
+
<Amount asset={assetB} amount={maxAmountB} issuer={!compact}/> to the pool{' '}
|
|
740
|
+
<AssetLink asset={liquidityPoolId} issuer={!compact}/>{' '}
|
|
741
|
+
{!compact && <span className="dimmed">(price range {formatPrice(minPrice)} - {formatPrice(maxPrice)})</span>}
|
|
742
|
+
</>
|
|
743
|
+
if (op.isEphemeral)
|
|
744
|
+
return <>
|
|
745
|
+
<b>Deposit liquidity</b> {depositInfo}<OpSourceAccount op={op}/>
|
|
746
|
+
</>
|
|
747
|
+
return <>
|
|
748
|
+
<OpSourceAccount op={op}/> deposited liquidity {depositInfo}
|
|
749
|
+
</>
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
/**
|
|
753
|
+
* LiquidityPoolWithdraw operation (type 23)
|
|
754
|
+
* @param {OperationDescriptor} op
|
|
755
|
+
* @param {boolean} compact
|
|
756
|
+
* @constructor
|
|
757
|
+
*/
|
|
758
|
+
function WithdrawLiquidityDescriptionView({op, compact}) {
|
|
759
|
+
const {liquidityPoolId, amount, minAmountA, minAmountB} = op.operation
|
|
760
|
+
const meta = useAssetMeta(liquidityPoolId)
|
|
761
|
+
const [assetA, assetB] = meta?.assets.map(a => a.asset) || ['tokens A', 'tokens B']
|
|
762
|
+
const withdrawInfo = <>
|
|
763
|
+
{formatWithAutoPrecision(amount)} shares from the pool <AssetLink asset={liquidityPoolId} issuer={!compact}/>{' '}
|
|
764
|
+
{!compact && <span className="dimmed">
|
|
765
|
+
(minimum <Amount asset={assetA} amount={minAmountA}/> + <Amount asset={assetB} amount={minAmountB}/>)
|
|
766
|
+
</span>}
|
|
767
|
+
</>
|
|
768
|
+
if (op.isEphemeral)
|
|
769
|
+
return <>
|
|
770
|
+
<b>Withdraw liquidity</b> {withdrawInfo}<OpSourceAccount op={op}/>
|
|
771
|
+
</>
|
|
772
|
+
return <>
|
|
773
|
+
<OpSourceAccount op={op}/> withdrew {withdrawInfo}
|
|
774
|
+
</>
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
/**
|
|
778
|
+
* InvokeHostFunction operation (type 24) — Soroban contract calls
|
|
779
|
+
* @param {OperationDescriptor} op
|
|
780
|
+
* @param {boolean} compact
|
|
781
|
+
* @constructor
|
|
782
|
+
*/
|
|
783
|
+
function InvokeHostFunctionView({op, compact}) {
|
|
784
|
+
const network = useStellarNetwork()
|
|
785
|
+
const {func} = op.operation
|
|
786
|
+
const value = func.value()
|
|
787
|
+
switch (func.arm()) {
|
|
788
|
+
case 'invokeContract':
|
|
789
|
+
const contractAddress = xdrParserUtils.xdrParseScVal(value._attributes.contractAddress)
|
|
790
|
+
const sac = op.operation.sacMap?.[contractAddress]
|
|
791
|
+
const invocationArgs = {
|
|
792
|
+
contract: contractAddress,
|
|
793
|
+
func: value.functionName().toString(),
|
|
794
|
+
args: value.args(),
|
|
795
|
+
sac
|
|
796
|
+
}
|
|
797
|
+
if (op.isEphemeral)
|
|
798
|
+
return <>
|
|
799
|
+
<b>Invoke contract</b> <AccountAddress account={contractAddress}/>{' '}
|
|
800
|
+
<InvocationInfoView {...invocationArgs}/>
|
|
801
|
+
<OpSourceAccount op={op}/>
|
|
802
|
+
</>
|
|
803
|
+
const invocationEffect = op.operation.effects.find(e => e.type === 'contractInvoked' && e.contract === contractAddress)
|
|
804
|
+
return <>
|
|
805
|
+
<OpSourceAccount op={op}/> invoked contract <AccountAddress account={contractAddress}/>{' '}
|
|
806
|
+
<InvocationInfoView {...invocationArgs} result={invocationEffect?.result}/>
|
|
807
|
+
</>
|
|
808
|
+
case 'wasm':
|
|
809
|
+
const wasmCode = value.toString('base64')
|
|
810
|
+
const codeReference = <>
|
|
811
|
+
<code title={wasmCode}>{shortenString(value.toString('base64'), 16)}</code>
|
|
812
|
+
<CopyToClipboard text={wasmCode}/>
|
|
813
|
+
</>
|
|
814
|
+
if (op.isEphemeral)
|
|
815
|
+
return <>
|
|
816
|
+
<b>Upload contract code</b> {codeReference}<OpSourceAccount op={op}/>
|
|
817
|
+
</>
|
|
818
|
+
return <>
|
|
819
|
+
<OpSourceAccount op={op}/> uploaded contract code {codeReference}
|
|
820
|
+
</>
|
|
821
|
+
case 'createContract':
|
|
822
|
+
case 'createContractV2':
|
|
823
|
+
const preimage = value.contractIdPreimage()
|
|
824
|
+
const executable = value.executable()
|
|
825
|
+
const executableType = executable.switch().name
|
|
826
|
+
const contract = contractPreimageEncoder.contractIdFromPreimage(preimage, Networks[network.toUpperCase()])
|
|
827
|
+
let contractProps
|
|
828
|
+
switch (executableType) {
|
|
829
|
+
case 'contractExecutableWasm':
|
|
830
|
+
const wasmHash = executable.wasmHash().toString('hex')
|
|
831
|
+
contractProps = <>
|
|
832
|
+
WASM code <code title={wasmHash}>{shortenString(wasmHash, 16)}</code>
|
|
833
|
+
<CopyToClipboard text={wasmHash}/>
|
|
834
|
+
</>
|
|
835
|
+
break
|
|
836
|
+
case 'contractExecutableStellarAsset':
|
|
837
|
+
const preimageParams = preimage.value()
|
|
838
|
+
switch (preimage.switch().name) {
|
|
839
|
+
case 'contractIdPreimageFromAddress':
|
|
840
|
+
const issuerAddress = xdrParserUtils.xdrParseAccountAddress(preimageParams.address().value())
|
|
841
|
+
const salt = preimageParams.salt().toString('base64')
|
|
842
|
+
contractProps = <>address <AccountAddress account={issuerAddress}/> with salt {salt}</>
|
|
843
|
+
break
|
|
844
|
+
case 'contractIdPreimageFromAsset':
|
|
845
|
+
contractProps = <>asset <AssetLink asset={xdrParserUtils.xdrParseAsset(preimageParams)}/></>
|
|
846
|
+
break
|
|
847
|
+
}
|
|
848
|
+
break
|
|
849
|
+
}
|
|
850
|
+
if (func.arm() === 'createContractV2') {
|
|
851
|
+
const args = value.constructorArgs() //array
|
|
852
|
+
if (args.length > 0) {
|
|
853
|
+
contractProps = <>{contractProps} with <InvocationInfoView func="__constructor" args={args}/></>
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
if (op.isEphemeral)
|
|
857
|
+
return <>
|
|
858
|
+
<b>Create contract</b> <AccountAddress account={contract}/> from {contractProps}<OpSourceAccount op={op}/>
|
|
859
|
+
</>
|
|
860
|
+
return <>
|
|
861
|
+
<OpSourceAccount op={op}/> created contract <AccountAddress account={contract}/> from {contractProps}
|
|
862
|
+
</>
|
|
863
|
+
break
|
|
864
|
+
default:
|
|
865
|
+
return <>Unknown invocation type</>
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
/**
|
|
870
|
+
* ExtendFootprintTTL operation (type 25)
|
|
871
|
+
* @param {OperationDescriptor} op
|
|
872
|
+
* @param {boolean} compact
|
|
873
|
+
* @constructor
|
|
874
|
+
*/
|
|
875
|
+
function ExtendFootprintTTLView({op}) {
|
|
876
|
+
const {extendTo} = op.operation
|
|
877
|
+
if (op.isEphemeral)
|
|
878
|
+
return <>
|
|
879
|
+
<b>Extend ledger state expiration</b> to sequence {extendTo}
|
|
880
|
+
<OpSourceAccount op={op}/>
|
|
881
|
+
</>
|
|
882
|
+
return <>
|
|
883
|
+
<OpSourceAccount op={op}/> extended ledger state expiration to sequence {extendTo}
|
|
884
|
+
</>
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
/**
|
|
888
|
+
* RestoreFootprint operation (type 26)
|
|
889
|
+
* @param {OperationDescriptor} op
|
|
890
|
+
* @param {boolean} compact
|
|
891
|
+
* @constructor
|
|
892
|
+
*/
|
|
893
|
+
function RestoreFootprintView({op}) {
|
|
894
|
+
const {ledgersToExpire} = op.operation
|
|
895
|
+
if (op.isEphemeral)
|
|
896
|
+
return <>
|
|
897
|
+
<b>Restore ledger state entry</b> <OpSourceAccount op={op}/>
|
|
898
|
+
</>
|
|
899
|
+
return <>
|
|
900
|
+
<OpSourceAccount op={op}/> restored ledger state entry
|
|
901
|
+
</>
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
|
|
905
|
+
function getAccountPredefinedDisplayName(address) {
|
|
906
|
+
if (!window.predefinedAccountDisplayNames)
|
|
907
|
+
return undefined
|
|
908
|
+
return window.predefinedAccountDisplayNames[address]
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
const typeMapping = {
|
|
912
|
+
createAccount: CreateAccountDescriptionView,
|
|
913
|
+
payment: PaymentDescriptionView,
|
|
914
|
+
pathPaymentStrictReceive: PathPaymentDescriptionView,
|
|
915
|
+
manageSellOffer: ManageOfferDescriptionView,
|
|
916
|
+
createPassiveSellOffer: ManageOfferDescriptionView,
|
|
917
|
+
setOptions: SetOptionsDescriptionView,
|
|
918
|
+
changeTrust: ChangeTrustDescriptionView,
|
|
919
|
+
allowTrust: AllowTrustDescriptionView,
|
|
920
|
+
accountMerge: MergeAccountDescriptionView,
|
|
921
|
+
inflation: InflationDescriptionView,
|
|
922
|
+
manageData: ManageDataDescriptionView,
|
|
923
|
+
bumpSequence: BumpSequenceDescriptionView,
|
|
924
|
+
manageBuyOffer: ManageOfferDescriptionView,
|
|
925
|
+
pathPaymentStrictSend: PathPaymentDescriptionView,
|
|
926
|
+
createClaimableBalance: CreateClaimableBalanceDescriptionView,
|
|
927
|
+
claimClaimableBalance: ClaimClaimableBalanceDescriptionView,
|
|
928
|
+
beginSponsoringFutureReserves: BeginSponsoringFutureReservesDescriptionView,
|
|
929
|
+
endSponsoringFutureReserves: EndSponsoringFutureReservesDescriptionView,
|
|
930
|
+
revokeAccountSponsorship: RevokeAccountSponsorshipDescriptionView,
|
|
931
|
+
revokeTrustlineSponsorship: RevokeTrustlineSponsorshipDescriptionView,
|
|
932
|
+
revokeOfferSponsorship: RevokeOfferSponsorshipDescriptionView,
|
|
933
|
+
revokeDataSponsorship: RevokeDataSponsorshipDescriptionView,
|
|
934
|
+
revokeClaimableBalanceSponsorship: RevokeClaimableBalanceSponsorshipDescriptionView,
|
|
935
|
+
revokeLiquidityPoolSponsorship: RevokeLiquidityPoolSponsorshipDescriptionView,
|
|
936
|
+
revokeSignerSponsorship: RevokeSignerSponsorshipDescriptionView,
|
|
937
|
+
clawback: ClawbackDescriptionView,
|
|
938
|
+
clawbackClaimableBalance: ClawbackClaimableBalanceDescriptionView,
|
|
939
|
+
setTrustLineFlags: SetTrustLineFlagsDescriptionView,
|
|
940
|
+
liquidityPoolDeposit: DepositLiquidityDescriptionView,
|
|
941
|
+
liquidityPoolWithdraw: WithdrawLiquidityDescriptionView,
|
|
942
|
+
invokeHostFunction: InvokeHostFunctionView,
|
|
943
|
+
extendFootprintTtl: ExtendFootprintTTLView,
|
|
944
|
+
restoreFootprint: RestoreFootprintView
|
|
945
|
+
}
|