@wowok/skills 1.1.12 → 1.2.1
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/LICENSE +1 -2
- package/examples/Insurance/Insurance.md +426 -70
- package/examples/MyShop/MyShop.md +349 -228
- package/examples/MyShop/myshop_machine_nodes.json +14 -8
- package/examples/MyShop_Advanced/MyShop_Advanced.md +472 -105
- package/examples/ThreeBody_Signature/ThreeBody_Signature.md +623 -121
- package/examples/Travel/Travel.md +298 -77
- package/package.json +1 -1
- package/wowok-guard/SKILL.md +317 -20
- package/wowok-machine/SKILL.md +72 -0
- package/wowok-order/APPENDIX.md +33 -33
- package/wowok-provider/SKILL.md +26 -12
- package/wowok-scenario/SKILL.md +10 -0
- package/wowok-tools/SKILL.md +2 -2
|
@@ -4,6 +4,15 @@ A complete e-commerce example demonstrating how to build an online store using W
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
## ⚠️ Running Principle
|
|
8
|
+
|
|
9
|
+
> **Run the example in full every time (repeatable).** This example uses `replaceExistName: true` on all object creations — each run generates new objects with new addresses. If you skip build steps, operations may silently act on orphaned objects from previous runs, producing incorrect results. Old objects' configurations do not reflect the current document version.
|
|
10
|
+
|
|
11
|
+
- **Execution order**: Part 1 (Merchant Setup, Steps 1–7) → Part 2 (Customer Flow, Steps 1–9). Run all build steps in sequence before testing any customer flow. Do not skip steps — each depends on objects created by prior steps.
|
|
12
|
+
- **Prerequisites**: `myshop_merchant` with sufficient WOW for gas and order operations. All on-chain operations require `env.confirmed: true`.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
7
16
|
## Core Requirements & Features
|
|
8
17
|
|
|
9
18
|
| Requirement | Description | Implementation |
|
|
@@ -109,8 +118,10 @@ Before starting, ensure you have:
|
|
|
109
118
|
```json
|
|
110
119
|
{
|
|
111
120
|
"transfer": {
|
|
112
|
-
"
|
|
113
|
-
"amount": 1000000000
|
|
121
|
+
"name_or_address_to": "myshop_merchant",
|
|
122
|
+
"amount": 1000000000,
|
|
123
|
+
"network": "mainnet",
|
|
124
|
+
"confirmed": true
|
|
114
125
|
}
|
|
115
126
|
}
|
|
116
127
|
```
|
|
@@ -137,18 +148,21 @@ First, create a Permission object to manage access control for your store operat
|
|
|
137
148
|
},
|
|
138
149
|
"env": {
|
|
139
150
|
"account": "myshop_merchant",
|
|
140
|
-
"network": "mainnet"
|
|
151
|
+
"network": "mainnet",
|
|
152
|
+
"confirmed": true
|
|
141
153
|
}
|
|
142
154
|
}
|
|
143
155
|
```
|
|
144
156
|
|
|
145
157
|
---
|
|
146
158
|
|
|
147
|
-
### Step 2: Create Machine
|
|
159
|
+
### Step 2: Create Machine with Workflow Nodes
|
|
160
|
+
|
|
161
|
+
Create a Machine to define the order processing workflow. This includes nodes for order confirmation, shipping, delivery, and completion. The Machine must be created with all nodes and published in a single operation — the protocol requires at least one node when publishing a Machine.
|
|
148
162
|
|
|
149
|
-
|
|
163
|
+
> **Reference**: The complete node configuration is available in [`myshop_machine_nodes.json`](./myshop_machine_nodes.json). The JSON below mirrors that file's content wrapped in an on-chain operation.
|
|
150
164
|
|
|
151
|
-
**Prompt**: Create a Machine named "myshop_machine_v2" with permission "myshop_permission_v2"
|
|
165
|
+
**Prompt**: Create a Machine named "myshop_machine_v2" with permission "myshop_permission_v2", including all workflow nodes (Order Confirmation, Shipping, In Transit, Completed, Cancelled), and publish it immediately.
|
|
152
166
|
|
|
153
167
|
```json
|
|
154
168
|
{
|
|
@@ -159,15 +173,115 @@ Create a Machine to define the order processing workflow. This includes nodes fo
|
|
|
159
173
|
"permission": "myshop_permission_v2",
|
|
160
174
|
"replaceExistName": true
|
|
161
175
|
},
|
|
162
|
-
"description": "Order processing workflow for MyShop toy store"
|
|
176
|
+
"description": "Order processing workflow for MyShop toy store",
|
|
177
|
+
"node": {
|
|
178
|
+
"op": "add",
|
|
179
|
+
"nodes": [
|
|
180
|
+
{
|
|
181
|
+
"name": "Cancelled",
|
|
182
|
+
"pairs": [
|
|
183
|
+
{
|
|
184
|
+
"prev_node": "",
|
|
185
|
+
"threshold": 0,
|
|
186
|
+
"forwards": [
|
|
187
|
+
{
|
|
188
|
+
"name": "Cancel Order",
|
|
189
|
+
"weight": 1,
|
|
190
|
+
"namedOperator": ""
|
|
191
|
+
}
|
|
192
|
+
]
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
"prev_node": "Order Confirmation",
|
|
196
|
+
"threshold": 1,
|
|
197
|
+
"forwards": [
|
|
198
|
+
{
|
|
199
|
+
"name": "Cancel Order",
|
|
200
|
+
"weight": 1,
|
|
201
|
+
"namedOperator": ""
|
|
202
|
+
}
|
|
203
|
+
]
|
|
204
|
+
}
|
|
205
|
+
]
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
"name": "Completed",
|
|
209
|
+
"pairs": [
|
|
210
|
+
{
|
|
211
|
+
"prev_node": "In Transit",
|
|
212
|
+
"threshold": 1,
|
|
213
|
+
"forwards": [
|
|
214
|
+
{
|
|
215
|
+
"name": "Complete Order",
|
|
216
|
+
"weight": 1,
|
|
217
|
+
"namedOperator": ""
|
|
218
|
+
}
|
|
219
|
+
]
|
|
220
|
+
}
|
|
221
|
+
]
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
"name": "In Transit",
|
|
225
|
+
"pairs": [
|
|
226
|
+
{
|
|
227
|
+
"prev_node": "Shipping",
|
|
228
|
+
"threshold": 1,
|
|
229
|
+
"forwards": [
|
|
230
|
+
{
|
|
231
|
+
"name": "Confirm Delivery",
|
|
232
|
+
"weight": 1,
|
|
233
|
+
"permissionIndex": 1002
|
|
234
|
+
}
|
|
235
|
+
]
|
|
236
|
+
}
|
|
237
|
+
]
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
"name": "Order Confirmation",
|
|
241
|
+
"pairs": [
|
|
242
|
+
{
|
|
243
|
+
"prev_node": "",
|
|
244
|
+
"threshold": 0,
|
|
245
|
+
"forwards": [
|
|
246
|
+
{
|
|
247
|
+
"name": "Confirm Order",
|
|
248
|
+
"weight": 1,
|
|
249
|
+
"permissionIndex": 1000
|
|
250
|
+
}
|
|
251
|
+
]
|
|
252
|
+
}
|
|
253
|
+
]
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
"name": "Shipping",
|
|
257
|
+
"pairs": [
|
|
258
|
+
{
|
|
259
|
+
"prev_node": "Order Confirmation",
|
|
260
|
+
"threshold": 1,
|
|
261
|
+
"forwards": [
|
|
262
|
+
{
|
|
263
|
+
"name": "Ship Goods",
|
|
264
|
+
"weight": 1,
|
|
265
|
+
"permissionIndex": 1001
|
|
266
|
+
}
|
|
267
|
+
]
|
|
268
|
+
}
|
|
269
|
+
]
|
|
270
|
+
}
|
|
271
|
+
]
|
|
272
|
+
},
|
|
273
|
+
"publish": true
|
|
163
274
|
},
|
|
164
275
|
"env": {
|
|
165
276
|
"account": "myshop_merchant",
|
|
166
|
-
"network": "mainnet"
|
|
277
|
+
"network": "mainnet",
|
|
278
|
+
"confirmed": true
|
|
167
279
|
}
|
|
168
280
|
}
|
|
169
281
|
```
|
|
170
282
|
|
|
283
|
+
> **Note**: The Machine must be created with nodes and published in a single operation. Creating an empty Machine and then adding nodes/publishing separately will be rejected by the protocol's constraint checker. The "Cancelled" node has two pairs: one with `prev_node: ""` (cancel from initial state) and one with `prev_node: "Order Confirmation"` (cancel after order confirmation).
|
|
284
|
+
|
|
171
285
|
---
|
|
172
286
|
|
|
173
287
|
### Step 3: Machine Workflow Design
|
|
@@ -279,152 +393,11 @@ Before adding nodes, let's understand the order processing workflow:
|
|
|
279
393
|
|
|
280
394
|
---
|
|
281
395
|
|
|
282
|
-
### Step 4:
|
|
283
|
-
|
|
284
|
-
Add the workflow nodes to the Machine for order processing. The initial pair (prev_node: "") defines transitions from the empty starting state.
|
|
285
|
-
|
|
286
|
-
**Prompt**: Add workflow nodes to "myshop_machine_v2" including Order Confirmation, Shipping, In Transit, Completed, and Cancelled nodes.
|
|
287
|
-
|
|
288
|
-
```json
|
|
289
|
-
{
|
|
290
|
-
"operation_type": "machine",
|
|
291
|
-
"data": {
|
|
292
|
-
"object": "myshop_machine_v2",
|
|
293
|
-
"node": {
|
|
294
|
-
"op": "add",
|
|
295
|
-
"nodes": [
|
|
296
|
-
{
|
|
297
|
-
"name": "Order Confirmation",
|
|
298
|
-
"pairs": [
|
|
299
|
-
{
|
|
300
|
-
"prev_node": "",
|
|
301
|
-
"threshold": 0,
|
|
302
|
-
"forwards": [
|
|
303
|
-
{
|
|
304
|
-
"name": "Confirm Order",
|
|
305
|
-
"permissionIndex": 1000,
|
|
306
|
-
"weight": 1
|
|
307
|
-
}
|
|
308
|
-
]
|
|
309
|
-
},
|
|
310
|
-
{
|
|
311
|
-
"prev_node": "Order Confirmation",
|
|
312
|
-
"threshold": 1,
|
|
313
|
-
"forwards": [
|
|
314
|
-
{
|
|
315
|
-
"name": "Ship Goods",
|
|
316
|
-
"permissionIndex": 1001,
|
|
317
|
-
"weight": 1
|
|
318
|
-
}
|
|
319
|
-
]
|
|
320
|
-
}
|
|
321
|
-
]
|
|
322
|
-
},
|
|
323
|
-
{
|
|
324
|
-
"name": "Shipping",
|
|
325
|
-
"pairs": [
|
|
326
|
-
{
|
|
327
|
-
"prev_node": "Order Confirmation",
|
|
328
|
-
"threshold": 1,
|
|
329
|
-
"forwards": [
|
|
330
|
-
{
|
|
331
|
-
"name": "Ship Goods",
|
|
332
|
-
"permissionIndex": 1001,
|
|
333
|
-
"weight": 1
|
|
334
|
-
}
|
|
335
|
-
]
|
|
336
|
-
}
|
|
337
|
-
]
|
|
338
|
-
},
|
|
339
|
-
{
|
|
340
|
-
"name": "In Transit",
|
|
341
|
-
"pairs": [
|
|
342
|
-
{
|
|
343
|
-
"prev_node": "Shipping",
|
|
344
|
-
"threshold": 1,
|
|
345
|
-
"forwards": [
|
|
346
|
-
{
|
|
347
|
-
"name": "Confirm Delivery",
|
|
348
|
-
"permissionIndex": 1002,
|
|
349
|
-
"weight": 1
|
|
350
|
-
}
|
|
351
|
-
]
|
|
352
|
-
}
|
|
353
|
-
]
|
|
354
|
-
},
|
|
355
|
-
{
|
|
356
|
-
"name": "Completed",
|
|
357
|
-
"pairs": [
|
|
358
|
-
{
|
|
359
|
-
"prev_node": "In Transit",
|
|
360
|
-
"threshold": 1,
|
|
361
|
-
"forwards": [
|
|
362
|
-
{
|
|
363
|
-
"name": "Complete Order",
|
|
364
|
-
"namedOperator": "",
|
|
365
|
-
"weight": 1
|
|
366
|
-
}
|
|
367
|
-
]
|
|
368
|
-
}
|
|
369
|
-
]
|
|
370
|
-
},
|
|
371
|
-
{
|
|
372
|
-
"name": "Cancelled",
|
|
373
|
-
"pairs": [
|
|
374
|
-
{
|
|
375
|
-
"prev_node": "Order Confirmation",
|
|
376
|
-
"threshold": 0,
|
|
377
|
-
"forwards": [
|
|
378
|
-
{
|
|
379
|
-
"name": "Cancel Order",
|
|
380
|
-
"namedOperator": "",
|
|
381
|
-
"weight": 1
|
|
382
|
-
}
|
|
383
|
-
]
|
|
384
|
-
}
|
|
385
|
-
]
|
|
386
|
-
}
|
|
387
|
-
]
|
|
388
|
-
}
|
|
389
|
-
},
|
|
390
|
-
"env": {
|
|
391
|
-
"account": "myshop_merchant",
|
|
392
|
-
"network": "mainnet"
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
```
|
|
396
|
-
|
|
397
|
-
> **Note**: The "Cancel Order" forward is defined on the "Cancelled" node with `prev_node: "Order Confirmation"`. This means cancellation can only happen AFTER the merchant confirms the order (transitions from "Order Confirmation" to "Cancelled"). The "Cancelled" node is a terminal state with no further forwards.
|
|
398
|
-
|
|
399
|
-
---
|
|
400
|
-
|
|
401
|
-
### Step 5: Publish the Machine
|
|
402
|
-
|
|
403
|
-
Publish the Machine to make it available for creating orders.
|
|
404
|
-
|
|
405
|
-
**Prompt**: Publish the Machine "myshop_machine_v2" to enable order creation.
|
|
406
|
-
|
|
407
|
-
```json
|
|
408
|
-
{
|
|
409
|
-
"operation_type": "machine",
|
|
410
|
-
"data": {
|
|
411
|
-
"object": "myshop_machine_v2",
|
|
412
|
-
"publish": true
|
|
413
|
-
},
|
|
414
|
-
"env": {
|
|
415
|
-
"account": "myshop_merchant",
|
|
416
|
-
"network": "mainnet"
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
```
|
|
420
|
-
|
|
421
|
-
---
|
|
422
|
-
|
|
423
|
-
### Step 6: Create Contact Object for Customer Service
|
|
396
|
+
### Step 4: Create Contact Object for Customer Service
|
|
424
397
|
|
|
425
398
|
Create a Contact object to enable encrypted communication between customers and the store for after-sales support.
|
|
426
399
|
|
|
427
|
-
####
|
|
400
|
+
#### 4.1 Enable Merchant Messenger
|
|
428
401
|
|
|
429
402
|
**Prompt**: Enable messenger for the merchant account.
|
|
430
403
|
|
|
@@ -437,7 +410,7 @@ Create a Contact object to enable encrypted communication between customers and
|
|
|
437
410
|
}
|
|
438
411
|
```
|
|
439
412
|
|
|
440
|
-
####
|
|
413
|
+
#### 4.2 Create After-Sales Contact Object
|
|
441
414
|
|
|
442
415
|
**Prompt**: Create a Contact object named "myshop_aftersales_contact_v2" with permission "myshop_permission_v2" for after-sales support.
|
|
443
416
|
|
|
@@ -463,7 +436,8 @@ Create a Contact object to enable encrypted communication between customers and
|
|
|
463
436
|
},
|
|
464
437
|
"env": {
|
|
465
438
|
"account": "myshop_merchant",
|
|
466
|
-
"network": "mainnet"
|
|
439
|
+
"network": "mainnet",
|
|
440
|
+
"confirmed": true
|
|
467
441
|
}
|
|
468
442
|
}
|
|
469
443
|
```
|
|
@@ -472,13 +446,13 @@ Create a Contact object to enable encrypted communication between customers and
|
|
|
472
446
|
|
|
473
447
|
---
|
|
474
448
|
|
|
475
|
-
### Step
|
|
449
|
+
### Step 5: Create Guards for Fund Allocation
|
|
476
450
|
|
|
477
451
|
Before creating the Service, create Guards that validate fund allocation conditions. These Guards ensure funds are only released when specific conditions are met.
|
|
478
452
|
|
|
479
|
-
####
|
|
453
|
+
#### 5.1 Create Withdraw Guard (Merchant Withdrawal)
|
|
480
454
|
|
|
481
|
-
Create a Guard that validates the order's Progress has reached the "Completed" node. This Guard uses `convert_witness:
|
|
455
|
+
Create a Guard that validates the order's Progress has reached the "Completed" node. This Guard uses `convert_witness: "OrderProgress"` (TypeOrderProgress) to query the Order's associated Progress object.
|
|
482
456
|
|
|
483
457
|
**Prompt**: Create a Guard named "myshop_withdraw_guard_v2" that verifies the order is completed before allowing merchant withdrawal.
|
|
484
458
|
|
|
@@ -488,62 +462,118 @@ Create a Guard that validates the order's Progress has reached the "Completed" n
|
|
|
488
462
|
"data": {
|
|
489
463
|
"namedNew": {
|
|
490
464
|
"name": "myshop_withdraw_guard_v2",
|
|
491
|
-
"tags": ["order", "completed", "withdraw"],
|
|
465
|
+
"tags": ["order", "completed", "withdraw", "signer-bound"],
|
|
492
466
|
"onChain": false,
|
|
493
467
|
"replaceExistName": true
|
|
494
468
|
},
|
|
495
|
-
"description": "Verify order progress is at Completed node for merchant withdrawal",
|
|
469
|
+
"description": "Verify order progress is at Completed node for merchant withdrawal. RISK ELIMINATION: Three-fold verification - (1) order at Completed node, (2) signer is myshop_merchant (prevents fund theft), (3) order belongs to myshop_service_v2 (prevents cross-service theft).",
|
|
496
470
|
"table": [
|
|
497
471
|
{
|
|
498
472
|
"identifier": 0,
|
|
499
473
|
"b_submission": true,
|
|
500
474
|
"value_type": "Address",
|
|
501
|
-
"
|
|
475
|
+
"object_type": "Order",
|
|
476
|
+
"name": "order_address (Order object submitted at runtime)"
|
|
502
477
|
},
|
|
503
478
|
{
|
|
504
479
|
"identifier": 1,
|
|
505
480
|
"b_submission": false,
|
|
506
481
|
"value_type": "String",
|
|
507
482
|
"value": "Completed",
|
|
508
|
-
"name": "
|
|
483
|
+
"name": "Expected Completed node name (case-sensitive)"
|
|
484
|
+
},
|
|
485
|
+
{
|
|
486
|
+
"identifier": 2,
|
|
487
|
+
"b_submission": false,
|
|
488
|
+
"value_type": "Address",
|
|
489
|
+
"value": "myshop_merchant",
|
|
490
|
+
"name": "Authorized merchant address (prevents fund theft by unauthorized callers)"
|
|
491
|
+
},
|
|
492
|
+
{
|
|
493
|
+
"identifier": 3,
|
|
494
|
+
"b_submission": false,
|
|
495
|
+
"value_type": "Address",
|
|
496
|
+
"value": "myshop_service_v2",
|
|
497
|
+
"name": "Expected service address (prevents cross-service fund theft)"
|
|
509
498
|
}
|
|
510
499
|
],
|
|
511
500
|
"root": {
|
|
512
|
-
"type": "
|
|
501
|
+
"type": "logic_and",
|
|
513
502
|
"nodes": [
|
|
514
503
|
{
|
|
515
|
-
"type": "
|
|
516
|
-
"
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
504
|
+
"type": "logic_equal",
|
|
505
|
+
"nodes": [
|
|
506
|
+
{
|
|
507
|
+
"type": "query",
|
|
508
|
+
"query": "progress.current",
|
|
509
|
+
"object": {
|
|
510
|
+
"identifier": 0,
|
|
511
|
+
"convert_witness": "OrderProgress"
|
|
512
|
+
},
|
|
513
|
+
"parameters": []
|
|
514
|
+
},
|
|
515
|
+
{
|
|
516
|
+
"type": "identifier",
|
|
517
|
+
"identifier": 1
|
|
518
|
+
}
|
|
519
|
+
]
|
|
522
520
|
},
|
|
523
521
|
{
|
|
524
|
-
"type": "
|
|
525
|
-
"
|
|
522
|
+
"type": "logic_equal",
|
|
523
|
+
"nodes": [
|
|
524
|
+
{
|
|
525
|
+
"type": "context",
|
|
526
|
+
"context": "Signer"
|
|
527
|
+
},
|
|
528
|
+
{
|
|
529
|
+
"type": "identifier",
|
|
530
|
+
"identifier": 2
|
|
531
|
+
}
|
|
532
|
+
]
|
|
533
|
+
},
|
|
534
|
+
{
|
|
535
|
+
"type": "logic_equal",
|
|
536
|
+
"nodes": [
|
|
537
|
+
{
|
|
538
|
+
"type": "query",
|
|
539
|
+
"query": "order.service",
|
|
540
|
+
"object": {
|
|
541
|
+
"identifier": 0
|
|
542
|
+
},
|
|
543
|
+
"parameters": []
|
|
544
|
+
},
|
|
545
|
+
{
|
|
546
|
+
"type": "identifier",
|
|
547
|
+
"identifier": 3
|
|
548
|
+
}
|
|
549
|
+
]
|
|
526
550
|
}
|
|
527
551
|
]
|
|
528
552
|
}
|
|
529
553
|
},
|
|
530
554
|
"env": {
|
|
531
555
|
"account": "myshop_merchant",
|
|
532
|
-
"network": "mainnet"
|
|
556
|
+
"network": "mainnet",
|
|
557
|
+
"confirmed": true
|
|
533
558
|
}
|
|
534
559
|
}
|
|
535
560
|
```
|
|
536
561
|
|
|
537
|
-
**Guard Explanation:**
|
|
538
|
-
- **Table Item 0**: Order address (submitted
|
|
562
|
+
**Guard Explanation (Three-fold Verification):**
|
|
563
|
+
- **Table Item 0**: Order address (submitted at runtime, typed as Order object)
|
|
539
564
|
- **Table Item 1**: Constant string "Completed" (the target node name)
|
|
540
|
-
- **
|
|
541
|
-
- **
|
|
542
|
-
- **
|
|
543
|
-
|
|
544
|
-
|
|
565
|
+
- **Table Item 2**: Constant address `myshop_merchant` (authorized merchant)
|
|
566
|
+
- **Table Item 3**: Constant address `myshop_service_v2` (this service's on-chain address)
|
|
567
|
+
- **Condition 1 — Order Completed**: `logic_equal[query("progress.current", witness="OrderProgress"), identifier[1]]` — queries the submitted Order's Progress (via witness "OrderProgress") and verifies the current node is "Completed"
|
|
568
|
+
- **Condition 2 — Signer is Merchant**: `logic_equal[context(Signer), identifier[2]]` — verifies the transaction caller is `myshop_merchant`, **preventing fund theft by unauthorized callers** (R-C3-01/R-C3-06)
|
|
569
|
+
- **Condition 3 — Service Ownership**: `logic_equal[query("order.service"), identifier[3]]` — queries the submitted Order's `service` field and verifies it equals `myshop_service_v2`, **preventing cross-service theft** where someone submits another service's Completed order (R-C3-05)
|
|
570
|
+
- **root**: `logic_and` of all three conditions — all must pass for allocation to proceed
|
|
571
|
+
|
|
572
|
+
> **Risk Elimination (R-C3-06)**: The allocator uses `"who": {"Signer": "signer"}` (funds go to the caller). This is safe ONLY because Condition 2 binds the Signer to `myshop_merchant`. Without this binding, anyone could submit any Completed order and steal 100% of funds. The three-fold verification ensures only the authorized merchant can trigger withdrawal.
|
|
573
|
+
>
|
|
574
|
+
> **Note**: The Guard `root` field directly specifies the GuardNode (e.g., `type: "logic_and"`), not wrapped in a `type: "node"` object.
|
|
545
575
|
|
|
546
|
-
####
|
|
576
|
+
#### 5.2 Create Refund Guard (Customer Refund)
|
|
547
577
|
|
|
548
578
|
Create a Guard for customer refunds when order is cancelled.
|
|
549
579
|
|
|
@@ -555,61 +585,122 @@ Create a Guard for customer refunds when order is cancelled.
|
|
|
555
585
|
"data": {
|
|
556
586
|
"namedNew": {
|
|
557
587
|
"name": "myshop_refund_guard_v2",
|
|
558
|
-
"tags": ["order", "cancelled", "refund"],
|
|
588
|
+
"tags": ["order", "cancelled", "refund", "signer-bound"],
|
|
559
589
|
"onChain": false,
|
|
560
590
|
"replaceExistName": true
|
|
561
591
|
},
|
|
562
|
-
"description": "Verify order progress is at Cancelled node for customer refund",
|
|
592
|
+
"description": "Verify order progress is at Cancelled node for customer refund. RISK ELIMINATION: Three-fold verification - (1) order at Cancelled node, (2) signer is order.owner (dynamic query, prevents fund theft - only order owner can trigger their own refund), (3) order belongs to myshop_service_v2 (prevents cross-service theft).",
|
|
563
593
|
"table": [
|
|
564
594
|
{
|
|
565
595
|
"identifier": 0,
|
|
566
596
|
"b_submission": true,
|
|
567
597
|
"value_type": "Address",
|
|
568
|
-
"
|
|
598
|
+
"object_type": "Order",
|
|
599
|
+
"name": "order_address (Order object submitted at runtime)"
|
|
569
600
|
},
|
|
570
601
|
{
|
|
571
602
|
"identifier": 1,
|
|
572
603
|
"b_submission": false,
|
|
573
604
|
"value_type": "String",
|
|
574
605
|
"value": "Cancelled",
|
|
575
|
-
"name": "
|
|
606
|
+
"name": "Expected Cancelled node name (case-sensitive)"
|
|
607
|
+
},
|
|
608
|
+
{
|
|
609
|
+
"identifier": 2,
|
|
610
|
+
"b_submission": false,
|
|
611
|
+
"value_type": "Address",
|
|
612
|
+
"value": "myshop_service_v2",
|
|
613
|
+
"name": "Expected service address (prevents cross-service fund theft)"
|
|
576
614
|
}
|
|
577
615
|
],
|
|
578
616
|
"root": {
|
|
579
|
-
"type": "
|
|
617
|
+
"type": "logic_and",
|
|
580
618
|
"nodes": [
|
|
581
619
|
{
|
|
582
|
-
"type": "
|
|
583
|
-
"
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
620
|
+
"type": "logic_equal",
|
|
621
|
+
"nodes": [
|
|
622
|
+
{
|
|
623
|
+
"type": "query",
|
|
624
|
+
"query": "progress.current",
|
|
625
|
+
"object": {
|
|
626
|
+
"identifier": 0,
|
|
627
|
+
"convert_witness": "OrderProgress"
|
|
628
|
+
},
|
|
629
|
+
"parameters": []
|
|
630
|
+
},
|
|
631
|
+
{
|
|
632
|
+
"type": "identifier",
|
|
633
|
+
"identifier": 1
|
|
634
|
+
}
|
|
635
|
+
]
|
|
589
636
|
},
|
|
590
637
|
{
|
|
591
|
-
"type": "
|
|
592
|
-
"
|
|
638
|
+
"type": "logic_equal",
|
|
639
|
+
"nodes": [
|
|
640
|
+
{
|
|
641
|
+
"type": "context",
|
|
642
|
+
"context": "Signer"
|
|
643
|
+
},
|
|
644
|
+
{
|
|
645
|
+
"type": "query",
|
|
646
|
+
"query": "order.owner",
|
|
647
|
+
"object": {
|
|
648
|
+
"identifier": 0
|
|
649
|
+
},
|
|
650
|
+
"parameters": []
|
|
651
|
+
}
|
|
652
|
+
]
|
|
653
|
+
},
|
|
654
|
+
{
|
|
655
|
+
"type": "logic_equal",
|
|
656
|
+
"nodes": [
|
|
657
|
+
{
|
|
658
|
+
"type": "query",
|
|
659
|
+
"query": "order.service",
|
|
660
|
+
"object": {
|
|
661
|
+
"identifier": 0
|
|
662
|
+
},
|
|
663
|
+
"parameters": []
|
|
664
|
+
},
|
|
665
|
+
{
|
|
666
|
+
"type": "identifier",
|
|
667
|
+
"identifier": 2
|
|
668
|
+
}
|
|
669
|
+
]
|
|
593
670
|
}
|
|
594
671
|
]
|
|
595
672
|
}
|
|
596
673
|
},
|
|
597
674
|
"env": {
|
|
598
675
|
"account": "myshop_merchant",
|
|
599
|
-
"network": "mainnet"
|
|
676
|
+
"network": "mainnet",
|
|
677
|
+
"confirmed": true
|
|
600
678
|
}
|
|
601
679
|
}
|
|
602
680
|
```
|
|
603
681
|
|
|
682
|
+
**Guard Explanation (Three-fold Verification):**
|
|
683
|
+
- **Table Item 0**: Order address (submitted at runtime, typed as Order object)
|
|
684
|
+
- **Table Item 1**: Constant string "Cancelled" (the target node name)
|
|
685
|
+
- **Table Item 2**: Constant address `myshop_service_v2` (this service's on-chain address)
|
|
686
|
+
- **Condition 1 — Order Cancelled**: `logic_equal[query("progress.current", witness="OrderProgress"), identifier[1]]` — queries the submitted Order's Progress (via witness "OrderProgress") and verifies the current node is "Cancelled"
|
|
687
|
+
- **Condition 2 — Signer is Order Owner**: `logic_equal[context(Signer), query("order.owner")]` — verifies the transaction caller is the Order's owner (dynamic query, not a fixed address), **preventing fund theft by unauthorized callers** (R-C3-01/R-C3-06). Only the customer who placed the order can trigger their own refund.
|
|
688
|
+
- **Condition 3 — Service Ownership**: `logic_equal[query("order.service"), identifier[2]]` — queries the submitted Order's `service` field and verifies it equals `myshop_service_v2`, **preventing cross-service theft** (R-C3-05)
|
|
689
|
+
- **root**: `logic_and` of all three conditions — all must pass for refund allocation to proceed
|
|
690
|
+
|
|
691
|
+
> **Risk Elimination (R-C3-06)**: Unlike the withdraw Guard (which binds Signer to a fixed merchant address), the refund Guard binds Signer to `order.owner` via a **dynamic query** (query 1562). This is because refunds flow to the customer, and each order has a different customer. Only the order's rightful owner can trigger the refund — an attacker cannot submit another customer's Cancelled order.
|
|
692
|
+
>
|
|
693
|
+
> **Refund Recipient Design**: The allocator uses `"who": {"GuardIdentifier": 0}` (funds go to the Order object's address, not the caller's wallet). This creates an escrow pattern: the refund is held at the Order object's address, and the customer subsequently claims it via a separate withdraw operation. This ensures traceability and audit trail.
|
|
694
|
+
|
|
604
695
|
---
|
|
605
696
|
|
|
606
|
-
### Step
|
|
697
|
+
### Step 6: Create Service (Store)
|
|
607
698
|
|
|
608
699
|
Create the Service object that represents your online store with products. This step binds all previously created components together.
|
|
609
700
|
|
|
610
701
|
> **Important**: For Service creation, provide a complete configuration including machine, order_allocators with Guards, and products. The Service will be created and published in a single transaction.
|
|
611
702
|
|
|
612
|
-
####
|
|
703
|
+
#### 6.1 Understanding Order Allocators
|
|
613
704
|
|
|
614
705
|
The `order_allocators` configuration defines how order payments are distributed:
|
|
615
706
|
|
|
@@ -621,13 +712,19 @@ The `order_allocators` configuration defines how order payments are distributed:
|
|
|
621
712
|
| **Threshold** | Minimum amount to trigger allocation |
|
|
622
713
|
|
|
623
714
|
**Recipient Types:**
|
|
624
|
-
- `{ "Signer": "signer" }` - Transaction sender (
|
|
625
|
-
- `{ "Entity": { "name_or_address": "..." } }` - Specific address or account name
|
|
626
|
-
- `{ "GuardIdentifier": 0 }` - Address from Guard table
|
|
715
|
+
- `{ "Signer": "signer" }` - Transaction sender (caller). **⚠️ R-C3-06 Risk**: If the Guard does NOT bind the Signer to an authorized address, anyone who passes the Guard can steal 100% of funds. Safe ONLY when the Guard includes a `logic_equal[context(Signer), <authorized_address>]` check.
|
|
716
|
+
- `{ "Entity": { "name_or_address": "..." } }` - Specific address or account name (safest — funds go to a fixed address regardless of caller)
|
|
717
|
+
- `{ "GuardIdentifier": 0 }` - Address from Guard table (e.g., the submitted Order object's address)
|
|
718
|
+
|
|
719
|
+
> **R-C3-06 Risk Elimination — Guard + Sharing Coupling**: The `order_allocators` scene couples Guard verification (WHO can trigger) with sharing recipient (WHERE funds go). This example uses two risk-elimination strategies:
|
|
720
|
+
> - **Withdraw allocator** (`sharing.who = Signer`): Safe because `myshop_withdraw_guard_v2` binds `context(Signer)` to `myshop_merchant` (identifier 2). Only the merchant can pass the Guard, so funds correctly flow to the merchant.
|
|
721
|
+
> - **Refund allocator** (`sharing.who = GuardIdentifier 0`): Funds go to the Order object's address (escrow), not to the caller. The Guard additionally binds `context(Signer)` to `order.owner` (dynamic query 1562), ensuring only the order's rightful owner can trigger the refund.
|
|
722
|
+
>
|
|
723
|
+
> **Alternative approach**: Instead of Signer binding in the Guard, you can use `sharing.who = Entity` to send funds to a fixed Treasury or personal address. This is even more robust because funds are directed regardless of who passes the Guard. See the Insurance example for this pattern.
|
|
627
724
|
|
|
628
725
|
> **Design Decision — Refund Recipient**: When using `{ "GuardIdentifier": 0 }` in the refund allocation, the refund is sent to the **Order object's on-chain address** (not the customer's wallet address). This is by design: the Order object acts as an escrow holding the refunded payment at its own address. The customer subsequently claims the refund from the Order object via a separate withdraw operation. This two-step design ensures the refund is traceable on-chain and tied to the specific order, providing better dispute resolution and audit trail.
|
|
629
726
|
|
|
630
|
-
####
|
|
727
|
+
#### 6.2 Create and Publish Service
|
|
631
728
|
|
|
632
729
|
**Prompt**: Create and publish a Service named "myshop_service_v2" with machine "myshop_machine_v2", order allocation using Guards, after-sales contact, and toy products.
|
|
633
730
|
|
|
@@ -706,7 +803,8 @@ The `order_allocators` configuration defines how order payments are distributed:
|
|
|
706
803
|
},
|
|
707
804
|
"env": {
|
|
708
805
|
"account": "myshop_merchant",
|
|
709
|
-
"network": "mainnet"
|
|
806
|
+
"network": "mainnet",
|
|
807
|
+
"confirmed": true
|
|
710
808
|
}
|
|
711
809
|
}
|
|
712
810
|
```
|
|
@@ -718,7 +816,7 @@ The `order_allocators` configuration defines how order payments are distributed:
|
|
|
718
816
|
|
|
719
817
|
---
|
|
720
818
|
|
|
721
|
-
### Step
|
|
819
|
+
### Step 7: Update Product Pricing (Optional)
|
|
722
820
|
|
|
723
821
|
To offer promotional pricing, update product prices using the `sales` operation with `op: "set"`:
|
|
724
822
|
|
|
@@ -745,7 +843,8 @@ To offer promotional pricing, update product prices using the `sales` operation
|
|
|
745
843
|
},
|
|
746
844
|
"env": {
|
|
747
845
|
"account": "myshop_merchant",
|
|
748
|
-
"network": "mainnet"
|
|
846
|
+
"network": "mainnet",
|
|
847
|
+
"confirmed": true
|
|
749
848
|
}
|
|
750
849
|
}
|
|
751
850
|
```
|
|
@@ -778,8 +877,10 @@ Create a customer account:
|
|
|
778
877
|
```json
|
|
779
878
|
{
|
|
780
879
|
"transfer": {
|
|
781
|
-
"
|
|
782
|
-
"amount": 1000000000
|
|
880
|
+
"name_or_address_to": "myshop_customer",
|
|
881
|
+
"amount": 1000000000,
|
|
882
|
+
"network": "mainnet",
|
|
883
|
+
"confirmed": true
|
|
783
884
|
}
|
|
784
885
|
}
|
|
785
886
|
```
|
|
@@ -802,7 +903,7 @@ Customers can query the Service to see available products.
|
|
|
802
903
|
}
|
|
803
904
|
```
|
|
804
905
|
|
|
805
|
-
> **AI Note**: Capture the `wip_hash` from the Service query result for each product. When the customer places an order, pass the captured `wip_hash` in `buy.items[].wip_hash`. This is a dispute-prevention mechanism — the on-chain contract compares `item.wip_hash` against the Service's current `sale.wip_hash` to ensure the product hasn't been swapped between browse and purchase time.
|
|
906
|
+
> **AI Note**: Capture the `wip_hash` from the Service query result for each product. When the customer places an order, pass the captured `wip_hash` in `buy.items[].wip_hash`. **The `wip_hash` field cannot be an empty string** — it must match the hash stored in the Service. This is a dispute-prevention mechanism — the on-chain contract compares `item.wip_hash` against the Service's current `sale.wip_hash` to ensure the product hasn't been swapped between browse and purchase time.
|
|
806
907
|
|
|
807
908
|
---
|
|
808
909
|
|
|
@@ -823,7 +924,7 @@ Customer creates an order by purchasing products from the Service.
|
|
|
823
924
|
{
|
|
824
925
|
"name": "Play Purse Set 35PCS",
|
|
825
926
|
"stock": 1,
|
|
826
|
-
"wip_hash": ""
|
|
927
|
+
"wip_hash": "03c18561efa8faf4d75480eb1f732c4a46ffde95599e92eca06167785fc07a5b"
|
|
827
928
|
}
|
|
828
929
|
],
|
|
829
930
|
"total_pay": {
|
|
@@ -846,7 +947,8 @@ Customer creates an order by purchasing products from the Service.
|
|
|
846
947
|
},
|
|
847
948
|
"env": {
|
|
848
949
|
"account": "myshop_customer",
|
|
849
|
-
"network": "mainnet"
|
|
950
|
+
"network": "mainnet",
|
|
951
|
+
"confirmed": true
|
|
850
952
|
}
|
|
851
953
|
}
|
|
852
954
|
```
|
|
@@ -1010,7 +1112,8 @@ Merchant advances the order from initial state to "Order Confirmation" node.
|
|
|
1010
1112
|
},
|
|
1011
1113
|
"env": {
|
|
1012
1114
|
"account": "myshop_merchant",
|
|
1013
|
-
"network": "mainnet"
|
|
1115
|
+
"network": "mainnet",
|
|
1116
|
+
"confirmed": true
|
|
1014
1117
|
}
|
|
1015
1118
|
}
|
|
1016
1119
|
```
|
|
@@ -1039,7 +1142,8 @@ Merchant ships the order and advances from "Order Confirmation" to "Shipping".
|
|
|
1039
1142
|
},
|
|
1040
1143
|
"env": {
|
|
1041
1144
|
"account": "myshop_merchant",
|
|
1042
|
-
"network": "mainnet"
|
|
1145
|
+
"network": "mainnet",
|
|
1146
|
+
"confirmed": true
|
|
1043
1147
|
}
|
|
1044
1148
|
}
|
|
1045
1149
|
```
|
|
@@ -1068,7 +1172,8 @@ Merchant or delivery service confirms the order has been delivered.
|
|
|
1068
1172
|
},
|
|
1069
1173
|
"env": {
|
|
1070
1174
|
"account": "myshop_merchant",
|
|
1071
|
-
"network": "mainnet"
|
|
1175
|
+
"network": "mainnet",
|
|
1176
|
+
"confirmed": true
|
|
1072
1177
|
}
|
|
1073
1178
|
}
|
|
1074
1179
|
```
|
|
@@ -1097,7 +1202,8 @@ Customer confirms receipt and completes the order.
|
|
|
1097
1202
|
},
|
|
1098
1203
|
"env": {
|
|
1099
1204
|
"account": "myshop_customer",
|
|
1100
|
-
"network": "mainnet"
|
|
1205
|
+
"network": "mainnet",
|
|
1206
|
+
"confirmed": true
|
|
1101
1207
|
}
|
|
1102
1208
|
}
|
|
1103
1209
|
```
|
|
@@ -1110,7 +1216,7 @@ After order completion, the merchant needs to:
|
|
|
1110
1216
|
1. Activate the Allocation by verifying the Guard (order completion status)
|
|
1111
1217
|
2. Withdraw funds from the Service
|
|
1112
1218
|
|
|
1113
|
-
####
|
|
1219
|
+
#### 7.1 Activate Allocation (Guard Verification)
|
|
1114
1220
|
|
|
1115
1221
|
First, activate the Allocation by submitting the Guard verification with the Order ID.
|
|
1116
1222
|
|
|
@@ -1151,6 +1257,7 @@ First, activate the Allocation by submitting the Guard verification with the Ord
|
|
|
1151
1257
|
"env": {
|
|
1152
1258
|
"account": "myshop_merchant",
|
|
1153
1259
|
"network": "mainnet",
|
|
1260
|
+
"confirmed": true,
|
|
1154
1261
|
"no_cache": true
|
|
1155
1262
|
}
|
|
1156
1263
|
}
|
|
@@ -1158,7 +1265,7 @@ First, activate the Allocation by submitting the Guard verification with the Ord
|
|
|
1158
1265
|
|
|
1159
1266
|
> **Note**: Replace the Guard address `0x5af9...1074` and Order address `0xa6db...3d5` with your actual object addresses. Use the full 64-character addresses in actual operations.
|
|
1160
1267
|
|
|
1161
|
-
####
|
|
1268
|
+
#### 7.2 Withdraw Funds from Service
|
|
1162
1269
|
|
|
1163
1270
|
After the Allocation is activated, withdraw the funds from the Service.
|
|
1164
1271
|
|
|
@@ -1173,7 +1280,8 @@ After the Allocation is activated, withdraw the funds from the Service.
|
|
|
1173
1280
|
},
|
|
1174
1281
|
"env": {
|
|
1175
1282
|
"account": "myshop_merchant",
|
|
1176
|
-
"network": "mainnet"
|
|
1283
|
+
"network": "mainnet",
|
|
1284
|
+
"confirmed": true
|
|
1177
1285
|
}
|
|
1178
1286
|
}
|
|
1179
1287
|
```
|
|
@@ -1204,7 +1312,8 @@ Customer can cancel the order after the merchant confirms it. The "Cancel Order"
|
|
|
1204
1312
|
},
|
|
1205
1313
|
"env": {
|
|
1206
1314
|
"account": "myshop_merchant",
|
|
1207
|
-
"network": "mainnet"
|
|
1315
|
+
"network": "mainnet",
|
|
1316
|
+
"confirmed": true
|
|
1208
1317
|
}
|
|
1209
1318
|
}
|
|
1210
1319
|
```
|
|
@@ -1229,7 +1338,8 @@ Customer can cancel the order after the merchant confirms it. The "Cancel Order"
|
|
|
1229
1338
|
},
|
|
1230
1339
|
"env": {
|
|
1231
1340
|
"account": "myshop_customer",
|
|
1232
|
-
"network": "mainnet"
|
|
1341
|
+
"network": "mainnet",
|
|
1342
|
+
"confirmed": true
|
|
1233
1343
|
}
|
|
1234
1344
|
}
|
|
1235
1345
|
```
|
|
@@ -1273,6 +1383,7 @@ After the order is cancelled, the customer can activate the refund allocation us
|
|
|
1273
1383
|
"env": {
|
|
1274
1384
|
"account": "myshop_customer",
|
|
1275
1385
|
"network": "mainnet",
|
|
1386
|
+
"confirmed": true,
|
|
1276
1387
|
"no_cache": true
|
|
1277
1388
|
}
|
|
1278
1389
|
}
|
|
@@ -1308,7 +1419,8 @@ The Service must have a compensation fund balance ≥ the arbitration indemnity
|
|
|
1308
1419
|
},
|
|
1309
1420
|
"env": {
|
|
1310
1421
|
"account": "myshop_merchant",
|
|
1311
|
-
"network": "mainnet"
|
|
1422
|
+
"network": "mainnet",
|
|
1423
|
+
"confirmed": true
|
|
1312
1424
|
}
|
|
1313
1425
|
}
|
|
1314
1426
|
```
|
|
@@ -1336,7 +1448,8 @@ Create an Arbitration object for handling order disputes.
|
|
|
1336
1448
|
},
|
|
1337
1449
|
"env": {
|
|
1338
1450
|
"account": "myshop_merchant",
|
|
1339
|
-
"network": "mainnet"
|
|
1451
|
+
"network": "mainnet",
|
|
1452
|
+
"confirmed": true
|
|
1340
1453
|
}
|
|
1341
1454
|
}
|
|
1342
1455
|
```
|
|
@@ -1358,7 +1471,8 @@ The merchant unpauses the Arbitration object to enable dispute submissions.
|
|
|
1358
1471
|
},
|
|
1359
1472
|
"env": {
|
|
1360
1473
|
"account": "myshop_merchant",
|
|
1361
|
-
"network": "mainnet"
|
|
1474
|
+
"network": "mainnet",
|
|
1475
|
+
"confirmed": true
|
|
1362
1476
|
}
|
|
1363
1477
|
}
|
|
1364
1478
|
```
|
|
@@ -1379,7 +1493,8 @@ Create a new order for testing the arbitration flow (if you don't have one alrea
|
|
|
1379
1493
|
"items": [
|
|
1380
1494
|
{
|
|
1381
1495
|
"name": "Tree House Building Set",
|
|
1382
|
-
"stock": 1
|
|
1496
|
+
"stock": 1,
|
|
1497
|
+
"wip_hash": "03c18561efa8faf4d75480eb1f732c4a46ffde95599e92eca06167785fc07a5b"
|
|
1383
1498
|
}
|
|
1384
1499
|
],
|
|
1385
1500
|
"total_pay": {"balance": 30000000}
|
|
@@ -1391,12 +1506,13 @@ Create a new order for testing the arbitration flow (if you don't have one alrea
|
|
|
1391
1506
|
},
|
|
1392
1507
|
"env": {
|
|
1393
1508
|
"account": "myshop_customer",
|
|
1394
|
-
"network": "mainnet"
|
|
1509
|
+
"network": "mainnet",
|
|
1510
|
+
"confirmed": true
|
|
1395
1511
|
}
|
|
1396
1512
|
}
|
|
1397
1513
|
```
|
|
1398
1514
|
|
|
1399
|
-
> **Note**: The
|
|
1515
|
+
> **Note**: The `wip_hash` must be obtained from the Service query result (Step 1 of Part 2). It cannot be omitted or set to an empty string — the on-chain contract validates it against the Service's current `sale.wip_hash`.
|
|
1400
1516
|
|
|
1401
1517
|
### Step 5: Customer Submits Dispute
|
|
1402
1518
|
|
|
@@ -1419,7 +1535,8 @@ The customer submits a dispute against the order, creating an Arb object.
|
|
|
1419
1535
|
},
|
|
1420
1536
|
"env": {
|
|
1421
1537
|
"account": "myshop_customer",
|
|
1422
|
-
"network": "mainnet"
|
|
1538
|
+
"network": "mainnet",
|
|
1539
|
+
"confirmed": true
|
|
1423
1540
|
}
|
|
1424
1541
|
}
|
|
1425
1542
|
```
|
|
@@ -1444,7 +1561,8 @@ The merchant confirms the dispute materials are valid and sets the voting deadli
|
|
|
1444
1561
|
},
|
|
1445
1562
|
"env": {
|
|
1446
1563
|
"account": "myshop_merchant",
|
|
1447
|
-
"network": "mainnet"
|
|
1564
|
+
"network": "mainnet",
|
|
1565
|
+
"confirmed": true
|
|
1448
1566
|
}
|
|
1449
1567
|
}
|
|
1450
1568
|
```
|
|
@@ -1470,7 +1588,8 @@ The merchant provides the final arbitration result with feedback and indemnity a
|
|
|
1470
1588
|
},
|
|
1471
1589
|
"env": {
|
|
1472
1590
|
"account": "myshop_merchant",
|
|
1473
|
-
"network": "mainnet"
|
|
1591
|
+
"network": "mainnet",
|
|
1592
|
+
"confirmed": true
|
|
1474
1593
|
}
|
|
1475
1594
|
}
|
|
1476
1595
|
```
|
|
@@ -1494,7 +1613,8 @@ The customer claims the compensation from the Service's compensation fund.
|
|
|
1494
1613
|
},
|
|
1495
1614
|
"env": {
|
|
1496
1615
|
"account": "myshop_customer",
|
|
1497
|
-
"network": "mainnet"
|
|
1616
|
+
"network": "mainnet",
|
|
1617
|
+
"confirmed": true
|
|
1498
1618
|
}
|
|
1499
1619
|
}
|
|
1500
1620
|
```
|
|
@@ -1573,7 +1693,8 @@ When advancing order workflows, use `operation_type: "progress"` with the `opera
|
|
|
1573
1693
|
},
|
|
1574
1694
|
"env": {
|
|
1575
1695
|
"account": "operator_account",
|
|
1576
|
-
"network": "mainnet"
|
|
1696
|
+
"network": "mainnet",
|
|
1697
|
+
"confirmed": true
|
|
1577
1698
|
}
|
|
1578
1699
|
}
|
|
1579
1700
|
```
|