-
Notifications
You must be signed in to change notification settings - Fork 0
/
JAAA.Oscript
302 lines (285 loc) · 16.6 KB
/
JAAA.Oscript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
{
/*
JAAA, Joint Account Agent
Check in explorer: https://testnetexplorer.obyte.org/#5wm9JYxDcE1zzZiH+w83jPFJq205fVhwIBSqrlSOS3s=
Agent address: 7WJL4TYFGIYO7U5G35ETIH6B7VMM72Q2
*/
init: "{
// FOREVER CONSTANTE
$AA_NAME = "JAAA";
// light version of HOLLAA to be able to add more user before reaching the 2000 operations limit.
$LIST_HOLDER_AA = "MNS7LOJJ4SUM2UPOOVRK5VAOHVQ4DGUO";
$INSTRUCTIONS = "Every operation need 'account_name= <account name>'except if you received a 'pay_id', then just use it, 'pay_id = <received pay_id> optionaly with 'cancel = true' to deny the payment. To initiate a payment, define 'pay_to' and 'amount'. To create a new account, add users with 'add_user = <address>' multiple times then 'activate_account = true' and choose 'hierarchical/flat = true'";
$TRICK_TO_ORDER_FIELD_PROPOSITION_IN_WALLET = trigger.data.pay_id||trigger.data.account_name||trigger.data.pay_to||trigger.data.amount||trigger.data.communication||trigger.data.fill||trigger.data.add_user||trigger.data.nickname||trigger.data.activate_account||trigger.data.hierarchical||trigger.data.flat;
//inputs
$inputs = "For the moment I received: "||json_stringify(trigger.data)||json_stringify(trigger.output[[asset=base]]);
}",
messages: {
cases: [
{ if: "{ !!trigger.data.cancel}", // cancel a payment providing the pay_id
init: "{
$account_name = trigger.data.account_name otherwise bounce ($INSTRUCTIONS);
if (!var[$LIST_HOLDER_AA][$account_name||"_users_"||trigger.address])
bounce ("This address is not listed as actor of this account");
$payment_id = trigger.data.token otherwise bounce ("'Token' needed !");
$message = "Payment cancelled by "||trigger.address||", "||var[$payment_id];
}",
messages: [ // send cancel message to initiator of the payment
{
app: 'data', payload: { message: `{ $message }` },
},
{
app: 'payment', payload: { asset: "base", outputs: [
{ "address": "{ var[$payment_id||"_initiator"] }", "amount": 6 }
] }
},
{
app: "state", state: "{
var[$payment_id] = false;
var[$payment_id||"_initiator"] = false;
var[$payment_id||"_validations_needed"] = false;
var[$payment_id||"_communication"] = false;
var[$payment_id||"_destination"] = false;
var[$payment_id||"_amount"] = false;
var[$payment_id||"_account"] = false;
var[$payment_id||"_needs_"||trigger.address] = false;
var[$payment_id||"_destination"] = false;
var[$payment_id||"_amount"] = false;
var[$account_name||"_balance"] += trigger.output[[asset=base]].amount-6;
response['message'] = $message;
}"
}
]
},
{ if: "{ !!trigger.data.pay_id }", // pay_id received as validation from one of the party
init: "{
$payment_id = trigger.data.pay_id;
$account_name = var[$payment_id||"_account"];
// bouncings
if (!var[$payment_id])
bounce ("Token "||$payment_id||" do not exist!");
if (!var[$LIST_HOLDER_AA][$account_name||"_users_"||trigger.address])
bounce ("This address is not listed as actor of this account");
if (!var[$payment_id||"_needs_"||trigger.address])
bounce ("Your validation is not needed!");
$number_of_validations_needed = var[$payment_id||"_validations_needed"] - 1;
$is_validated = ($number_of_validations_needed == 0);
$payment_amount = var[$payment_id||"_amount"];
$forwarding_needed = !$is_validated and var[$account_name] == "hierarchical";
}",
messages: [
{
if: `{ $is_validated }`, // is everyone have validate then we can send the message and pay
app: 'data', payload: {
message: `{ var[$payment_id||"_communication"] }`
},
},
{
if: `{ $is_validated }`, // is everyone have validate then we can send the message and pay
app: 'payment', payload: { asset: "base", outputs: [
{ "address": "{ var[$payment_id||"_destination"] }", "amount": "{ $payment_amount }" }
] }
},
{
if: `{ $forwarding_needed }`, // in hierarchical mode, not all party are warn at the same time
app: 'data', payload: {
list_name: `{ $account_name||"_users" }`,
token: `{ $payment_id }`,
get_previous: `{ trigger.address }`
},
},
{
if: `{ $forwarding_needed }`,
app: 'payment', payload: { asset: "base", outputs: [
{ "address": "{ $LIST_HOLDER_AA }", "amount": "{ 1000 }" }
] }
},
{
app: "state", state: "{
var[$payment_id||"_needs_"||trigger.address] = false;
var[$payment_id||"_validations_needed"] = $number_of_validations_needed;
var[$account_name||"_balance"] += trigger.output[[asset=base]].amount-1000;
if ($is_validated) // clean the payment state
{
var[$payment_id] = false;
var[$payment_id||"_initiator"] = false;
var[$payment_id||"_communication"] = false;
var[$payment_id||"_destination"] = false;
var[$payment_id||"_amount"] = false;
var[$payment_id||"_account"] = false;
var[$payment_id||"_validations_needed"] =false;
response['message'] = "Payment executed";
var[$account_name||"_balance"] += trigger.output[[asset=base]].amount-$payment_amount;
}
else
response['message'] = "Payment validated, next validation in progress ^^";
}"
}
]
},
{ if: "{ !!trigger.data.pay_to}", // intiate a payment from teh joint account
init: "{
// bouncing
$account_name = trigger.data.account_name otherwise bounce ($INSTRUCTIONS);
if (!var[$account_name]) bounce ("Account "||$account_name||" do not exist!");
if (!var[$LIST_HOLDER_AA][$account_name||"_users_"||trigger.address])
bounce ("This address is not listed as actor of this account");
if (!is_valid_address(trigger.data.pay_to)) bounce ("Invalid address in 'pay_to'!");
if (!is_valid_amount(trigger.data.amount)) bounce ("amount must be positive !");
// initiate payment request
$payment_id = sha256($account_name||'>'||$pay_address||': '||$pay_amount);
}",
messages: [
{
app: 'data', payload: {
list_name: `{ $account_name||"_users" }`,
get_previous: `{ true }`,
token: `{ $payment_id }`
},
},
{
app: 'payment', payload: { asset: "base", outputs: [
{ "address": "{ $LIST_HOLDER_AA }", "amount": 1000 }
] }
},
{
app: "state", state: "{
$nickname = var[$LIST_HOLDER_AA][$account_name||"_users_"||trigger.address];
var[$payment_id] = "Payment of "||trigger.data.amount||" bytes from "||$account_name||" to "||trigger.data.pay_to||" initiated by "||trigger.address||"("||$nickname||")";
var[$payment_id||"_initiator"] = trigger.address;
var[$payment_id||"_destination"] = trigger.data.pay_to;
var[$payment_id||"_amount"] = trigger.data.amount;
var[$payment_id||"_account"] = $account_name;
var[$payment_id||"_communication"] = trigger.data.communication otherwise "none";
var[$payment_id||"_validations_needed"] = var[$LIST_HOLDER_AA][$account_name||"_users_items_count"]-1;
var[$account_name||"_balance"] += trigger.output[[asset=base]].amount-1000;
response['message'] = "Payment "||$payment_id||" created and approvals requested";
}"
},
]
},
{ if: "{ !!trigger.data.add_user }", // as long as the account is not activated
init: "{
$account_name = var[trigger.address] otherwise trigger.data.account_name otherwise bounce ($INSTRUCTIONS);
if (!!var[$account_name||"_owner"])
if (trigger.address != var[$account_name||"_owner"])
bounce ("Account "||$account_name||" already exist!");
if (!is_valid_address(trigger.data.add_user)) bounce ("Invalid address in 'add_user'!");
}",
messages: [
{
app: 'data', payload: {
list_name: `{ $account_name||"_users" }`,
add: `{ trigger.data.add_user }`,
value: `{ trigger.data.nickname }`,
},
},
{
app: 'payment', payload: { asset: "base", outputs: [
{"address": "{ $LIST_HOLDER_AA }", "amount": 1000 }
]}
},
{
app: "state", state: "{
// temporary store creator to avoid to enter account name for each new user added
var[trigger.address] = $account_name;
// temporary store owner to avoid abuse during creation of the account
var[$account_name||"_owner"] = trigger.address;
var[$account_name||"_balance"] += trigger.output[[asset=base]].amount - 2000;
response['message'] = 'One user added ^^';
}"
}
]
},
{ if: "{ !!trigger.data.activate_account }", // just after the addition of all the parties
init: "{
$account_name = var[trigger.address] otherwise trigger.data.account_name otherwise bounce ($INSTRUCTIONS);
if (!!var[$account_name||"_owner"])
if (trigger.address != var[$account_name||"_owner"])
bounce ($account_name||" already active!");
if (!trigger.data.hierarchical and !trigger.data.flat)
bounce ("you must specify 'hierarchical = true' or 'flat = true'");
}",
messages: [
{
app: "state", state: "{
var[$account_name] = !!trigger.data.hierarchical ? "hierarchical": "flat";
var[$account_name||"_owner"] = false;
var[trigger.address] = false;
var[$account_name||"_balance"] += trigger.output[[asset=base]].amount;
response['message'] = $account_name||" activated ^^";
}"
}
]
},
{ if: "{ !!trigger.data.fill}", // cancel a payment providing the pay_id
init: "{
$account_name = trigger.data.account_name otherwise bounce ($INSTRUCTIONS);
}",
messages: [ // send cancel message to initiator of the payment
{
app: "state", state: "{
var[$account_name||"_balance"] += trigger.output[[asset=base]].amount;
response['message'] = "Account filled ^^";
}"
}
]
},
{ if: "{ trigger.address == $LIST_HOLDER_AA }", // forward request to next party and continue the list of parties
init: "{
// initiate payment request
$payment_id = trigger.data.token; // get it back from HOLLAA
$account_name = var[$payment_id||"_account"];
$party = trigger.data.item_name;
// validation from party needed?
$actual_user_validation_needed = $party != var[$payment_id||"_initiator"];
//
$another_party_is_needed = $party != var[$LIST_HOLDER_AA][$account_name||"_users_first_item"];
$forwarding_needed = $another_party_is_needed
and (var[$account_name] == "flat" or !$actual_user_validation_needed);
}",
messages: [
{
if: `{ $forwarding_needed }`,
app: 'data', payload: {
list_name: `{ $account_name||"_users" }`,
get_previous: `{ $party }`,
token: `{ $payment_id }`,
},
},
{
if: `{ $actual_user_validation_needed }`, // validation is not needed by initiator
app: 'data', payload: {
message: `{"JAAA: Your approval is required: "||var[$payment_id]||", please send me back the pay_id linked to validate the transaction. And add a 'cancel = true' field to refuse it."}`,
me: `{ this_address }`,
pay_id: `{ $payment_id }`,
},
},
{
app: 'payment', payload: { asset: "base", outputs: [
{ if: `{ $forwarding_needed }`,
"address": "{ $LIST_HOLDER_AA }", "amount": "{ 1000 }"
},
{ if: `{ $actual_user_validation_needed }`,
"address": "{ $party }", "amount": "{ 1000 }"
}
] }
},
{
app: "state", state: "{
var[$payment_id||"_needs_"||$party] = $actual_user_validation_needed;
if ( $actual_user_validation_needed )
response["message"] = $party||" has been requested for validation";
if ( $forwarding_needed )
response["message"] = "Forwarding info to other parties";
var[$account_name||"_balance"] += trigger.output[[asset=base]].amount-2000;
}"
},
]
},
{ // default case: bouncing the instruction
messages: [ { "app": "state","state": "{ bounce ($INSTRUCTIONS); }" } ]
}
]
}
}