@wowok/skills 3.0.4 → 3.1.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/README.md +146 -122
- package/dist/cli.d.ts +6 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +223 -837
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +24 -1
- package/dist/index.js.map +1 -1
- package/dist/installer.d.ts +121 -0
- package/dist/installer.d.ts.map +1 -0
- package/dist/installer.js +802 -0
- package/dist/installer.js.map +1 -0
- package/dist/skills.d.ts +5 -2
- package/dist/skills.d.ts.map +1 -1
- package/dist/skills.js +86 -62
- package/dist/skills.js.map +1 -1
- package/dist/targets.d.ts +94 -0
- package/dist/targets.d.ts.map +1 -0
- package/dist/targets.js +421 -0
- package/dist/targets.js.map +1 -0
- package/dist/types.d.ts +5 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +0 -32
- package/dist/types.js.map +1 -1
- package/package.json +5 -4
- package/scripts/install.js +21 -859
- package/wowok-arbitrator/SKILL.md +5 -12
- package/wowok-auditor/SKILL.md +5 -17
- package/wowok-collaborator/SKILL.md +5 -17
- package/wowok-governance/SKILL.md +10 -30
- package/wowok-machine/SKILL.md +5 -18
- package/wowok-market/SKILL.md +5 -21
- package/wowok-messenger/SKILL.md +32 -50
- package/wowok-onboard/SKILL.md +5 -22
- package/wowok-order/SKILL.md +6 -19
- package/wowok-output/SKILL.md +5 -10
- package/wowok-planner/SKILL.md +6 -20
- package/wowok-provider/SKILL.md +6 -18
- package/wowok-supplier/SKILL.md +5 -16
- package/examples/Insurance/Insurance.md +0 -1245
- package/examples/MyShop/MyShop.md +0 -2003
- package/examples/MyShop/myshop_machine_nodes.json +0 -93
- package/examples/MyShop_Advanced/MyShop_Advanced.md +0 -2880
- package/examples/ThreeBody_Signature/ThreeBody_Signature.md +0 -1831
- package/examples/Travel/Travel.md +0 -1849
- package/examples/Travel/calc-weather-timestamps.js +0 -12
|
@@ -1,2003 +0,0 @@
|
|
|
1
|
-
# MyShop E-Commerce Example
|
|
2
|
-
|
|
3
|
-
A complete e-commerce example demonstrating how to build an online store using WoWok protocol. This guide covers both merchant setup and customer order workflows.
|
|
4
|
-
|
|
5
|
-
---
|
|
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–8) → 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
|
-
> **💡 Call Format**: All WoWok operations go through a single unified `wowok` tool. The AI calls `wowok({ tool: "<sub-tool>", data: {<params>} })`. If parameters don't match the schema, the response includes the correct schema for self-correction. See [Response Format](../../docs/response-format.md) for details.
|
|
15
|
-
|
|
16
|
-
---
|
|
17
|
-
|
|
18
|
-
## Core Requirements & Features
|
|
19
|
-
|
|
20
|
-
| Requirement | Description | Implementation |
|
|
21
|
-
|-------------|-------------|----------------|
|
|
22
|
-
| **Product Listing** | Create and manage product/service listings | Service object with pricing, inventory, and WIP integration |
|
|
23
|
-
| **Order Workflow** | Automated order processing from creation to completion | Machine with nodes: Order Confirmation → Shipping → In Transit → Completed |
|
|
24
|
-
| **Permission Control** | Role-based access for merchant and customer operations | Permission object with custom indexes for merchant operations |
|
|
25
|
-
| **Arbitration Support** | Dispute resolution mechanism | Arbitration object for handling order conflicts |
|
|
26
|
-
| **WIP Verification** | Product authenticity verification via WIP files | WIP hash stored in Service for customer verification |
|
|
27
|
-
| **Customer Communication** | Secure messaging between merchant and customer | Contact objects for pre-sales and after-sales support |
|
|
28
|
-
|
|
29
|
-
### Key Design Decisions
|
|
30
|
-
|
|
31
|
-
1. **Workflow-Driven Orders**: Order state transitions controlled by Machine workflow, ensuring predictable processing
|
|
32
|
-
2. **Permission-Based Operations**: Merchant operations require specific permission indexes (1000-1002)
|
|
33
|
-
3. **Customer Ownership**: Order owners can cancel orders and complete orders via `namedOperator: ""`
|
|
34
|
-
4. **Modular Architecture**: Separate objects for Permission, Machine, Service, Arbitration, and Contact
|
|
35
|
-
|
|
36
|
-
---
|
|
37
|
-
|
|
38
|
-
## Overview
|
|
39
|
-
|
|
40
|
-
This example demonstrates a toy store e-commerce system with the following features:
|
|
41
|
-
|
|
42
|
-
- **Merchant System**: Product listing, order management, workflow automation
|
|
43
|
-
- **Customer Experience**: Browse products, place orders, track progress
|
|
44
|
-
- **Trust & Security**: Arbitration for disputes, WIP for product verification
|
|
45
|
-
- **Workflow Automation**: Machine-driven order processing from confirmation to delivery
|
|
46
|
-
|
|
47
|
-
---
|
|
48
|
-
|
|
49
|
-
## Architecture
|
|
50
|
-
|
|
51
|
-
### System Components
|
|
52
|
-
|
|
53
|
-
```
|
|
54
|
-
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
55
|
-
│ MyShop E-Commerce System │
|
|
56
|
-
├─────────────────────────────────────────────────────────────────────────────┤
|
|
57
|
-
│ │
|
|
58
|
-
│ ┌─────────────────────────┐ ┌─────────────────────────┐ │
|
|
59
|
-
│ │ Merchant System │ │ Customer System │ │
|
|
60
|
-
│ ├─────────────────────────┤ ├─────────────────────────┤ │
|
|
61
|
-
│ │ • Permission (Access) │ │ • Browse Products │ │
|
|
62
|
-
│ │ • Machine (Workflow) │ │ • Create Order │ │
|
|
63
|
-
│ │ • Service (Products) │◄──►│ • Send Private Info(*) │ │
|
|
64
|
-
│ │ • Allocation (Payment) │ │ • Track Progress │ │
|
|
65
|
-
│ │ • Contact (Messaging) │ │ • Order Complete │ │
|
|
66
|
-
│ └─────────────────────────┘ └─────────────────────────┘ │
|
|
67
|
-
│ │
|
|
68
|
-
│ Optional: Arbitration (Dispute Resolution) │
|
|
69
|
-
│ │
|
|
70
|
-
└─────────────────────────────────────────────────────────────────────────────┘
|
|
71
|
-
|
|
72
|
-
> **\*** Private information (shipping address, phone number) is sent via encrypted Messenger after order creation, not stored on-chain.
|
|
73
|
-
|
|
74
|
-
### Order Workflow (Happy Path)
|
|
75
|
-
|
|
76
|
-
```
|
|
77
|
-
┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
|
78
|
-
│ Order │────►│ Shipping │────►│ In Transit │────►│ Completed │
|
|
79
|
-
│ Confirmation │ │ │ │ │ │ │
|
|
80
|
-
└──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘
|
|
81
|
-
│ │
|
|
82
|
-
│ ┌──────────────┐ │
|
|
83
|
-
└───────────────────►│ Cancelled │◄───────────────────────┘
|
|
84
|
-
(Cancel Order) │(Final State) │ (Complete Order)
|
|
85
|
-
└──────────────┘
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
**Normal Flow**: Order Confirmation → Shipping → In Transit → Completed
|
|
89
|
-
**Alternative**: Order Confirmation → Cancelled (if customer cancels before shipping)
|
|
90
|
-
|
|
91
|
-
---
|
|
92
|
-
|
|
93
|
-
## Part 1: Merchant System Setup
|
|
94
|
-
|
|
95
|
-
This section guides merchants through setting up their online store.
|
|
96
|
-
|
|
97
|
-
### Prerequisites
|
|
98
|
-
|
|
99
|
-
Before starting, ensure you have:
|
|
100
|
-
- A WoWok account with mainnet WOW tokens (gas)
|
|
101
|
-
- Access to the WoWok MCP server
|
|
102
|
-
|
|
103
|
-
**Create merchant account:**
|
|
104
|
-
|
|
105
|
-
**Prompt**: Create a new account named "myshop_merchant" for the store owner.
|
|
106
|
-
|
|
107
|
-
```json
|
|
108
|
-
{
|
|
109
|
-
"tool": "account_operation",
|
|
110
|
-
"data": {
|
|
111
|
-
"gen": {
|
|
112
|
-
"name": "myshop_merchant",
|
|
113
|
-
"replaceExistName": true
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
**Get mainnet tokens:**
|
|
120
|
-
|
|
121
|
-
**Prompt**: Transfer 1 WOW to account "myshop_merchant" from a funded account for gas fees.
|
|
122
|
-
|
|
123
|
-
```json
|
|
124
|
-
{
|
|
125
|
-
"tool": "account_operation",
|
|
126
|
-
"data": {
|
|
127
|
-
"transfer": {
|
|
128
|
-
"name_or_address_to": "myshop_merchant",
|
|
129
|
-
"amount": 1000000000,
|
|
130
|
-
"network": "mainnet"
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
---
|
|
137
|
-
|
|
138
|
-
### Step 1: Create Permission Object
|
|
139
|
-
|
|
140
|
-
First, create a Permission object to manage access control for your store operations.
|
|
141
|
-
|
|
142
|
-
**Prompt**: Create a Permission object named "myshop_permission_v2" with tags ["ecommerce", "toys", "shop"] and description "Permission management for MyShop toy store".
|
|
143
|
-
|
|
144
|
-
```json
|
|
145
|
-
{
|
|
146
|
-
"tool": "onchain_operations",
|
|
147
|
-
"data": {
|
|
148
|
-
"operation_type": "permission",
|
|
149
|
-
"data": {
|
|
150
|
-
"object": {
|
|
151
|
-
"name": "myshop_permission_v2",
|
|
152
|
-
"tags": ["ecommerce", "toys", "shop"],
|
|
153
|
-
"onChain": false,
|
|
154
|
-
"replaceExistName": true
|
|
155
|
-
},
|
|
156
|
-
"description": "Permission management for MyShop toy store"
|
|
157
|
-
},
|
|
158
|
-
"env": {
|
|
159
|
-
"account": "myshop_merchant",
|
|
160
|
-
"network": "mainnet",
|
|
161
|
-
"confirmed": true
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
---
|
|
168
|
-
|
|
169
|
-
### Step 2: Create Machine with Workflow Nodes
|
|
170
|
-
|
|
171
|
-
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.
|
|
172
|
-
|
|
173
|
-
> **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.
|
|
174
|
-
|
|
175
|
-
**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.
|
|
176
|
-
|
|
177
|
-
```json
|
|
178
|
-
{
|
|
179
|
-
"tool": "onchain_operations",
|
|
180
|
-
"data": {
|
|
181
|
-
"operation_type": "machine",
|
|
182
|
-
"data": {
|
|
183
|
-
"object": {
|
|
184
|
-
"name": "myshop_machine_v2",
|
|
185
|
-
"permission": "myshop_permission_v2",
|
|
186
|
-
"replaceExistName": true
|
|
187
|
-
},
|
|
188
|
-
"description": "Order processing workflow for MyShop toy store",
|
|
189
|
-
"node": {
|
|
190
|
-
"op": "add",
|
|
191
|
-
"nodes": [
|
|
192
|
-
{
|
|
193
|
-
"name": "Cancelled",
|
|
194
|
-
"pairs": [
|
|
195
|
-
{
|
|
196
|
-
"prev_node": "",
|
|
197
|
-
"threshold": 0,
|
|
198
|
-
"forwards": [
|
|
199
|
-
{
|
|
200
|
-
"name": "Cancel Order",
|
|
201
|
-
"weight": 1,
|
|
202
|
-
"namedOperator": ""
|
|
203
|
-
}
|
|
204
|
-
]
|
|
205
|
-
},
|
|
206
|
-
{
|
|
207
|
-
"prev_node": "Order Confirmation",
|
|
208
|
-
"threshold": 1,
|
|
209
|
-
"forwards": [
|
|
210
|
-
{
|
|
211
|
-
"name": "Cancel Order",
|
|
212
|
-
"weight": 1,
|
|
213
|
-
"namedOperator": ""
|
|
214
|
-
}
|
|
215
|
-
]
|
|
216
|
-
}
|
|
217
|
-
]
|
|
218
|
-
},
|
|
219
|
-
{
|
|
220
|
-
"name": "Completed",
|
|
221
|
-
"pairs": [
|
|
222
|
-
{
|
|
223
|
-
"prev_node": "In Transit",
|
|
224
|
-
"threshold": 1,
|
|
225
|
-
"forwards": [
|
|
226
|
-
{
|
|
227
|
-
"name": "Complete Order",
|
|
228
|
-
"weight": 1,
|
|
229
|
-
"namedOperator": ""
|
|
230
|
-
}
|
|
231
|
-
]
|
|
232
|
-
}
|
|
233
|
-
]
|
|
234
|
-
},
|
|
235
|
-
{
|
|
236
|
-
"name": "In Transit",
|
|
237
|
-
"pairs": [
|
|
238
|
-
{
|
|
239
|
-
"prev_node": "Shipping",
|
|
240
|
-
"threshold": 1,
|
|
241
|
-
"forwards": [
|
|
242
|
-
{
|
|
243
|
-
"name": "Confirm Delivery",
|
|
244
|
-
"weight": 1,
|
|
245
|
-
"permissionIndex": 1002
|
|
246
|
-
}
|
|
247
|
-
]
|
|
248
|
-
}
|
|
249
|
-
]
|
|
250
|
-
},
|
|
251
|
-
{
|
|
252
|
-
"name": "Order Confirmation",
|
|
253
|
-
"pairs": [
|
|
254
|
-
{
|
|
255
|
-
"prev_node": "",
|
|
256
|
-
"threshold": 0,
|
|
257
|
-
"forwards": [
|
|
258
|
-
{
|
|
259
|
-
"name": "Confirm Order",
|
|
260
|
-
"weight": 1,
|
|
261
|
-
"permissionIndex": 1000
|
|
262
|
-
}
|
|
263
|
-
]
|
|
264
|
-
}
|
|
265
|
-
]
|
|
266
|
-
},
|
|
267
|
-
{
|
|
268
|
-
"name": "Shipping",
|
|
269
|
-
"pairs": [
|
|
270
|
-
{
|
|
271
|
-
"prev_node": "Order Confirmation",
|
|
272
|
-
"threshold": 1,
|
|
273
|
-
"forwards": [
|
|
274
|
-
{
|
|
275
|
-
"name": "Ship Goods",
|
|
276
|
-
"weight": 1,
|
|
277
|
-
"permissionIndex": 1001
|
|
278
|
-
}
|
|
279
|
-
]
|
|
280
|
-
}
|
|
281
|
-
]
|
|
282
|
-
}
|
|
283
|
-
]
|
|
284
|
-
},
|
|
285
|
-
"publish": true
|
|
286
|
-
},
|
|
287
|
-
"env": {
|
|
288
|
-
"account": "myshop_merchant",
|
|
289
|
-
"network": "mainnet",
|
|
290
|
-
"confirmed": true
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
```
|
|
295
|
-
|
|
296
|
-
> **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).
|
|
297
|
-
|
|
298
|
-
---
|
|
299
|
-
|
|
300
|
-
### Step 3: Machine Workflow Design
|
|
301
|
-
|
|
302
|
-
Before adding nodes, let's understand the order processing workflow:
|
|
303
|
-
|
|
304
|
-
```
|
|
305
|
-
┌─────────────────────────────────────────────────────────────────────────────────────┐
|
|
306
|
-
│ MyShop Order Processing Workflow │
|
|
307
|
-
├─────────────────────────────────────────────────────────────────────────────────────┤
|
|
308
|
-
│ │
|
|
309
|
-
│ ┌──────────────────┐ │
|
|
310
|
-
│ │ Order Created │◄─────────────────────────────────────────────────────────┐ │
|
|
311
|
-
│ │ (Initial State) │ │ │
|
|
312
|
-
│ └────────┬─────────┘ │ │
|
|
313
|
-
│ │ │ │
|
|
314
|
-
│ ▼ │ │
|
|
315
|
-
│ ┌──────────────────┐ ┌──────────────┐ ┌──────────────┐ │ │
|
|
316
|
-
│ │ Order Confirmation│────►│ Confirm Order│ │ Cancel Order │───────────────────┘ │
|
|
317
|
-
│ │ (Node 1) │ │ (Merchant) │ │ (Customer) │ │
|
|
318
|
-
│ │ │ │ permission │ │ (Order │ │
|
|
319
|
-
│ └────────┬─────────┘ │ Index 1000 │ │ Owner) │ │
|
|
320
|
-
│ │ └──────────────┘ └──────────────┘ │
|
|
321
|
-
│ │ │ │
|
|
322
|
-
│ │ ▼ │
|
|
323
|
-
│ │ ┌──────────────┐ │
|
|
324
|
-
│ │ │ Threshold │ │
|
|
325
|
-
│ │ │ = 1 │ │
|
|
326
|
-
│ │ └──────┬───────┘ │
|
|
327
|
-
│ │ │ │
|
|
328
|
-
│ ▼ ▼ │
|
|
329
|
-
│ ┌──────────────────┐ │
|
|
330
|
-
│ │ Shipping │◄─────────────────────────────────────────────────────────┐ │
|
|
331
|
-
│ │ (Node 2) │ │ │
|
|
332
|
-
│ │ │ ┌──────────────┐ │ │
|
|
333
|
-
│ └────────┬─────────┘────►│ Ship Goods │ │ │
|
|
334
|
-
│ │ │ (Merchant) │ │ │
|
|
335
|
-
│ │ │ permission │ │ │
|
|
336
|
-
│ │ │ Index 1001 │ │ │
|
|
337
|
-
│ │ └──────────────┘ │ │
|
|
338
|
-
│ │ │ │ │
|
|
339
|
-
│ │ ▼ │ │
|
|
340
|
-
│ │ ┌──────────────┐ │ │
|
|
341
|
-
│ │ │ Threshold │ │ │
|
|
342
|
-
│ │ │ = 1 │ │ │
|
|
343
|
-
│ │ └──────┬───────┘ │ │
|
|
344
|
-
│ │ │ │ │
|
|
345
|
-
│ ▼ ▼ │ │
|
|
346
|
-
│ ┌──────────────────┐ │
|
|
347
|
-
│ │ In Transit │◄─────────────────────────────────────────────────────────┐ │
|
|
348
|
-
│ │ (Node 3) │ │ │
|
|
349
|
-
│ │ │ ┌──────────────┐ │ │
|
|
350
|
-
│ └────────┬─────────┘────►│Confirm Delivery │ │
|
|
351
|
-
│ │ │ (Merchant) │ │ │
|
|
352
|
-
│ │ │ permission │ │ │
|
|
353
|
-
│ │ │ Index 1002 │ │ │
|
|
354
|
-
│ │ └──────────────┘ │ │
|
|
355
|
-
│ │ │ │ │
|
|
356
|
-
│ │ ▼ │ │
|
|
357
|
-
│ │ ┌──────────────┐ │ │
|
|
358
|
-
│ │ │ Threshold │ │ │
|
|
359
|
-
│ │ │ = 1 │ │ │
|
|
360
|
-
│ │ └──────┬───────┘ │ │
|
|
361
|
-
│ │ │ │ │
|
|
362
|
-
│ ▼ ▼ │ │
|
|
363
|
-
│ ┌──────────────────┐ │
|
|
364
|
-
│ │ Completed │◄─────────────────────────────────────────────────────────┐ │
|
|
365
|
-
│ │ (Node 4) │ │ │
|
|
366
|
-
│ │ │ ┌──────────────┐ │ │
|
|
367
|
-
│ └────────┬─────────┘────►│Complete Order│ │ │
|
|
368
|
-
│ │ │ (Customer) │ │ │
|
|
369
|
-
│ │ │ (Order │ │ │
|
|
370
|
-
│ │ │ Owner) │ │ │
|
|
371
|
-
│ │ └──────────────┘ │ │
|
|
372
|
-
│ │ │ │ │
|
|
373
|
-
│ │ ▼ │ │
|
|
374
|
-
│ │ ┌──────────────┐ │ │
|
|
375
|
-
│ │ │ Cancelled │ │ │
|
|
376
|
-
│ │ │ (Final State)│ │ │
|
|
377
|
-
│ │ └──────────────┘ │ │
|
|
378
|
-
│ │ │ │
|
|
379
|
-
│ └───────────────────────────────────────────────────────────────────────┘
|
|
380
|
-
│ │
|
|
381
|
-
│ Legend: │
|
|
382
|
-
│ ───► = Forward transition (with threshold requirement) │
|
|
383
|
-
│ ◄─── = Alternative path (cancellation) │
|
|
384
|
-
│ │
|
|
385
|
-
└─────────────────────────────────────────────────────────────────────────────────────┘
|
|
386
|
-
```
|
|
387
|
-
|
|
388
|
-
**Workflow Explanation:**
|
|
389
|
-
|
|
390
|
-
| Node | Name | Description | Threshold | Forwards |
|
|
391
|
-
|------|------|-------------|-----------|----------|
|
|
392
|
-
| 1 | Order Confirmation | Initial state after order creation | 0 | Confirm Order (Merchant) |
|
|
393
|
-
| 2 | Shipping | Merchant prepares and ships goods | 1 | Ship Goods (Merchant) |
|
|
394
|
-
| 3 | In Transit | Goods are being delivered | 1 | Confirm Delivery (Merchant) |
|
|
395
|
-
| 4 | Completed | Order successfully completed | 1 | Complete Order (Customer) |
|
|
396
|
-
| 5 | Cancelled | Order cancelled by customer (from Order Confirmation) | 0 | Cancel Order (Customer) |
|
|
397
|
-
|
|
398
|
-
**Permission Index Mapping:**
|
|
399
|
-
- `1000` - Merchant confirms order
|
|
400
|
-
- `1001` - Merchant ships goods
|
|
401
|
-
- `1002` - Merchant confirms delivery
|
|
402
|
-
|
|
403
|
-
**Order Permission:**
|
|
404
|
-
- Use `namedOperator: ""` (empty string) to allow order owner and agents to operate through Order object
|
|
405
|
-
- This is the recommended way to give order owners control over their orders
|
|
406
|
-
|
|
407
|
-
---
|
|
408
|
-
|
|
409
|
-
### Step 4: Create Contact Object for Customer Service
|
|
410
|
-
|
|
411
|
-
Create a Contact object to enable encrypted communication between customers and the store for after-sales support.
|
|
412
|
-
|
|
413
|
-
#### 4.1 Enable Merchant Messenger
|
|
414
|
-
|
|
415
|
-
**Prompt**: Enable messenger for the merchant account.
|
|
416
|
-
|
|
417
|
-
```json
|
|
418
|
-
{
|
|
419
|
-
"tool": "account_operation",
|
|
420
|
-
"data": {
|
|
421
|
-
"messenger": {
|
|
422
|
-
"enabled": true,
|
|
423
|
-
"name_or_account": "myshop_merchant"
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
```
|
|
428
|
-
|
|
429
|
-
> **Note**: Enabling messenger now registers the account on the messenger server **immediately and synchronously** — each account registers itself (its own identity, its own keys). The result includes `registered: true` on success, or `registered: false` with `registerError` if the server is unreachable (the background refresh retries automatically every 60s). If the operation result shows `registered: false`, retry the enable operation before proceeding — otherwise the counterpart's first message will fail with "Recipient not registered".
|
|
430
|
-
|
|
431
|
-
#### 4.2 Create After-Sales Contact Object
|
|
432
|
-
|
|
433
|
-
**Prompt**: Create a Contact object named "myshop_aftersales_contact_v2" with permission "myshop_permission_v2" for after-sales support.
|
|
434
|
-
|
|
435
|
-
```json
|
|
436
|
-
{
|
|
437
|
-
"tool": "onchain_operations",
|
|
438
|
-
"data": {
|
|
439
|
-
"operation_type": "contact",
|
|
440
|
-
"data": {
|
|
441
|
-
"object": {
|
|
442
|
-
"name": "myshop_aftersales_contact_v2",
|
|
443
|
-
"permission": "myshop_permission_v2",
|
|
444
|
-
"replaceExistName": true
|
|
445
|
-
},
|
|
446
|
-
"description": "MyShop after-sales support contact - we're here to help with orders, shipping, and returns",
|
|
447
|
-
"ims": {
|
|
448
|
-
"op": "add",
|
|
449
|
-
"im": [
|
|
450
|
-
{
|
|
451
|
-
"at": "myshop_merchant",
|
|
452
|
-
"description": "Primary after-sales support representative"
|
|
453
|
-
}
|
|
454
|
-
]
|
|
455
|
-
}
|
|
456
|
-
},
|
|
457
|
-
"env": {
|
|
458
|
-
"account": "myshop_merchant",
|
|
459
|
-
"network": "mainnet",
|
|
460
|
-
"confirmed": true
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
```
|
|
465
|
-
|
|
466
|
-
> **Note**: The `at` field accepts an **account name** (not messenger name). It will be resolved to the account's address. Alternatively, use the full address directly.
|
|
467
|
-
|
|
468
|
-
---
|
|
469
|
-
|
|
470
|
-
### Step 5: Create Service (Store) DRAFT
|
|
471
|
-
|
|
472
|
-
> **⚠️ Order matters — Service DRAFT must be created BEFORE the Guards.** The Guards in Step 6 reference the Service by name (`myshop_service_v2` as an Address table value). The SDK resolves the name to the on-chain address AT Guard creation time. If the Service does not exist yet, Guard creation aborts with:
|
|
473
|
-
> ```
|
|
474
|
-
> Error: invalid parameter:BCS serialization failed: ... failed to resolve string: myshop_service_v2. Address may not exist in local accounts or marks.
|
|
475
|
-
> ```
|
|
476
|
-
> Create the Service as an unpublished DRAFT here so the name resolves, then bind machine/allocators/sales and publish it in Step 7.
|
|
477
|
-
|
|
478
|
-
**Prompt**: Create an unpublished Service DRAFT named "myshop_service_v2" (no `publish` field — it stays a DRAFT so Guards can reference it and the mutable fields can still be configured).
|
|
479
|
-
|
|
480
|
-
```json
|
|
481
|
-
{
|
|
482
|
-
"tool": "onchain_operations",
|
|
483
|
-
"data": {
|
|
484
|
-
"operation_type": "service",
|
|
485
|
-
"data": {
|
|
486
|
-
"object": {
|
|
487
|
-
"name": "myshop_service_v2",
|
|
488
|
-
"type_parameter": "0x2::wow::WOW",
|
|
489
|
-
"permission": "myshop_permission_v2",
|
|
490
|
-
"tags": ["ecommerce", "toys", "store"],
|
|
491
|
-
"onChain": false,
|
|
492
|
-
"replaceExistName": true
|
|
493
|
-
},
|
|
494
|
-
"description": "MyShop - Top quality toys for children",
|
|
495
|
-
"location": "Online Store"
|
|
496
|
-
},
|
|
497
|
-
"env": {
|
|
498
|
-
"account": "myshop_merchant",
|
|
499
|
-
"network": "mainnet",
|
|
500
|
-
"confirmed": true
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
```
|
|
505
|
-
|
|
506
|
-
> **Note**: After publishing, `machine`, `order_allocators`, and `arbitrations` become **immutable**. Creating the draft first lets the Guards resolve the Service name while the Service is still configurable.
|
|
507
|
-
|
|
508
|
-
---
|
|
509
|
-
|
|
510
|
-
### Step 6: Create Guards for Fund Allocation
|
|
511
|
-
|
|
512
|
-
Before publishing the Service, create Guards that validate fund allocation conditions. These Guards ensure funds are only released when specific conditions are met. The Guards reference the Service DRAFT by name (`myshop_service_v2`), which now resolves to the draft's on-chain address (the address does NOT change when the draft is later published).
|
|
513
|
-
|
|
514
|
-
> **Note**: Guard table item `name` must be ≤ 64 characters (`MAX_NAME_LENGTH`) and must NOT start with `0x`. Descriptive names with spaces/parentheses (e.g. `order_address (Order object submitted at runtime)`) exceed the limit and abort with `invalid parameter:table.name`. Use short identifiers like `order_address`.
|
|
515
|
-
|
|
516
|
-
#### 6.1 Create Withdraw Guard (Merchant Withdrawal)
|
|
517
|
-
|
|
518
|
-
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.
|
|
519
|
-
|
|
520
|
-
**Prompt**: Create a Guard named "myshop_withdraw_guard_v2" that verifies the order is completed before allowing merchant withdrawal.
|
|
521
|
-
|
|
522
|
-
```json
|
|
523
|
-
{
|
|
524
|
-
"tool": "onchain_operations",
|
|
525
|
-
"data": {
|
|
526
|
-
"operation_type": "guard",
|
|
527
|
-
"data": {
|
|
528
|
-
"namedNew": {
|
|
529
|
-
"name": "myshop_withdraw_guard_v2",
|
|
530
|
-
"tags": ["order", "completed", "withdraw", "signer-bound"],
|
|
531
|
-
"onChain": false,
|
|
532
|
-
"replaceExistName": true
|
|
533
|
-
},
|
|
534
|
-
"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).",
|
|
535
|
-
"table": [
|
|
536
|
-
{
|
|
537
|
-
"identifier": 0,
|
|
538
|
-
"b_submission": true,
|
|
539
|
-
"value_type": "Address",
|
|
540
|
-
"name": "order_address"
|
|
541
|
-
},
|
|
542
|
-
{
|
|
543
|
-
"identifier": 1,
|
|
544
|
-
"b_submission": false,
|
|
545
|
-
"value_type": "String",
|
|
546
|
-
"value": "Completed",
|
|
547
|
-
"name": "expected_node"
|
|
548
|
-
},
|
|
549
|
-
{
|
|
550
|
-
"identifier": 2,
|
|
551
|
-
"b_submission": false,
|
|
552
|
-
"value_type": "Address",
|
|
553
|
-
"value": "myshop_merchant",
|
|
554
|
-
"name": "merchant_address"
|
|
555
|
-
},
|
|
556
|
-
{
|
|
557
|
-
"identifier": 3,
|
|
558
|
-
"b_submission": false,
|
|
559
|
-
"value_type": "Address",
|
|
560
|
-
"value": "myshop_service_v2",
|
|
561
|
-
"name": "service_address"
|
|
562
|
-
}
|
|
563
|
-
],
|
|
564
|
-
"root": {
|
|
565
|
-
"type": "logic_and",
|
|
566
|
-
"nodes": [
|
|
567
|
-
{
|
|
568
|
-
"type": "logic_equal",
|
|
569
|
-
"nodes": [
|
|
570
|
-
{
|
|
571
|
-
"type": "query",
|
|
572
|
-
"query": "progress.current",
|
|
573
|
-
"object": {
|
|
574
|
-
"identifier": 0,
|
|
575
|
-
"convert_witness": "OrderProgress"
|
|
576
|
-
},
|
|
577
|
-
"parameters": []
|
|
578
|
-
},
|
|
579
|
-
{
|
|
580
|
-
"type": "identifier",
|
|
581
|
-
"identifier": 1
|
|
582
|
-
}
|
|
583
|
-
]
|
|
584
|
-
},
|
|
585
|
-
{
|
|
586
|
-
"type": "logic_equal",
|
|
587
|
-
"nodes": [
|
|
588
|
-
{
|
|
589
|
-
"type": "context",
|
|
590
|
-
"context": "Signer"
|
|
591
|
-
},
|
|
592
|
-
{
|
|
593
|
-
"type": "identifier",
|
|
594
|
-
"identifier": 2
|
|
595
|
-
}
|
|
596
|
-
]
|
|
597
|
-
},
|
|
598
|
-
{
|
|
599
|
-
"type": "logic_equal",
|
|
600
|
-
"nodes": [
|
|
601
|
-
{
|
|
602
|
-
"type": "query",
|
|
603
|
-
"query": "order.service",
|
|
604
|
-
"object": {
|
|
605
|
-
"identifier": 0
|
|
606
|
-
},
|
|
607
|
-
"parameters": []
|
|
608
|
-
},
|
|
609
|
-
{
|
|
610
|
-
"type": "identifier",
|
|
611
|
-
"identifier": 3
|
|
612
|
-
}
|
|
613
|
-
]
|
|
614
|
-
}
|
|
615
|
-
]
|
|
616
|
-
}
|
|
617
|
-
},
|
|
618
|
-
"env": {
|
|
619
|
-
"account": "myshop_merchant",
|
|
620
|
-
"network": "mainnet",
|
|
621
|
-
"confirmed": true
|
|
622
|
-
}
|
|
623
|
-
}
|
|
624
|
-
}
|
|
625
|
-
```
|
|
626
|
-
|
|
627
|
-
**Guard Explanation (Three-fold Verification):**
|
|
628
|
-
- **Table Item 0**: Order address (submitted at runtime, typed as Order object)
|
|
629
|
-
- **Table Item 1**: Constant string "Completed" (the target node name)
|
|
630
|
-
- **Table Item 2**: Constant address `myshop_merchant` (authorized merchant)
|
|
631
|
-
- **Table Item 3**: Constant address `myshop_service_v2` (this service's on-chain address)
|
|
632
|
-
- **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"
|
|
633
|
-
- **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)
|
|
634
|
-
- **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)
|
|
635
|
-
- **root**: `logic_and` of all three conditions — all must pass for allocation to proceed
|
|
636
|
-
|
|
637
|
-
> **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.
|
|
638
|
-
>
|
|
639
|
-
> **Note**: The Guard `root` field directly specifies the GuardNode (e.g., `type: "logic_and"`), not wrapped in a `type: "node"` object.
|
|
640
|
-
|
|
641
|
-
#### 6.2 Create Refund Guard (Customer Refund)
|
|
642
|
-
|
|
643
|
-
Create a Guard for customer refunds when order is cancelled.
|
|
644
|
-
|
|
645
|
-
**Prompt**: Create a Guard named "myshop_refund_guard_v2" for customer refund validation.
|
|
646
|
-
|
|
647
|
-
```json
|
|
648
|
-
{
|
|
649
|
-
"tool": "onchain_operations",
|
|
650
|
-
"data": {
|
|
651
|
-
"operation_type": "guard",
|
|
652
|
-
"data": {
|
|
653
|
-
"namedNew": {
|
|
654
|
-
"name": "myshop_refund_guard_v2",
|
|
655
|
-
"tags": ["order", "cancelled", "refund", "signer-bound"],
|
|
656
|
-
"onChain": false,
|
|
657
|
-
"replaceExistName": true
|
|
658
|
-
},
|
|
659
|
-
"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).",
|
|
660
|
-
"table": [
|
|
661
|
-
{
|
|
662
|
-
"identifier": 0,
|
|
663
|
-
"b_submission": true,
|
|
664
|
-
"value_type": "Address",
|
|
665
|
-
"name": "order_address"
|
|
666
|
-
},
|
|
667
|
-
{
|
|
668
|
-
"identifier": 1,
|
|
669
|
-
"b_submission": false,
|
|
670
|
-
"value_type": "String",
|
|
671
|
-
"value": "Cancelled",
|
|
672
|
-
"name": "expected_node"
|
|
673
|
-
},
|
|
674
|
-
{
|
|
675
|
-
"identifier": 2,
|
|
676
|
-
"b_submission": false,
|
|
677
|
-
"value_type": "Address",
|
|
678
|
-
"value": "myshop_service_v2",
|
|
679
|
-
"name": "service_address"
|
|
680
|
-
}
|
|
681
|
-
],
|
|
682
|
-
"root": {
|
|
683
|
-
"type": "logic_and",
|
|
684
|
-
"nodes": [
|
|
685
|
-
{
|
|
686
|
-
"type": "logic_equal",
|
|
687
|
-
"nodes": [
|
|
688
|
-
{
|
|
689
|
-
"type": "query",
|
|
690
|
-
"query": "progress.current",
|
|
691
|
-
"object": {
|
|
692
|
-
"identifier": 0,
|
|
693
|
-
"convert_witness": "OrderProgress"
|
|
694
|
-
},
|
|
695
|
-
"parameters": []
|
|
696
|
-
},
|
|
697
|
-
{
|
|
698
|
-
"type": "identifier",
|
|
699
|
-
"identifier": 1
|
|
700
|
-
}
|
|
701
|
-
]
|
|
702
|
-
},
|
|
703
|
-
{
|
|
704
|
-
"type": "logic_equal",
|
|
705
|
-
"nodes": [
|
|
706
|
-
{
|
|
707
|
-
"type": "context",
|
|
708
|
-
"context": "Signer"
|
|
709
|
-
},
|
|
710
|
-
{
|
|
711
|
-
"type": "query",
|
|
712
|
-
"query": "order.owner",
|
|
713
|
-
"object": {
|
|
714
|
-
"identifier": 0
|
|
715
|
-
},
|
|
716
|
-
"parameters": []
|
|
717
|
-
}
|
|
718
|
-
]
|
|
719
|
-
},
|
|
720
|
-
{
|
|
721
|
-
"type": "logic_equal",
|
|
722
|
-
"nodes": [
|
|
723
|
-
{
|
|
724
|
-
"type": "query",
|
|
725
|
-
"query": "order.service",
|
|
726
|
-
"object": {
|
|
727
|
-
"identifier": 0
|
|
728
|
-
},
|
|
729
|
-
"parameters": []
|
|
730
|
-
},
|
|
731
|
-
{
|
|
732
|
-
"type": "identifier",
|
|
733
|
-
"identifier": 2
|
|
734
|
-
}
|
|
735
|
-
]
|
|
736
|
-
}
|
|
737
|
-
]
|
|
738
|
-
}
|
|
739
|
-
},
|
|
740
|
-
"env": {
|
|
741
|
-
"account": "myshop_merchant",
|
|
742
|
-
"network": "mainnet",
|
|
743
|
-
"confirmed": true
|
|
744
|
-
}
|
|
745
|
-
}
|
|
746
|
-
}
|
|
747
|
-
```
|
|
748
|
-
|
|
749
|
-
**Guard Explanation (Three-fold Verification):**
|
|
750
|
-
- **Table Item 0**: Order address (submitted at runtime, typed as Order object)
|
|
751
|
-
- **Table Item 1**: Constant string "Cancelled" (the target node name)
|
|
752
|
-
- **Table Item 2**: Constant address `myshop_service_v2` (this service's on-chain address)
|
|
753
|
-
- **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"
|
|
754
|
-
- **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.
|
|
755
|
-
- **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)
|
|
756
|
-
- **root**: `logic_and` of all three conditions — all must pass for refund allocation to proceed
|
|
757
|
-
|
|
758
|
-
> **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.
|
|
759
|
-
>
|
|
760
|
-
> **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.
|
|
761
|
-
|
|
762
|
-
---
|
|
763
|
-
|
|
764
|
-
### Step 7: Publish Service (Store)
|
|
765
|
-
|
|
766
|
-
Bind all previously created components (machine, Guards, products, after-sales contact) to the Service DRAFT created in Step 5, then publish it. The Service address stays the same as the DRAFT, so the Guards' `service_address` table values remain valid.
|
|
767
|
-
|
|
768
|
-
> **Important**: Provide a complete configuration including machine, order_allocators with Guards, and products. The Service is published in a single transaction. After publish, `machine`, `order_allocators`, and `arbitrations` become immutable.
|
|
769
|
-
|
|
770
|
-
#### 7.1 Understanding Order Allocators
|
|
771
|
-
|
|
772
|
-
The `order_allocators` configuration defines how order payments are distributed:
|
|
773
|
-
|
|
774
|
-
| Component | Description |
|
|
775
|
-
|-----------|-------------|
|
|
776
|
-
| **Guard** | Validates allocation conditions (e.g., order must be completed) |
|
|
777
|
-
| **Sharing** | Defines who receives funds and how much |
|
|
778
|
-
| **Mode** | "Rate" (percentage), "Amount" (fixed), or "Surplus" |
|
|
779
|
-
| **Threshold** | Minimum amount to trigger allocation |
|
|
780
|
-
|
|
781
|
-
**Recipient Types:**
|
|
782
|
-
- `{ "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.
|
|
783
|
-
- `{ "Entity": { "name_or_address": "..." } }` - Specific address or account name (safest — funds go to a fixed address regardless of caller)
|
|
784
|
-
- `{ "GuardIdentifier": 0 }` - Address from Guard table (e.g., the submitted Order object's address)
|
|
785
|
-
|
|
786
|
-
> **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:
|
|
787
|
-
> - **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.
|
|
788
|
-
> - **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.
|
|
789
|
-
>
|
|
790
|
-
> **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.
|
|
791
|
-
|
|
792
|
-
> **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.
|
|
793
|
-
|
|
794
|
-
#### 7.2 Publish Service (bind machine + allocators + sales + um)
|
|
795
|
-
|
|
796
|
-
**Prompt**: Publish the Service DRAFT "myshop_service_v2" (created in Step 5) by binding machine "myshop_machine_v2", order allocation using the Guards, after-sales contact, and toy products. Note `object` is now a STRING reference to the existing draft, and `publish: true` is set.
|
|
797
|
-
|
|
798
|
-
```json
|
|
799
|
-
{
|
|
800
|
-
"tool": "onchain_operations",
|
|
801
|
-
"data": {
|
|
802
|
-
"operation_type": "service",
|
|
803
|
-
"data": {
|
|
804
|
-
"object": "myshop_service_v2",
|
|
805
|
-
"machine": "myshop_machine_v2",
|
|
806
|
-
"order_allocators": {
|
|
807
|
-
"description": "Order revenue allocation - merchant withdraw after completion",
|
|
808
|
-
"threshold": 0,
|
|
809
|
-
"allocators": [
|
|
810
|
-
{
|
|
811
|
-
"guard": "myshop_withdraw_guard_v2",
|
|
812
|
-
"sharing": [
|
|
813
|
-
{
|
|
814
|
-
"who": { "Signer": "signer" },
|
|
815
|
-
"sharing": 10000,
|
|
816
|
-
"mode": "Rate"
|
|
817
|
-
}
|
|
818
|
-
]
|
|
819
|
-
},
|
|
820
|
-
{
|
|
821
|
-
"guard": "myshop_refund_guard_v2",
|
|
822
|
-
"sharing": [
|
|
823
|
-
{
|
|
824
|
-
"who": { "GuardIdentifier": 0 },
|
|
825
|
-
"sharing": 10000,
|
|
826
|
-
"mode": "Rate"
|
|
827
|
-
}
|
|
828
|
-
]
|
|
829
|
-
}
|
|
830
|
-
]
|
|
831
|
-
},
|
|
832
|
-
"sales": {
|
|
833
|
-
"op": "add",
|
|
834
|
-
"sales": [
|
|
835
|
-
{
|
|
836
|
-
"name": "Play Purse Set 35PCS",
|
|
837
|
-
"price": 50000000,
|
|
838
|
-
"stock": 100,
|
|
839
|
-
"suspension": false,
|
|
840
|
-
"wip": "https://raw.githubusercontent.com/wowok-ai/docs/main/wip-examples/three_body.wip",
|
|
841
|
-
"wip_hash": ""
|
|
842
|
-
},
|
|
843
|
-
{
|
|
844
|
-
"name": "Little Girls Purse with Accessories",
|
|
845
|
-
"price": 50000000,
|
|
846
|
-
"stock": 50,
|
|
847
|
-
"suspension": false,
|
|
848
|
-
"wip": "https://raw.githubusercontent.com/wowok-ai/docs/main/wip-examples/three_body.wip",
|
|
849
|
-
"wip_hash": ""
|
|
850
|
-
},
|
|
851
|
-
{
|
|
852
|
-
"name": "Tree House Building Set",
|
|
853
|
-
"price": 30000000,
|
|
854
|
-
"stock": 75,
|
|
855
|
-
"suspension": false,
|
|
856
|
-
"wip": "https://raw.githubusercontent.com/wowok-ai/docs/main/wip-examples/three_body.wip",
|
|
857
|
-
"wip_hash": ""
|
|
858
|
-
}
|
|
859
|
-
]
|
|
860
|
-
},
|
|
861
|
-
"um": "myshop_aftersales_contact_v2",
|
|
862
|
-
"publish": true
|
|
863
|
-
},
|
|
864
|
-
"env": {
|
|
865
|
-
"account": "myshop_merchant",
|
|
866
|
-
"network": "mainnet",
|
|
867
|
-
"confirmed": true
|
|
868
|
-
}
|
|
869
|
-
}
|
|
870
|
-
}
|
|
871
|
-
```
|
|
872
|
-
|
|
873
|
-
**Important Notes:**
|
|
874
|
-
- After publishing, `machine`, `order_allocators`, and `arbitrations` become **immutable**
|
|
875
|
-
- Ensure your Guards and allocation logic are correct before publishing
|
|
876
|
-
- The `sharing` value of `10000` represents 100% (rate mode uses 0-10000 scale)
|
|
877
|
-
|
|
878
|
-
---
|
|
879
|
-
|
|
880
|
-
### Step 8: Update Product Pricing (Optional)
|
|
881
|
-
|
|
882
|
-
To offer promotional pricing, update product prices using the `sales` operation with `op: "set"`:
|
|
883
|
-
|
|
884
|
-
**Prompt**: Update the price of "Play Purse Set 35PCS" to 0.04 WOW for a promotion.
|
|
885
|
-
|
|
886
|
-
```json
|
|
887
|
-
{
|
|
888
|
-
"tool": "onchain_operations",
|
|
889
|
-
"data": {
|
|
890
|
-
"operation_type": "service",
|
|
891
|
-
"data": {
|
|
892
|
-
"object": "myshop_service_v2",
|
|
893
|
-
"sales": {
|
|
894
|
-
"op": "set",
|
|
895
|
-
"sales": [
|
|
896
|
-
{
|
|
897
|
-
"name": "Play Purse Set 35PCS",
|
|
898
|
-
"price": 40000000,
|
|
899
|
-
"stock": 100,
|
|
900
|
-
"suspension": false,
|
|
901
|
-
"wip": "https://raw.githubusercontent.com/wowok-ai/docs/main/wip-examples/three_body.wip",
|
|
902
|
-
"wip_hash": ""
|
|
903
|
-
}
|
|
904
|
-
]
|
|
905
|
-
}
|
|
906
|
-
},
|
|
907
|
-
"env": {
|
|
908
|
-
"account": "myshop_merchant",
|
|
909
|
-
"network": "mainnet",
|
|
910
|
-
"confirmed": true
|
|
911
|
-
}
|
|
912
|
-
}
|
|
913
|
-
}
|
|
914
|
-
```
|
|
915
|
-
|
|
916
|
-
---
|
|
917
|
-
|
|
918
|
-
## Part 2: Customer Order Flow
|
|
919
|
-
|
|
920
|
-
This section guides customers through browsing products, placing orders, and tracking progress.
|
|
921
|
-
|
|
922
|
-
### Prerequisites
|
|
923
|
-
|
|
924
|
-
Create a customer account:
|
|
925
|
-
|
|
926
|
-
**Prompt**: Create a customer account named "myshop_customer".
|
|
927
|
-
|
|
928
|
-
```json
|
|
929
|
-
{
|
|
930
|
-
"tool": "account_operation",
|
|
931
|
-
"data": {
|
|
932
|
-
"gen": {
|
|
933
|
-
"name": "myshop_customer",
|
|
934
|
-
"replaceExistName": true
|
|
935
|
-
}
|
|
936
|
-
}
|
|
937
|
-
}
|
|
938
|
-
```
|
|
939
|
-
|
|
940
|
-
**Get mainnet tokens:**
|
|
941
|
-
|
|
942
|
-
**Prompt**: Transfer 1 WOW to account "myshop_customer" from a funded account for gas fees.
|
|
943
|
-
|
|
944
|
-
```json
|
|
945
|
-
{
|
|
946
|
-
"tool": "account_operation",
|
|
947
|
-
"data": {
|
|
948
|
-
"transfer": {
|
|
949
|
-
"name_or_address_to": "myshop_customer",
|
|
950
|
-
"amount": 1000000000,
|
|
951
|
-
"network": "mainnet"
|
|
952
|
-
}
|
|
953
|
-
}
|
|
954
|
-
}
|
|
955
|
-
```
|
|
956
|
-
|
|
957
|
-
> **Note**: Ensure sufficient WOW balance for order payments plus gas fees. If needed, transfer additional tokens from a funded account.
|
|
958
|
-
|
|
959
|
-
---
|
|
960
|
-
|
|
961
|
-
### Step 1: Query Service Products
|
|
962
|
-
|
|
963
|
-
Customers can query the Service to see available products.
|
|
964
|
-
|
|
965
|
-
**Prompt**: Query the Service "myshop_service_v2" to view available products and their details.
|
|
966
|
-
|
|
967
|
-
```json
|
|
968
|
-
{
|
|
969
|
-
"tool": "query_toolkit",
|
|
970
|
-
"data": {
|
|
971
|
-
"query_type": "onchain_objects",
|
|
972
|
-
"objects": ["myshop_service_v2"],
|
|
973
|
-
"no_cache": true
|
|
974
|
-
}
|
|
975
|
-
}
|
|
976
|
-
```
|
|
977
|
-
|
|
978
|
-
> **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.
|
|
979
|
-
|
|
980
|
-
---
|
|
981
|
-
|
|
982
|
-
### Step 2: Create Order (Customer Purchase)
|
|
983
|
-
|
|
984
|
-
Customer creates an order by purchasing products from the Service.
|
|
985
|
-
|
|
986
|
-
**Prompt**: Create an order for customer "myshop_customer" to purchase "Play Purse Set 35PCS" from "myshop_service_v2" with payment of 0.05 WOW.
|
|
987
|
-
|
|
988
|
-
```json
|
|
989
|
-
{
|
|
990
|
-
"tool": "onchain_operations",
|
|
991
|
-
"data": {
|
|
992
|
-
"operation_type": "service",
|
|
993
|
-
"data": {
|
|
994
|
-
"object": "myshop_service_v2",
|
|
995
|
-
"order_new": {
|
|
996
|
-
"buy": {
|
|
997
|
-
"items": [
|
|
998
|
-
{
|
|
999
|
-
"name": "Play Purse Set 35PCS",
|
|
1000
|
-
"stock": 1,
|
|
1001
|
-
"wip_hash": "<wip_hash captured from Step 1 query>"
|
|
1002
|
-
}
|
|
1003
|
-
],
|
|
1004
|
-
"total_pay": {
|
|
1005
|
-
"balance": 50000000
|
|
1006
|
-
}
|
|
1007
|
-
},
|
|
1008
|
-
"namedNewOrder": {
|
|
1009
|
-
"name": "myshop_test_order",
|
|
1010
|
-
"replaceExistName": true
|
|
1011
|
-
},
|
|
1012
|
-
"namedNewProgress": {
|
|
1013
|
-
"name": "myshop_test_progress",
|
|
1014
|
-
"replaceExistName": true
|
|
1015
|
-
},
|
|
1016
|
-
"namedNewAllocation": {
|
|
1017
|
-
"name": "myshop_test_allocation",
|
|
1018
|
-
"replaceExistName": true
|
|
1019
|
-
}
|
|
1020
|
-
}
|
|
1021
|
-
},
|
|
1022
|
-
"env": {
|
|
1023
|
-
"account": "myshop_customer",
|
|
1024
|
-
"network": "mainnet",
|
|
1025
|
-
"confirmed": true
|
|
1026
|
-
}
|
|
1027
|
-
}
|
|
1028
|
-
}
|
|
1029
|
-
```
|
|
1030
|
-
|
|
1031
|
-
---
|
|
1032
|
-
|
|
1033
|
-
### Step 2.1: Send Shipping Address via Messenger (Privacy Protection)
|
|
1034
|
-
|
|
1035
|
-
After creating the order, the customer sends their shipping address and contact information to the merchant's after-sales support team. This is done securely through the Messenger system to protect privacy - the information is never stored on-chain.
|
|
1036
|
-
|
|
1037
|
-
```
|
|
1038
|
-
┌─────────────────────────────────────────────────────────────────────────────────────┐
|
|
1039
|
-
│ Private Information Exchange via Messenger │
|
|
1040
|
-
├─────────────────────────────────────────────────────────────────────────────────────┤
|
|
1041
|
-
│ │
|
|
1042
|
-
│ ┌──────────────────┐ End-to-End Encrypted ┌──────────────────┐ │
|
|
1043
|
-
│ │ │◄──────────────────────────────────────►│ │ │
|
|
1044
|
-
│ │ myshop_customer │ Messenger Channel │ myshop_merchant │ │
|
|
1045
|
-
│ │ (Customer) │ (Never on-chain) │ (After-Sales │ │
|
|
1046
|
-
│ │ │ │ Support) │ │
|
|
1047
|
-
│ └────────┬─────────┘ └────────┬─────────┘ │
|
|
1048
|
-
│ │ │ │
|
|
1049
|
-
│ │ 1. Send shipping address │ │
|
|
1050
|
-
│ │ - Full name │ │
|
|
1051
|
-
│ │ - Phone number │ │
|
|
1052
|
-
│ │ - Shipping address │ │
|
|
1053
|
-
│ │ - Order reference ID │ │
|
|
1054
|
-
│ │──────────────────────────────────────────────────────────►│ │
|
|
1055
|
-
│ │ │ │
|
|
1056
|
-
│ │ 2. Receive confirmation │ │
|
|
1057
|
-
│ │ - Address verified │ │
|
|
1058
|
-
│ │ - Delivery ETA │ │
|
|
1059
|
-
│ │ - Tracking number (when available) │ │
|
|
1060
|
-
│ │◄──────────────────────────────────────────────────────────│ │
|
|
1061
|
-
│ │ │ │
|
|
1062
|
-
│ ┌────────▼─────────┐ ┌────────▼─────────┐ │
|
|
1063
|
-
│ │ Customer Info │ │ Support System │ │
|
|
1064
|
-
│ │ (Local Storage) │ │ (Local Storage) │ │
|
|
1065
|
-
│ └──────────────────┘ └──────────────────┘ │
|
|
1066
|
-
│ │
|
|
1067
|
-
│ Privacy Guarantees: │
|
|
1068
|
-
│ - End-to-end encryption - Only customer and merchant can read │
|
|
1069
|
-
│ - No on-chain storage - Message content never touches blockchain │
|
|
1070
|
-
│ - Verifiable identity - Contact object confirms who you're talking to │
|
|
1071
|
-
│ │
|
|
1072
|
-
└─────────────────────────────────────────────────────────────────────────────────────┘
|
|
1073
|
-
```
|
|
1074
|
-
|
|
1075
|
-
#### 2.1.1 Customer Enables Messenger
|
|
1076
|
-
|
|
1077
|
-
**Prompt**: Enable messenger for customer account "myshop_customer" to send private messages.
|
|
1078
|
-
|
|
1079
|
-
```json
|
|
1080
|
-
{
|
|
1081
|
-
"tool": "account_operation",
|
|
1082
|
-
"data": {
|
|
1083
|
-
"messenger": {
|
|
1084
|
-
"enabled": true,
|
|
1085
|
-
"name_or_account": "myshop_customer"
|
|
1086
|
-
}
|
|
1087
|
-
}
|
|
1088
|
-
}
|
|
1089
|
-
```
|
|
1090
|
-
|
|
1091
|
-
> **Note**: Same as merchant enable (Step 4.1): registration on the messenger server happens synchronously with the enable. Each party must enable messenger **in its own environment with its own account** — one side can never register the other.
|
|
1092
|
-
|
|
1093
|
-
#### 2.1.2 Customer Sends Shipping Information
|
|
1094
|
-
|
|
1095
|
-
**Prompt**: Customer "myshop_customer" sends shipping address and contact information to merchant "myshop_merchant" via encrypted messenger.
|
|
1096
|
-
|
|
1097
|
-
```json
|
|
1098
|
-
{
|
|
1099
|
-
"tool": "messenger_operation",
|
|
1100
|
-
"data": {
|
|
1101
|
-
"operation": "send_message",
|
|
1102
|
-
"from": "myshop_customer",
|
|
1103
|
-
"to": "myshop_merchant",
|
|
1104
|
-
"content": "Order Shipping Information:\n\nOrder ID: 0xa6db...3d5\nProduct: Play Purse Set 35PCS\n\nRecipient: Zhang San\nPhone: 138-0000-0000\nAddress: Building 123, Unit 456, Room 789\n Chaoyang District, Beijing\n China, 100000\n\nPlease confirm receipt of this information."
|
|
1105
|
-
}
|
|
1106
|
-
}
|
|
1107
|
-
```
|
|
1108
|
-
|
|
1109
|
-
> **Note**: Replace the Order ID with your actual order object address from Step 2.
|
|
1110
|
-
>
|
|
1111
|
-
> **Spam Protection**: The Messenger server allows only ONE message to a stranger (non-friend) before the recipient must reply. If the customer already sent an initial message to the merchant, the merchant must reply first before the customer can send additional messages. Once both parties have exchanged messages, they become "friends" and can send unlimited messages. If you encounter "Spam protection denied: You can only send one stranger message, wait for recipient to reply", have the merchant send a reply first.
|
|
1112
|
-
|
|
1113
|
-
#### 2.1.3 Merchant Confirms Receipt
|
|
1114
|
-
|
|
1115
|
-
**Prompt**: Merchant "myshop_merchant" views the message and sends confirmation to customer.
|
|
1116
|
-
|
|
1117
|
-
```json
|
|
1118
|
-
{
|
|
1119
|
-
"tool": "messenger_operation",
|
|
1120
|
-
"data": {
|
|
1121
|
-
"operation": "send_message",
|
|
1122
|
-
"from": "myshop_merchant",
|
|
1123
|
-
"to": "myshop_customer",
|
|
1124
|
-
"content": "Dear Customer,\n\nWe have received your shipping information:\n- Order ID: 0xa6db...3d5 confirmed\n- Shipping address verified\n- Contact phone: 138-0000-0000\n\nYour order will be processed within 24 hours. We'll send you the tracking number once shipped.\n\nThank you for shopping with MyShop!"
|
|
1125
|
-
}
|
|
1126
|
-
}
|
|
1127
|
-
```
|
|
1128
|
-
|
|
1129
|
-
#### 2.1.4 View Conversation History
|
|
1130
|
-
|
|
1131
|
-
**Prompt**: View the conversation between customer and merchant to confirm both messages were delivered.
|
|
1132
|
-
|
|
1133
|
-
```json
|
|
1134
|
-
{
|
|
1135
|
-
"tool": "messenger_operation",
|
|
1136
|
-
"data": {
|
|
1137
|
-
"operation": "watch_messages",
|
|
1138
|
-
"filter": {
|
|
1139
|
-
"peerAddress": "myshop_merchant",
|
|
1140
|
-
"account": "myshop_customer"
|
|
1141
|
-
}
|
|
1142
|
-
}
|
|
1143
|
-
}
|
|
1144
|
-
```
|
|
1145
|
-
|
|
1146
|
-
---
|
|
1147
|
-
|
|
1148
|
-
### Step 3: Query Order Status
|
|
1149
|
-
|
|
1150
|
-
Customer can query the order status and progress.
|
|
1151
|
-
|
|
1152
|
-
**Prompt**: Query the order "myshop_test_order" to check its current status and progress.
|
|
1153
|
-
|
|
1154
|
-
```json
|
|
1155
|
-
{
|
|
1156
|
-
"tool": "query_toolkit",
|
|
1157
|
-
"data": {
|
|
1158
|
-
"query_type": "onchain_objects",
|
|
1159
|
-
"objects": ["myshop_test_order"],
|
|
1160
|
-
"no_cache": true
|
|
1161
|
-
}
|
|
1162
|
-
}
|
|
1163
|
-
```
|
|
1164
|
-
|
|
1165
|
-
---
|
|
1166
|
-
|
|
1167
|
-
### Step 4: Query Progress Status
|
|
1168
|
-
|
|
1169
|
-
Check the current workflow node of the order.
|
|
1170
|
-
|
|
1171
|
-
**Prompt**: Query the Progress "myshop_test_progress" to see the current workflow node.
|
|
1172
|
-
|
|
1173
|
-
```json
|
|
1174
|
-
{
|
|
1175
|
-
"tool": "query_toolkit",
|
|
1176
|
-
"data": {
|
|
1177
|
-
"query_type": "onchain_objects",
|
|
1178
|
-
"objects": ["myshop_test_progress"],
|
|
1179
|
-
"no_cache": true
|
|
1180
|
-
}
|
|
1181
|
-
}
|
|
1182
|
-
```
|
|
1183
|
-
|
|
1184
|
-
---
|
|
1185
|
-
|
|
1186
|
-
### Step 5: Merchant Confirms Order
|
|
1187
|
-
|
|
1188
|
-
Merchant advances the order from initial state to "Order Confirmation" node.
|
|
1189
|
-
|
|
1190
|
-
> **Note**: Use `operation_type: "progress"` with `operate` to advance the workflow. The order is created with an empty initial node "", and the first step is to transition to "Order Confirmation" using "Confirm Order" forward.
|
|
1191
|
-
|
|
1192
|
-
**Prompt**: Advance the order "myshop_test_order" progress from initial state to "Order Confirmation" using the "Confirm Order" forward.
|
|
1193
|
-
|
|
1194
|
-
```json
|
|
1195
|
-
{
|
|
1196
|
-
"tool": "onchain_operations",
|
|
1197
|
-
"data": {
|
|
1198
|
-
"operation_type": "progress",
|
|
1199
|
-
"data": {
|
|
1200
|
-
"object": "myshop_test_progress",
|
|
1201
|
-
"operate": {
|
|
1202
|
-
"operation": {
|
|
1203
|
-
"next_node_name": "Order Confirmation",
|
|
1204
|
-
"forward": "Confirm Order"
|
|
1205
|
-
},
|
|
1206
|
-
"op": "next",
|
|
1207
|
-
"message": "Order confirmed by merchant"
|
|
1208
|
-
}
|
|
1209
|
-
},
|
|
1210
|
-
"env": {
|
|
1211
|
-
"account": "myshop_merchant",
|
|
1212
|
-
"network": "mainnet",
|
|
1213
|
-
"confirmed": true
|
|
1214
|
-
}
|
|
1215
|
-
}
|
|
1216
|
-
}
|
|
1217
|
-
```
|
|
1218
|
-
|
|
1219
|
-
---
|
|
1220
|
-
|
|
1221
|
-
### Step 6: Merchant Ships Order
|
|
1222
|
-
|
|
1223
|
-
Merchant ships the order and advances from "Order Confirmation" to "Shipping".
|
|
1224
|
-
|
|
1225
|
-
**Prompt**: Advance the order progress from "Order Confirmation" to "Shipping" using the "Ship Goods" forward.
|
|
1226
|
-
|
|
1227
|
-
```json
|
|
1228
|
-
{
|
|
1229
|
-
"tool": "onchain_operations",
|
|
1230
|
-
"data": {
|
|
1231
|
-
"operation_type": "progress",
|
|
1232
|
-
"data": {
|
|
1233
|
-
"object": "myshop_test_progress",
|
|
1234
|
-
"operate": {
|
|
1235
|
-
"operation": {
|
|
1236
|
-
"next_node_name": "Shipping",
|
|
1237
|
-
"forward": "Ship Goods"
|
|
1238
|
-
},
|
|
1239
|
-
"op": "next",
|
|
1240
|
-
"message": "Goods shipped via express delivery"
|
|
1241
|
-
}
|
|
1242
|
-
},
|
|
1243
|
-
"env": {
|
|
1244
|
-
"account": "myshop_merchant",
|
|
1245
|
-
"network": "mainnet",
|
|
1246
|
-
"confirmed": true
|
|
1247
|
-
}
|
|
1248
|
-
}
|
|
1249
|
-
}
|
|
1250
|
-
```
|
|
1251
|
-
|
|
1252
|
-
---
|
|
1253
|
-
|
|
1254
|
-
### Step 7: Confirm Delivery
|
|
1255
|
-
|
|
1256
|
-
Merchant or delivery service confirms the order has been delivered.
|
|
1257
|
-
|
|
1258
|
-
**Prompt**: Advance the order progress from "Shipping" to "In Transit" using the "Confirm Delivery" forward.
|
|
1259
|
-
|
|
1260
|
-
```json
|
|
1261
|
-
{
|
|
1262
|
-
"tool": "onchain_operations",
|
|
1263
|
-
"data": {
|
|
1264
|
-
"operation_type": "progress",
|
|
1265
|
-
"data": {
|
|
1266
|
-
"object": "myshop_test_progress",
|
|
1267
|
-
"operate": {
|
|
1268
|
-
"operation": {
|
|
1269
|
-
"next_node_name": "In Transit",
|
|
1270
|
-
"forward": "Confirm Delivery"
|
|
1271
|
-
},
|
|
1272
|
-
"op": "next",
|
|
1273
|
-
"message": "Goods delivered successfully"
|
|
1274
|
-
}
|
|
1275
|
-
},
|
|
1276
|
-
"env": {
|
|
1277
|
-
"account": "myshop_merchant",
|
|
1278
|
-
"network": "mainnet",
|
|
1279
|
-
"confirmed": true
|
|
1280
|
-
}
|
|
1281
|
-
}
|
|
1282
|
-
}
|
|
1283
|
-
```
|
|
1284
|
-
|
|
1285
|
-
---
|
|
1286
|
-
|
|
1287
|
-
### Step 8: Customer Completes Order
|
|
1288
|
-
|
|
1289
|
-
Customer confirms receipt and completes the order.
|
|
1290
|
-
|
|
1291
|
-
**Prompt**: Customer "myshop_customer" completes the order by advancing from "In Transit" to "Completed" node using "Complete Order" forward.
|
|
1292
|
-
|
|
1293
|
-
```json
|
|
1294
|
-
{
|
|
1295
|
-
"tool": "onchain_operations",
|
|
1296
|
-
"data": {
|
|
1297
|
-
"operation_type": "progress",
|
|
1298
|
-
"data": {
|
|
1299
|
-
"object": "myshop_test_progress",
|
|
1300
|
-
"operate": {
|
|
1301
|
-
"operation": {
|
|
1302
|
-
"next_node_name": "Completed",
|
|
1303
|
-
"forward": "Complete Order"
|
|
1304
|
-
},
|
|
1305
|
-
"op": "next",
|
|
1306
|
-
"message": "Order received and completed"
|
|
1307
|
-
}
|
|
1308
|
-
},
|
|
1309
|
-
"env": {
|
|
1310
|
-
"account": "myshop_customer",
|
|
1311
|
-
"network": "mainnet",
|
|
1312
|
-
"confirmed": true
|
|
1313
|
-
}
|
|
1314
|
-
}
|
|
1315
|
-
}
|
|
1316
|
-
```
|
|
1317
|
-
|
|
1318
|
-
---
|
|
1319
|
-
|
|
1320
|
-
### Step 9: Merchant Withdraws Funds
|
|
1321
|
-
|
|
1322
|
-
After order completion, the merchant needs to:
|
|
1323
|
-
1. Activate the Allocation by verifying the Guard (order completion status)
|
|
1324
|
-
2. Withdraw funds from the Service
|
|
1325
|
-
|
|
1326
|
-
#### 7.1 Activate Allocation (Guard Verification)
|
|
1327
|
-
|
|
1328
|
-
First, activate the Allocation by submitting the Guard verification with the Order ID.
|
|
1329
|
-
|
|
1330
|
-
> **Note**: The `alloc_by_guard` and `submission` fields require the actual Guard object address (0x...), not the local name. You can obtain the Guard address from the local mark list or by querying the Guard name.
|
|
1331
|
-
|
|
1332
|
-
**Prompt**: Activate allocation "myshop_test_allocation" by verifying the withdraw guard with order "myshop_test_order".
|
|
1333
|
-
|
|
1334
|
-
```json
|
|
1335
|
-
{
|
|
1336
|
-
"tool": "onchain_operations",
|
|
1337
|
-
"data": {
|
|
1338
|
-
"operation_type": "allocation",
|
|
1339
|
-
"data": {
|
|
1340
|
-
"object": "myshop_test_allocation",
|
|
1341
|
-
"alloc_by_guard": "0x5af9...1074"
|
|
1342
|
-
},
|
|
1343
|
-
"submission": {
|
|
1344
|
-
"type": "submission",
|
|
1345
|
-
"guard": [
|
|
1346
|
-
{
|
|
1347
|
-
"object": "0x5af9...1074",
|
|
1348
|
-
"impack": true
|
|
1349
|
-
}
|
|
1350
|
-
],
|
|
1351
|
-
"submission": [
|
|
1352
|
-
{
|
|
1353
|
-
"guard": "0x5af9...1074",
|
|
1354
|
-
"submission": [
|
|
1355
|
-
{
|
|
1356
|
-
"identifier": 0,
|
|
1357
|
-
"b_submission": true,
|
|
1358
|
-
"value_type": "Address",
|
|
1359
|
-
"value": "0xa6db...3d5",
|
|
1360
|
-
"name": "order_address"
|
|
1361
|
-
}
|
|
1362
|
-
]
|
|
1363
|
-
}
|
|
1364
|
-
]
|
|
1365
|
-
},
|
|
1366
|
-
"env": {
|
|
1367
|
-
"account": "myshop_merchant",
|
|
1368
|
-
"network": "mainnet",
|
|
1369
|
-
"confirmed": true,
|
|
1370
|
-
"no_cache": true
|
|
1371
|
-
}
|
|
1372
|
-
}
|
|
1373
|
-
}
|
|
1374
|
-
```
|
|
1375
|
-
|
|
1376
|
-
> **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.
|
|
1377
|
-
|
|
1378
|
-
#### 7.2 Withdraw Funds (Unwrap the Merchant's CoinWrapper)
|
|
1379
|
-
|
|
1380
|
-
The allocator's recipient is `{"Signer": "signer"}`, so the Allocation pays out via a **CoinWrapper transferred directly to the merchant account** (an owned object of the merchant EOA) — NOT to the Service object. Therefore `owner_receive` on the Service cannot collect this payout. Instead, find the CoinWrapper received by the merchant account and unwrap it into spendable coins.
|
|
1381
|
-
|
|
1382
|
-
**Step a**: Query the merchant account's received objects to find the payout CoinWrapper.
|
|
1383
|
-
|
|
1384
|
-
**Prompt**: Query objects recently received by account "myshop_merchant" to find the allocation payout CoinWrapper.
|
|
1385
|
-
|
|
1386
|
-
```json
|
|
1387
|
-
{
|
|
1388
|
-
"tool": "query_toolkit",
|
|
1389
|
-
"data": {
|
|
1390
|
-
"query_type": "onchain_received",
|
|
1391
|
-
"name_or_address": "myshop_merchant",
|
|
1392
|
-
"type": "CoinWrapper",
|
|
1393
|
-
"network": "mainnet"
|
|
1394
|
-
}
|
|
1395
|
-
}
|
|
1396
|
-
```
|
|
1397
|
-
|
|
1398
|
-
**Step b**: Unwrap the CoinWrapper into WOW coins in the merchant's wallet.
|
|
1399
|
-
|
|
1400
|
-
**Prompt**: Merchant "myshop_merchant" unwraps the received CoinWrapper "0x1234...abcd" into WOW coins.
|
|
1401
|
-
|
|
1402
|
-
```json
|
|
1403
|
-
{
|
|
1404
|
-
"tool": "onchain_operations",
|
|
1405
|
-
"data": {
|
|
1406
|
-
"operation_type": "payment",
|
|
1407
|
-
"data": {
|
|
1408
|
-
"object": "0x1234...abcd",
|
|
1409
|
-
"receive": true,
|
|
1410
|
-
"type_parameter": "0x2::wow::WOW"
|
|
1411
|
-
},
|
|
1412
|
-
"env": {
|
|
1413
|
-
"account": "myshop_merchant",
|
|
1414
|
-
"network": "mainnet",
|
|
1415
|
-
"confirmed": true
|
|
1416
|
-
}
|
|
1417
|
-
}
|
|
1418
|
-
}
|
|
1419
|
-
```
|
|
1420
|
-
|
|
1421
|
-
> **Note**: Replace `0x1234...abcd` with the actual CoinWrapper object ID found in Step a (use the full 64-character address). The caller must be the CoinWrapper's owner — the allocation's `Signer` recipient (the merchant).
|
|
1422
|
-
|
|
1423
|
-
---
|
|
1424
|
-
|
|
1425
|
-
## Alternative Flow: Order Cancellation
|
|
1426
|
-
|
|
1427
|
-
### Customer Cancels Order
|
|
1428
|
-
|
|
1429
|
-
Customer can cancel the order after the merchant confirms it. The "Cancel Order" forward transitions from "Order Confirmation" to "Cancelled". This requires the merchant to first confirm the order (advancing from the initial state "" to "Order Confirmation").
|
|
1430
|
-
|
|
1431
|
-
**Step 1**: Merchant confirms the order (advances from "" to "Order Confirmation"):
|
|
1432
|
-
|
|
1433
|
-
```json
|
|
1434
|
-
{
|
|
1435
|
-
"tool": "onchain_operations",
|
|
1436
|
-
"data": {
|
|
1437
|
-
"operation_type": "progress",
|
|
1438
|
-
"data": {
|
|
1439
|
-
"object": "myshop_test_progress",
|
|
1440
|
-
"operate": {
|
|
1441
|
-
"operation": {
|
|
1442
|
-
"next_node_name": "Order Confirmation",
|
|
1443
|
-
"forward": "Confirm Order"
|
|
1444
|
-
},
|
|
1445
|
-
"op": "next",
|
|
1446
|
-
"message": "Order confirmed by merchant"
|
|
1447
|
-
}
|
|
1448
|
-
},
|
|
1449
|
-
"env": {
|
|
1450
|
-
"account": "myshop_merchant",
|
|
1451
|
-
"network": "mainnet",
|
|
1452
|
-
"confirmed": true
|
|
1453
|
-
}
|
|
1454
|
-
}
|
|
1455
|
-
}
|
|
1456
|
-
```
|
|
1457
|
-
|
|
1458
|
-
**Step 2**: Customer cancels the order (advances from "Order Confirmation" to "Cancelled"):
|
|
1459
|
-
|
|
1460
|
-
**Prompt**: Customer "myshop_customer" cancels the order after merchant confirmation.
|
|
1461
|
-
|
|
1462
|
-
```json
|
|
1463
|
-
{
|
|
1464
|
-
"tool": "onchain_operations",
|
|
1465
|
-
"data": {
|
|
1466
|
-
"operation_type": "progress",
|
|
1467
|
-
"data": {
|
|
1468
|
-
"object": "myshop_test_progress",
|
|
1469
|
-
"operate": {
|
|
1470
|
-
"operation": {
|
|
1471
|
-
"next_node_name": "Cancelled",
|
|
1472
|
-
"forward": "Cancel Order"
|
|
1473
|
-
},
|
|
1474
|
-
"op": "next",
|
|
1475
|
-
"message": "Order cancelled by customer"
|
|
1476
|
-
}
|
|
1477
|
-
},
|
|
1478
|
-
"env": {
|
|
1479
|
-
"account": "myshop_customer",
|
|
1480
|
-
"network": "mainnet",
|
|
1481
|
-
"confirmed": true
|
|
1482
|
-
}
|
|
1483
|
-
}
|
|
1484
|
-
}
|
|
1485
|
-
```
|
|
1486
|
-
|
|
1487
|
-
> **Note**: Cancellation can only be done from the "Order Confirmation" state (after the merchant confirms the order, but before shipping). Once the order is shipped, cancellation is no longer possible through this forward.
|
|
1488
|
-
|
|
1489
|
-
### Customer Refund After Cancellation
|
|
1490
|
-
|
|
1491
|
-
After the order is cancelled, the customer can activate the refund allocation using the refund guard:
|
|
1492
|
-
|
|
1493
|
-
```json
|
|
1494
|
-
{
|
|
1495
|
-
"tool": "onchain_operations",
|
|
1496
|
-
"data": {
|
|
1497
|
-
"operation_type": "allocation",
|
|
1498
|
-
"data": {
|
|
1499
|
-
"object": "myshop_test_allocation",
|
|
1500
|
-
"alloc_by_guard": "0x5792...5d2c"
|
|
1501
|
-
},
|
|
1502
|
-
"submission": {
|
|
1503
|
-
"type": "submission",
|
|
1504
|
-
"guard": [
|
|
1505
|
-
{
|
|
1506
|
-
"object": "0x5792...5d2c",
|
|
1507
|
-
"impack": true
|
|
1508
|
-
}
|
|
1509
|
-
],
|
|
1510
|
-
"submission": [
|
|
1511
|
-
{
|
|
1512
|
-
"guard": "0x5792...5d2c",
|
|
1513
|
-
"submission": [
|
|
1514
|
-
{
|
|
1515
|
-
"identifier": 0,
|
|
1516
|
-
"b_submission": true,
|
|
1517
|
-
"value_type": "Address",
|
|
1518
|
-
"value": "0xa6db...3d5",
|
|
1519
|
-
"name": "order_address"
|
|
1520
|
-
}
|
|
1521
|
-
]
|
|
1522
|
-
}
|
|
1523
|
-
]
|
|
1524
|
-
},
|
|
1525
|
-
"env": {
|
|
1526
|
-
"account": "myshop_customer",
|
|
1527
|
-
"network": "mainnet",
|
|
1528
|
-
"confirmed": true,
|
|
1529
|
-
"no_cache": true
|
|
1530
|
-
}
|
|
1531
|
-
}
|
|
1532
|
-
}
|
|
1533
|
-
```
|
|
1534
|
-
|
|
1535
|
-
> **Note**: Replace the Guard address `0x5792...5d2c` and Order address `0xa6db...3d5` with your actual object addresses.
|
|
1536
|
-
|
|
1537
|
-
The refund Allocation escrows the refunded funds to the Order address. Finally, the customer claims them from the Order:
|
|
1538
|
-
|
|
1539
|
-
**Prompt**: Customer "myshop_customer" claims the refunded funds from order "myshop_test_order".
|
|
1540
|
-
|
|
1541
|
-
```json
|
|
1542
|
-
{
|
|
1543
|
-
"tool": "onchain_operations",
|
|
1544
|
-
"data": {
|
|
1545
|
-
"operation_type": "order",
|
|
1546
|
-
"data": {
|
|
1547
|
-
"object": "myshop_test_order",
|
|
1548
|
-
"receive": "recently"
|
|
1549
|
-
},
|
|
1550
|
-
"env": {
|
|
1551
|
-
"account": "myshop_customer",
|
|
1552
|
-
"network": "mainnet",
|
|
1553
|
-
"confirmed": true
|
|
1554
|
-
}
|
|
1555
|
-
}
|
|
1556
|
-
}
|
|
1557
|
-
```
|
|
1558
|
-
|
|
1559
|
-
> **Note**: `receive: "recently"` unwraps all objects recently received by the Order (including the refund CoinWrapper) and transfers them to the order owner (the customer).
|
|
1560
|
-
|
|
1561
|
-
---
|
|
1562
|
-
|
|
1563
|
-
## Alternative Flow: Dispute and Arbitration
|
|
1564
|
-
|
|
1565
|
-
This flow handles order disputes through a formal arbitration process. The arbitration state machine has these statuses:
|
|
1566
|
-
- 0: Principal_confirming (after reset)
|
|
1567
|
-
- 1: Arbitrator_confirming (after dispute submitted)
|
|
1568
|
-
- 2: Voting (after materials confirmed)
|
|
1569
|
-
- 3: Arbitrated (after arbitration result provided)
|
|
1570
|
-
- 4: Objectionable (if principal objects)
|
|
1571
|
-
- 5: Finished (after compensation claimed)
|
|
1572
|
-
- 6: Withdrawn (30 days after arbitrated)
|
|
1573
|
-
|
|
1574
|
-
### Step 1: Service Compensation Fund Setup
|
|
1575
|
-
|
|
1576
|
-
The Service must have a compensation fund balance ≥ the arbitration indemnity amount. The merchant pre-funds this before any disputes.
|
|
1577
|
-
|
|
1578
|
-
**Prompt**: Merchant adds 0.05 WOW to the Service compensation fund.
|
|
1579
|
-
|
|
1580
|
-
```json
|
|
1581
|
-
{
|
|
1582
|
-
"tool": "onchain_operations",
|
|
1583
|
-
"data": {
|
|
1584
|
-
"operation_type": "service",
|
|
1585
|
-
"data": {
|
|
1586
|
-
"object": "myshop_service_v2",
|
|
1587
|
-
"compensation_fund_add": {"balance": 50000000}
|
|
1588
|
-
},
|
|
1589
|
-
"env": {
|
|
1590
|
-
"account": "myshop_merchant",
|
|
1591
|
-
"network": "mainnet",
|
|
1592
|
-
"confirmed": true
|
|
1593
|
-
}
|
|
1594
|
-
}
|
|
1595
|
-
}
|
|
1596
|
-
```
|
|
1597
|
-
|
|
1598
|
-
### Step 2: Create Independent Arbitration Permission
|
|
1599
|
-
|
|
1600
|
-
The on-chain contract REQUIRES the Arbitration's Permission to be DIFFERENT from the Service's Permission — binding an Arbitration that shares the Service's Permission aborts the transaction with E_ARBITRATION_PERMISSION_CONFLICT (error 33). Create a dedicated Permission object for arbitration first.
|
|
1601
|
-
|
|
1602
|
-
**Prompt**: Create a Permission object named "myshop_arbitration_permission" for dispute arbitration.
|
|
1603
|
-
|
|
1604
|
-
```json
|
|
1605
|
-
{
|
|
1606
|
-
"tool": "onchain_operations",
|
|
1607
|
-
"data": {
|
|
1608
|
-
"operation_type": "permission",
|
|
1609
|
-
"data": {
|
|
1610
|
-
"object": {
|
|
1611
|
-
"name": "myshop_arbitration_permission",
|
|
1612
|
-
"tags": ["ecommerce", "dispute", "arbitration"],
|
|
1613
|
-
"onChain": false,
|
|
1614
|
-
"replaceExistName": true
|
|
1615
|
-
},
|
|
1616
|
-
"description": "Permission management for MyShop dispute arbitration"
|
|
1617
|
-
},
|
|
1618
|
-
"env": {
|
|
1619
|
-
"account": "myshop_merchant",
|
|
1620
|
-
"network": "mainnet",
|
|
1621
|
-
"confirmed": true
|
|
1622
|
-
}
|
|
1623
|
-
}
|
|
1624
|
-
}
|
|
1625
|
-
```
|
|
1626
|
-
|
|
1627
|
-
### Step 3: Create Arbitration Object
|
|
1628
|
-
|
|
1629
|
-
Create an Arbitration object for handling order disputes. It MUST use the independent arbitration Permission created in Step 2 (NOT the Service's "myshop_permission_v2").
|
|
1630
|
-
|
|
1631
|
-
**Prompt**: Create an Arbitration object named "myshop_arbitration_v2" with permission "myshop_arbitration_permission" for dispute resolution.
|
|
1632
|
-
|
|
1633
|
-
```json
|
|
1634
|
-
{
|
|
1635
|
-
"tool": "onchain_operations",
|
|
1636
|
-
"data": {
|
|
1637
|
-
"operation_type": "arbitration",
|
|
1638
|
-
"data": {
|
|
1639
|
-
"object": {
|
|
1640
|
-
"name": "myshop_arbitration_v2",
|
|
1641
|
-
"type_parameter": "0x2::wow::WOW",
|
|
1642
|
-
"permission": "myshop_arbitration_permission",
|
|
1643
|
-
"tags": ["ecommerce", "dispute", "toys"],
|
|
1644
|
-
"onChain": false
|
|
1645
|
-
},
|
|
1646
|
-
"description": "Arbitration system for MyShop toy store disputes",
|
|
1647
|
-
"location": "Online arbitration system",
|
|
1648
|
-
"fee": 5000000
|
|
1649
|
-
},
|
|
1650
|
-
"env": {
|
|
1651
|
-
"account": "myshop_merchant",
|
|
1652
|
-
"network": "mainnet",
|
|
1653
|
-
"confirmed": true
|
|
1654
|
-
}
|
|
1655
|
-
}
|
|
1656
|
-
}
|
|
1657
|
-
```
|
|
1658
|
-
|
|
1659
|
-
> **Note**: New Arbitration objects are created with `bPaused: true` by default. You must unpause it in the next step before submitting disputes.
|
|
1660
|
-
|
|
1661
|
-
### Step 4: Unpause the Arbitration Object
|
|
1662
|
-
|
|
1663
|
-
The merchant unpauses the Arbitration object to enable dispute submissions.
|
|
1664
|
-
|
|
1665
|
-
**Prompt**: Merchant unpauses the Arbitration object "myshop_arbitration_v2".
|
|
1666
|
-
|
|
1667
|
-
```json
|
|
1668
|
-
{
|
|
1669
|
-
"tool": "onchain_operations",
|
|
1670
|
-
"data": {
|
|
1671
|
-
"operation_type": "arbitration",
|
|
1672
|
-
"data": {
|
|
1673
|
-
"object": "myshop_arbitration_v2",
|
|
1674
|
-
"pause": false
|
|
1675
|
-
},
|
|
1676
|
-
"env": {
|
|
1677
|
-
"account": "myshop_merchant",
|
|
1678
|
-
"network": "mainnet",
|
|
1679
|
-
"confirmed": true
|
|
1680
|
-
}
|
|
1681
|
-
}
|
|
1682
|
-
}
|
|
1683
|
-
```
|
|
1684
|
-
|
|
1685
|
-
### Step 5: Bind Arbitration to the Service
|
|
1686
|
-
|
|
1687
|
-
Bind the Arbitration object to the Service so that orders on this Service can be disputed through it. Adding arbitrations is an L3 operation — it remains allowed even after the Service is published (only remove/clear requires pause + lock duration).
|
|
1688
|
-
|
|
1689
|
-
**Prompt**: Merchant binds arbitration "myshop_arbitration_v2" to service "myshop_service_v2".
|
|
1690
|
-
|
|
1691
|
-
```json
|
|
1692
|
-
{
|
|
1693
|
-
"tool": "onchain_operations",
|
|
1694
|
-
"data": {
|
|
1695
|
-
"operation_type": "service",
|
|
1696
|
-
"data": {
|
|
1697
|
-
"object": "myshop_service_v2",
|
|
1698
|
-
"arbitrations": {
|
|
1699
|
-
"op": "add",
|
|
1700
|
-
"objects": ["myshop_arbitration_v2"]
|
|
1701
|
-
}
|
|
1702
|
-
},
|
|
1703
|
-
"env": {
|
|
1704
|
-
"account": "myshop_merchant",
|
|
1705
|
-
"network": "mainnet",
|
|
1706
|
-
"confirmed": true
|
|
1707
|
-
}
|
|
1708
|
-
}
|
|
1709
|
-
}
|
|
1710
|
-
```
|
|
1711
|
-
|
|
1712
|
-
### Step 6: Create a Dispute Order
|
|
1713
|
-
|
|
1714
|
-
Create a new order for testing the arbitration flow (if you don't have one already).
|
|
1715
|
-
|
|
1716
|
-
**Prompt**: Customer "myshop_customer" creates a new order for "Tree House Building Set" for arbitration testing.
|
|
1717
|
-
|
|
1718
|
-
```json
|
|
1719
|
-
{
|
|
1720
|
-
"tool": "onchain_operations",
|
|
1721
|
-
"data": {
|
|
1722
|
-
"operation_type": "service",
|
|
1723
|
-
"data": {
|
|
1724
|
-
"object": "myshop_service_v2",
|
|
1725
|
-
"order_new": {
|
|
1726
|
-
"buy": {
|
|
1727
|
-
"items": [
|
|
1728
|
-
{
|
|
1729
|
-
"name": "Tree House Building Set",
|
|
1730
|
-
"stock": 1,
|
|
1731
|
-
"wip_hash": "<wip_hash captured from Step 1 query>"
|
|
1732
|
-
}
|
|
1733
|
-
],
|
|
1734
|
-
"total_pay": {"balance": 30000000}
|
|
1735
|
-
},
|
|
1736
|
-
"namedNewOrder": {"name": "myshop_arb_order", "replaceExistName": true},
|
|
1737
|
-
"namedNewProgress": {"name": "myshop_arb_progress", "replaceExistName": true},
|
|
1738
|
-
"namedNewAllocation": {"name": "myshop_arb_allocation", "replaceExistName": true}
|
|
1739
|
-
}
|
|
1740
|
-
},
|
|
1741
|
-
"env": {
|
|
1742
|
-
"account": "myshop_customer",
|
|
1743
|
-
"network": "mainnet",
|
|
1744
|
-
"confirmed": true
|
|
1745
|
-
}
|
|
1746
|
-
}
|
|
1747
|
-
}
|
|
1748
|
-
```
|
|
1749
|
-
|
|
1750
|
-
> **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`.
|
|
1751
|
-
|
|
1752
|
-
### Step 7: Customer Submits Dispute
|
|
1753
|
-
|
|
1754
|
-
The customer submits a dispute against the order, creating an Arb object.
|
|
1755
|
-
|
|
1756
|
-
**Prompt**: Customer "myshop_customer" submits a dispute for order "myshop_arb_order" using arbitration "myshop_arbitration_v2".
|
|
1757
|
-
|
|
1758
|
-
```json
|
|
1759
|
-
{
|
|
1760
|
-
"tool": "onchain_operations",
|
|
1761
|
-
"data": {
|
|
1762
|
-
"operation_type": "arbitration",
|
|
1763
|
-
"data": {
|
|
1764
|
-
"object": "myshop_arbitration_v2",
|
|
1765
|
-
"dispute": {
|
|
1766
|
-
"order": "myshop_arb_order",
|
|
1767
|
-
"description": "Product quality issue - the tree house set arrived damaged",
|
|
1768
|
-
"proposition": ["Full refund to customer", "Partial refund 50%", "Replace with new product"],
|
|
1769
|
-
"fee": {"balance": 5000000},
|
|
1770
|
-
"namedArb": {"name": "myshop_arb_case", "replaceExistName": true}
|
|
1771
|
-
}
|
|
1772
|
-
},
|
|
1773
|
-
"env": {
|
|
1774
|
-
"account": "myshop_customer",
|
|
1775
|
-
"network": "mainnet",
|
|
1776
|
-
"confirmed": true
|
|
1777
|
-
}
|
|
1778
|
-
}
|
|
1779
|
-
}
|
|
1780
|
-
```
|
|
1781
|
-
|
|
1782
|
-
> **Note**: The dispute fee (5000000 = 0.005 WOW) must be ≥ the Arbitration object's fee setting. The Arb object is created with status=1 (Arbitrator_confirming).
|
|
1783
|
-
|
|
1784
|
-
### Step 8: Merchant Confirms Materials
|
|
1785
|
-
|
|
1786
|
-
The merchant confirms the dispute materials are valid and sets the voting deadline.
|
|
1787
|
-
|
|
1788
|
-
**Prompt**: Merchant "myshop_merchant" confirms the dispute materials for Arb "myshop_arb_case" with voting_deadline 0 (voting impossible — the arbitrator can provide the verdict immediately).
|
|
1789
|
-
|
|
1790
|
-
```json
|
|
1791
|
-
{
|
|
1792
|
-
"tool": "onchain_operations",
|
|
1793
|
-
"data": {
|
|
1794
|
-
"operation_type": "arbitration",
|
|
1795
|
-
"data": {
|
|
1796
|
-
"object": "myshop_arbitration_v2",
|
|
1797
|
-
"confirm": {
|
|
1798
|
-
"arb": "myshop_arb_case",
|
|
1799
|
-
"voting_deadline": 0
|
|
1800
|
-
}
|
|
1801
|
-
},
|
|
1802
|
-
"env": {
|
|
1803
|
-
"account": "myshop_merchant",
|
|
1804
|
-
"network": "mainnet",
|
|
1805
|
-
"confirmed": true
|
|
1806
|
-
}
|
|
1807
|
-
}
|
|
1808
|
-
}
|
|
1809
|
-
```
|
|
1810
|
-
|
|
1811
|
-
> **Note**: `voting_deadline` accepts a Unix timestamp in **milliseconds**, `0`, or `null`. `0` (used here) sets the deadline in the past — voting is impossible, so the arbitrator can provide the verdict immediately. `null` means open-ended voting with no deadline — the verdict can also be provided at any time, but voting remains possible until then. To set a specific deadline, use a future Unix timestamp in milliseconds (e.g., `Date.now() + 86400000` for 24 hours).
|
|
1812
|
-
|
|
1813
|
-
### Step 9: Merchant Provides Arbitration Result
|
|
1814
|
-
|
|
1815
|
-
The merchant provides the final arbitration result with feedback and indemnity amount.
|
|
1816
|
-
|
|
1817
|
-
**Prompt**: Merchant "myshop_merchant" provides arbitration result for Arb "myshop_arb_case" with 0.03 WOW indemnity.
|
|
1818
|
-
|
|
1819
|
-
```json
|
|
1820
|
-
{
|
|
1821
|
-
"tool": "onchain_operations",
|
|
1822
|
-
"data": {
|
|
1823
|
-
"operation_type": "arbitration",
|
|
1824
|
-
"data": {
|
|
1825
|
-
"object": "myshop_arbitration_v2",
|
|
1826
|
-
"arbitration": {
|
|
1827
|
-
"arb": "myshop_arb_case",
|
|
1828
|
-
"feedback": "After investigation, the product quality issue is confirmed. Full refund to customer and return shipping cost covered by merchant.",
|
|
1829
|
-
"indemnity": 30000000
|
|
1830
|
-
}
|
|
1831
|
-
},
|
|
1832
|
-
"env": {
|
|
1833
|
-
"account": "myshop_merchant",
|
|
1834
|
-
"network": "mainnet",
|
|
1835
|
-
"confirmed": true
|
|
1836
|
-
}
|
|
1837
|
-
}
|
|
1838
|
-
}
|
|
1839
|
-
```
|
|
1840
|
-
|
|
1841
|
-
> **Note**: The Arb status changes to 3 (Arbitrated). The indemnity amount must be ≤ the Service's compensation_fund balance.
|
|
1842
|
-
|
|
1843
|
-
### Step 10: Customer Claims Compensation
|
|
1844
|
-
|
|
1845
|
-
The customer claims the compensation from the Service's compensation fund.
|
|
1846
|
-
|
|
1847
|
-
**Prompt**: Customer "myshop_customer" claims compensation for order "myshop_arb_order" from Arb "myshop_arb_case".
|
|
1848
|
-
|
|
1849
|
-
```json
|
|
1850
|
-
{
|
|
1851
|
-
"tool": "onchain_operations",
|
|
1852
|
-
"data": {
|
|
1853
|
-
"operation_type": "order",
|
|
1854
|
-
"data": {
|
|
1855
|
-
"object": "myshop_arb_order",
|
|
1856
|
-
"arb_claim_compensation": {
|
|
1857
|
-
"arb": "myshop_arb_case"
|
|
1858
|
-
}
|
|
1859
|
-
},
|
|
1860
|
-
"env": {
|
|
1861
|
-
"account": "myshop_customer",
|
|
1862
|
-
"network": "mainnet",
|
|
1863
|
-
"confirmed": true
|
|
1864
|
-
}
|
|
1865
|
-
}
|
|
1866
|
-
}
|
|
1867
|
-
```
|
|
1868
|
-
|
|
1869
|
-
> **Note**: The customer receives the indemnity amount (0.03 WOW) from the Service's compensation fund. The Arb status changes to 5 (Finished). The Order's `claimed_by` field is updated with the Arb address.
|
|
1870
|
-
|
|
1871
|
-
### Step 11: Query Arbitration Status
|
|
1872
|
-
|
|
1873
|
-
Check the final status of the arbitration.
|
|
1874
|
-
|
|
1875
|
-
**Prompt**: Query the Arb "myshop_arb_case" to verify the arbitration is finished.
|
|
1876
|
-
|
|
1877
|
-
```json
|
|
1878
|
-
{
|
|
1879
|
-
"tool": "query_toolkit",
|
|
1880
|
-
"data": {
|
|
1881
|
-
"query_type": "onchain_objects",
|
|
1882
|
-
"objects": ["myshop_arb_case"],
|
|
1883
|
-
"no_cache": true,
|
|
1884
|
-
"network": "mainnet"
|
|
1885
|
-
}
|
|
1886
|
-
}
|
|
1887
|
-
```
|
|
1888
|
-
|
|
1889
|
-
The Arb should have `status: 5` (Finished) with `compensation_time` set.
|
|
1890
|
-
|
|
1891
|
-
---
|
|
1892
|
-
|
|
1893
|
-
## Summary
|
|
1894
|
-
|
|
1895
|
-
This MyShop e-commerce example demonstrates:
|
|
1896
|
-
|
|
1897
|
-
1. **Merchant Setup**:
|
|
1898
|
-
- Permission management for access control
|
|
1899
|
-
- Machine workflow for order processing with visual flow diagram
|
|
1900
|
-
- Contact objects for after-sales support
|
|
1901
|
-
- Guard creation for fund allocation validation
|
|
1902
|
-
- Service creation with products and pricing
|
|
1903
|
-
|
|
1904
|
-
2. **Customer Flow**:
|
|
1905
|
-
- Product browsing and selection
|
|
1906
|
-
- Order creation with payment
|
|
1907
|
-
- Private information exchange via Messenger (shipping address, phone number)
|
|
1908
|
-
- Progress tracking through workflow nodes
|
|
1909
|
-
- Order completion and payment release
|
|
1910
|
-
|
|
1911
|
-
3. **Privacy & Security Features**:
|
|
1912
|
-
- End-to-end encrypted messaging for sensitive information
|
|
1913
|
-
- Contact-based identity verification
|
|
1914
|
-
- No private data stored on-chain
|
|
1915
|
-
|
|
1916
|
-
4. **Alternative Flows**:
|
|
1917
|
-
- Order cancellation after confirmation (from "Order Confirmation" state)
|
|
1918
|
-
- Customer refund after cancellation (via Guard-protected Allocation)
|
|
1919
|
-
- Dispute submission and arbitration process (7-step state machine)
|
|
1920
|
-
- Compensation claim from Service compensation fund
|
|
1921
|
-
|
|
1922
|
-
All operations use the WoWok SDK patterns with JSON-based sub-tool calls, making it easy for AI agents to interact with the blockchain e-commerce system.
|
|
1923
|
-
|
|
1924
|
-
---
|
|
1925
|
-
|
|
1926
|
-
## Workflow Advancement Notes
|
|
1927
|
-
|
|
1928
|
-
When advancing order workflows, use `operation_type: "progress"` with the `operate` field for all workflow transitions:
|
|
1929
|
-
|
|
1930
|
-
```json
|
|
1931
|
-
{
|
|
1932
|
-
"tool": "onchain_operations",
|
|
1933
|
-
"data": {
|
|
1934
|
-
"operation_type": "progress",
|
|
1935
|
-
"data": {
|
|
1936
|
-
"object": "myshop_test_progress",
|
|
1937
|
-
"operate": {
|
|
1938
|
-
"operation": {
|
|
1939
|
-
"next_node_name": "Target Node Name",
|
|
1940
|
-
"forward": "Forward Name"
|
|
1941
|
-
},
|
|
1942
|
-
"op": "next",
|
|
1943
|
-
"message": "Operation description"
|
|
1944
|
-
}
|
|
1945
|
-
},
|
|
1946
|
-
"env": {
|
|
1947
|
-
"account": "operator_account",
|
|
1948
|
-
"network": "mainnet",
|
|
1949
|
-
"confirmed": true
|
|
1950
|
-
}
|
|
1951
|
-
}
|
|
1952
|
-
}
|
|
1953
|
-
```
|
|
1954
|
-
|
|
1955
|
-
The Progress object ID can be obtained from:
|
|
1956
|
-
- Order object's `progress` field
|
|
1957
|
-
- Named during order creation with `namedNewProgress`
|
|
1958
|
-
|
|
1959
|
-
The operator account depends on the forward definition:
|
|
1960
|
-
- Forwards with `permissionIndex` require the merchant account (with appropriate permission)
|
|
1961
|
-
- Forwards with `namedOperator: ""` allow the order owner (customer) to operate
|
|
1962
|
-
|
|
1963
|
-
---
|
|
1964
|
-
|
|
1965
|
-
## Object Reference Summary
|
|
1966
|
-
|
|
1967
|
-
| Object Type | Name | Purpose |
|
|
1968
|
-
|-------------|------|---------|
|
|
1969
|
-
| Account | myshop_merchant | Store owner account |
|
|
1970
|
-
| Account | myshop_customer | Customer account |
|
|
1971
|
-
| Permission | myshop_permission_v2 | Access control management |
|
|
1972
|
-
| Permission | myshop_arbitration_permission | Arbitration access control (must differ from Service permission) |
|
|
1973
|
-
| Guard | myshop_withdraw_guard_v2 | Merchant withdrawal validation (order completed) |
|
|
1974
|
-
| Guard | myshop_refund_guard_v2 | Customer refund validation (order cancelled) |
|
|
1975
|
-
| Machine | myshop_machine_v2 | Order processing workflow |
|
|
1976
|
-
| Contact | myshop_aftersales_contact_v2 | After-sales support contact |
|
|
1977
|
-
| Service | myshop_service_v2 | Online store with products |
|
|
1978
|
-
| Arbitration | myshop_arbitration_v2 | Dispute resolution (optional) |
|
|
1979
|
-
| Order | myshop_test_order | Customer purchase order (dynamic) |
|
|
1980
|
-
| Progress | myshop_test_progress | Order workflow progress (dynamic) |
|
|
1981
|
-
| Allocation | myshop_test_allocation | Order fund allocation (dynamic) |
|
|
1982
|
-
|
|
1983
|
-
---
|
|
1984
|
-
|
|
1985
|
-
## Next Steps
|
|
1986
|
-
|
|
1987
|
-
- Extend the workflow with more nodes (e.g., "Return Goods", "Refund Processing")
|
|
1988
|
-
- Add more complex Guards for conditional transitions
|
|
1989
|
-
- Implement WIP files for product verification
|
|
1990
|
-
- Set up Repository for order data storage
|
|
1991
|
-
- Add WTS generation for messenger conversation records
|
|
1992
|
-
- Implement file sharing via Messenger (shipping labels, invoices)
|
|
1993
|
-
- Add blacklist/guardlist management for spam prevention
|
|
1994
|
-
- Create automated notification system for order status updates
|
|
1995
|
-
|
|
1996
|
-
---
|
|
1997
|
-
|
|
1998
|
-
## Notes
|
|
1999
|
-
|
|
2000
|
-
- All addresses shown in examples are truncated for readability (format: 0xabcd...efgh)
|
|
2001
|
-
- Use the full 64-character address in actual operations
|
|
2002
|
-
- Deploy and run on mainnet
|
|
2003
|
-
- Ensure sufficient WOW tokens for transaction fees
|