-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathakash.source
713 lines (618 loc) · 24.2 KB
/
akash.source
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
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
# Akash CLI shell booster 0.4.1
#
# Date: 21 February 2022
# Author: Andy <[email protected]>
#
# Make sure you have the following programs installed:
# bash, grep, column, awk, jq, bc, nc, curl, akash
#
#
# to avoid "printf: 105.23: invalid number" errors
export LC_NUMERIC=en_US.UTF-8
export LOGLEVEL=${LOGLEVEL:-2} # 1 ERROR, 2 INFO (default), 3 DEBUG
export AKASH_BROADCAST_MODE=sync
# block: the CLI waits for the tx to be committed in a block.
# sync: the CLI waits for a CheckTx execution response only.
# async: the CLI returns immediately (transaction might fail).
# set the gas price to pay the fees.
# fees = ceil(gasLimit * gasPrices)
# Akash RPC nodes usually set --minimum-gas-prices=0.025uakt hence we will
# also use --gas-prices=0.025uakt
# --gas - gas limit to set per-transaction; set to "auto" to calculate sufficient gas automatically (default 200000)
export AKASH_GAS=auto
export AKASH_GAS_PRICES=0.025uakt
# --gas-adjustment - adjustment factor to be multiplied against the estimate returned by the tx simulation.
# if the gas limit is set manually this flag is ignored.
# increase this parameter if you see "Out of gas" errors often.
export AKASH_GAS_ADJUSTMENT=1.5
export AKASH_OUTPUT=json # default: text
# will get auto-detected
#export AKASH_KEYRING_BACKEND=os # file
export AKASH_PAGE=1
export AKASH_LIMIT=100
function d_echo() {
[[ "$LOGLEVEL" -ge "3" ]] || return 0
>&2 echo "DEBUG: $@"
}
function i_echo() {
[[ "$LOGLEVEL" -ge "2" ]] || return 0
>&2 echo "INFO: $@"
}
function e_echo() {
[[ "$LOGLEVEL" -ge "1" ]] || return 0
>&2 echo "ERROR: $@"
}
function set_rpc() {
GOOD_RPC="$(curl -s "$AKASH_NET/rpc-nodes.txt" | while read url; do RESP="$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 1 --max-time 1 "$url")"; [[ 200 -eq $RESP ]] && echo "$url"; done)"
export AKASH_NODE="$(echo "$GOOD_RPC" | shuf -n 1)"
NET_ID=$(curl -s "$AKASH_NODE/status" | jq -r '.result.node_info.network')
if [[ $NET_ID != $AKASH_CHAIN_ID ]]; then
e_echo "AKASH_CHAIN_ID '$AKASH_CHAIN_ID' does not match what Akash RPC $AKASH_NODE has: '$NET_ID'!";
e_echo "Run set_rpc or source me again."
unset AKASH_NODE
return 1
fi
check_rpc || return 1
i_echo "Akash RPC has been set to $AKASH_NODE"
set_ps;
}
function check_rpc() {
DATE_AKASH=$(curl -s "$AKASH_NODE/status" | jq -r '.result.sync_info.latest_block_time')
TS_AKASH=$(date +%s --date "$DATE_AKASH")
TS=$(date +%s)
DIFF=$(echo "$TS - $TS_AKASH" | bc)
if [ $DIFF -gt 30 ]; then
e_echo "Akash RPC $AKASH_NODE is running $DIFF seconds behind."
echo "ACTION: Please source me (or run set_rpc) command again."
unset AKASH_NODE
return 1
elif [ $DIFF -lt -30 ]; then
e_echo "Akash RPC $AKASH_NODE is running $DIFF seconds ahead."
echo "ACTION: Make sure your system time is synchronized."
unset AKASH_NODE
return 1
else
d_echo "Last block Akash RPC $AKASH_NODE seen was $DIFF seconds ago => OK"
fi
}
function set_ps() {
arg1=$1
PS1=${ORIG_PS1:-$PS1}
ORIG_PS1=$PS1
arg1="[$AKASH_NODE][$AKASH_FROM][$arg1]"
PS1=$(echo $PS1 | sed -e 's#\\\$#'$arg1'$ #g')
}
# check whether variable is exported (not set, but exported!)
function check_envs() {
rc=0;
for i in $@; do
local name="$i"
if [[ "${!name@a}" != *x* ]]; then
echo "$i variable is not exported."
rc=1
fi
done
return $rc
}
function get_tx_status() {
TX=$1
unset rc
timeout 20 bash -c -- "
while ! $AKASH_BIN query tx $TX >/dev/null 2>&1; do
sleep 3
done
"
rc=$($AKASH_BIN query tx $TX 2>/dev/null | jq -r '.code')
echo $rc
#return $rc
}
# like 'akash tx' but with a follow-up
function akash_safe_tx() {
i_echo "Broadcasting '$AKASH_BIN $@' transaction..."
TX=$($AKASH_BIN tx $@ | jq -r '.txhash')
if [ -z "$TX" ]; then
e_echo "Failed to obtain TX hash. Possible reasons are:"
e_echo "- see the rpc error message above"
e_echo "- network congested"
e_echo "- RPC node is overloaded and timed out"
return 1
fi
i_echo "Waiting for the TX $TX to get processed by the Akash network"
d_echo "TX gets broadcasted to RPC and will sit in their mempool until getting picked by the validators and then committed to the next block."
rc=$(get_tx_status $TX);
case $rc in
0)
i_echo "Success"
d_echo "TX=$TX"
echo $TX
;;
11)
e_echo "Out of gas! Consider raising AKASH_GAS_ADJUSTMENT and trying again."
e_echo "$($AKASH_BIN query tx $TX | jq -r '.raw_log')"
return 1
;;
*)
if [ -z $rc ]; then
e_echo "Waiting for the TX: $TX has timed out. It could succeed, so check with '$AKASH_BIN query tx $TX | jq | less' command and if you see code 0 there, then it's good."
else
e_echo "Transaction $TX failed with '$rc' code."
fi
return 1
;;
esac
}
function akash_deploy() {
[ ! -f $1 ] || [ -z $1 ] && { e_echo "Specify deployment file"; return 1; }
# default to 1 if not exported.
export AKASH_OSEQ=${AKASH_OSEQ:-1}
# Make sure you have the cert
# TODO: add cert validity check, serial match + cert presence (~/.akash/<name>.pem)
CL="$($AKASH_BIN query cert list 2>/dev/null)"
rc=$?
if [ "$rc" -ne "0" ]; then
e_echo "Error. Make sure you are using the correct Akash version for $AKASH_CHAIN_ID network."
return 1
fi
certs_n=$(echo "$CL" | jq -r '.certificates | length')
if [ $certs_n -le 0 ]; then
e_echo "Missing client certificate! Run akash_mkcert to create one."
return 1
fi
B=$(akash_balance);
if (( $(echo "$B < 5.5" | bc) )); then
e_echo "Your $AKASH_OWNER account has low balance, make sure to have at least 5.5 AKT."
return 1
fi
export -n AKASH_DSEQ
TX=$(akash_safe_tx deployment create -y $1) # | jq -r '.txhash')
rc=$?
export AKASH_DSEQ
if [ "$rc" -ne "0" ]; then
e_echo "- issue in the Akash deployment manifest '$1'"
e_echo "- certificate has not been committed to blockchain"
e_echo "In some cases the transaction could have been successfully broadcasted, so"
e_echo "before re-running akash_deploy, run akash_orders first to see if that is the case."
return 1
fi
AKASH_DSEQ=$($AKASH_BIN query tx $TX | jq -r '.tx.body.messages[].id.dseq')
if [ -z "$AKASH_DSEQ" ]; then
e_echo "Failed to obtain AKASH_DSEQ"
return 1
fi
d_echo "Deployment request $AKASH_DSEQ broadcasted to the Akash $AKASH_CHAIN_ID chain!"
d_echo "AKASH_DSEQ=$AKASH_DSEQ"
export AKASH_DSEQ
set_ps $AKASH_DSEQ-$AKASH_GSEQ-$AKASH_OSEQ;
}
function akash_update() {
[ ! -f $1 ] || [ -z $1 ] && { e_echo "Specify deployment file"; return 1; }
TX=$(akash_safe_tx deployment update -y $1) # | jq -r '.txhash')
rc=$?
if [ "$rc" -ne "0" ]; then
return 1
fi
}
function akash_close_deployment() {
check_envs AKASH_DSEQ || return 1
$AKASH_BIN query deployment get | jq -r '.deployment.state' | grep -qw closed && { echo "$AKASH_DSEQ is already closed."; return 0; }
TX=$(akash_safe_tx deployment close -y) # | jq -r '.txhash')
rc=$?
if [ "$rc" -ne "0" ]; then
return 1
fi
echo "$AKASH_DSEQ/$AKASH_OSEQ deployment has been successfully closed."
usd_per_akt="$(get_akt_price)"
spent=$($AKASH_BIN query deployment get | jq -r '.escrow_account.transferred.amount')
spent_usd=$(echo "scale=7;($spent/10^6)*$usd_per_akt" | bc -l)
i_echo "Total $spent uakt or" $(printf '$%.7f' $spent_usd)
d_echo "Clearing AKASH_DSEQ, AKASH_GSEQ, AKASH_OSEQ, AKASH_PROVIDER environment variables"
unset AKASH_OSEQ
unset AKASH_GSEQ
unset AKASH_DSEQ
unset AKASH_PROVIDER
set_ps;
}
function akash_close_gseq() {
echo "$AKASH_DSEQ/$AKASH_GSEQ/$AKASH_OSEQ group has been successfully closed."
usd_per_akt="$(get_akt_price)"
spent=$($AKASH_BIN query deployment get | jq -r '.escrow_account.transferred.amount')
spent_usd=$(echo "scale=7;($spent/10^6)*$usd_per_akt" | bc -l)
i_echo "Spent $spent uakt or" $(printf '$%.7f' $spent_usd)
d_echo "Clearing AKASH_DSEQ, AKASH_GSEQ, AKASH_OSEQ, AKASH_PROVIDER environment variables"
unset AKASH_OSEQ
unset AKASH_GSEQ
unset AKASH_DSEQ
unset AKASH_PROVIDER
set_ps;
}
function akash_close() {
check_envs AKASH_DSEQ || return 1
$AKASH_BIN query deployment get | jq -r '.deployment.state' | grep -qw closed && { echo "$AKASH_DSEQ is already closed."; return 0; }
DL="$($AKASH_BIN query deployment list)"
groups_n="$(echo $DL | jq -r '[.deployments[].groups[].group_id.gseq] | length')"
if [[ $groups_n -gt 1 ]]; then
echo "This deployment has more than 1 placement group:"
echo "$DL" | jq -r '["dseq","gseq","state","name"], (.deployments[].groups[] | [.group_id.dseq, .group_id.gseq, .state, .group_spec.name]) | @csv' | column -t -s"," | awk '{if (NR!=1) {print NR-2 ">\t" $s} else {print "\t" $s}}'
read -ep "Choose your placement group to close or type \"a\" to close the entire deployment (default) [a]: " n
[[ -z "$n" ]] && n="a";
group=$n
if [[ $group == "a" ]]; then
akash_close_deployment;
else
AKASH_DSEQ=$(echo "$DL"| jq -r --argjson g $group '.deployments[].groups[$g].group_id.dseq')
AKASH_GSEQ=$(echo "$DL"| jq -r --argjson g $group '.deployments[].groups[$g].group_id.gseq')
TX=$(akash_safe_tx deployment group close -y) # | jq -r '.txhash')
rc=$?
if [ "$rc" -ne "0" ]; then
return 1
fi
akash_close_gseq;
fi
else
akash_close_deployment;
fi
}
# Lists active deployments
function akash_deployments() {
echo "List of open deployments"
# open == active deployments can remain open indefinitely, until their owner closes them.
# open deployments != active leases!
export -n AKASH_DSEQ
#export -n AKASH_GSEQ
#export -n AKASH_OSEQ
DL="$($AKASH_BIN query deployment list --state active)"
export AKASH_DSEQ
export AKASH_GSEQ
export AKASH_OSEQ
deployments_n="$(echo "$DL" | jq -r '[.deployments[]] | length')"
if [[ "$deployments_n" -eq 0 ]]; then
echo "Unable to find any active deployments."
return 1
fi
echo "Found the following active deployments:"
echo "$DL" | jq -r '"dseq", (.deployments[].deployment.deployment_id.dseq)' | column -t -s"," | awk '{if (NR!=1) {print NR-2 ">\t" $s} else {print "\t" $s}}'
n_last=$((deployments_n-1));
read -ep "Choose your deployment from the list [$n_last]: " n
[[ -z "$n" ]] && n=$n_last;
[[ $n =~ ^[0-9]+$ ]] || { echo "Enter a valid number"; return 1; }
if (($n < 0 || $n > $n_last)); then
echo "Value '$n' is outside the 0..${n_last} range."
return 1
fi
deployment=$n
groups_n="$(echo "$DL" | jq -r --argjson n $deployment '[.deployments[$n].groups[]] | length')"
n_last=$((groups_n-1));
if [[ $groups_n -gt 1 ]]; then
echo "This deployment has more than 1 placement group:"
echo "$DL" | jq -r --argjson n $deployment '["dseq","gseq","state","name"], (.deployments[$n].groups[] | [.group_id.dseq, .group_id.gseq, .state, .group_spec.name]) | @csv' | column -t -s"," | awk '{if (NR!=1) {print NR-2 ">\t" $s} else {print "\t" $s}}'
read -ep "Choose your placement group [$n_last]: " n
[[ -z "$n" ]] && n=$n_last;
group=$n
else
group=0
fi
AKASH_DSEQ=$(echo "$DL"| jq -r --argjson n $deployment --argjson g $group '.deployments[$n].groups[$g].group_id.dseq')
AKASH_GSEQ=$(echo "$DL"| jq -r --argjson n $deployment --argjson g $group '.deployments[$n].groups[$g].group_id.gseq')
AKASH_OSEQ=1
if [ -z "$AKASH_DSEQ" ]; then
echo "Unable to find most recent active deployment."
return 1
fi
echo "Selected $n: $AKASH_DSEQ-$AKASH_GSEQ-$AKASH_OSEQ"
echo "AKASH_DSEQ=$AKASH_DSEQ"
echo "AKASH_GSEQ=$AKASH_GSEQ"
echo "AKASH_OSEQ=$AKASH_OSEQ"
set_ps $AKASH_DSEQ-$AKASH_GSEQ-$AKASH_OSEQ;
echo "Looking for a matching provider for this order..."
akash_findprovider;
echo "AKASH_PROVIDER=$AKASH_PROVIDER"
}
# Lists open orders
function akash_orders() {
echo "Orders you have not accepted the bid for. (i.e. have not ran lease create yet)."
i_echo "Hint: You can close them to release the deposit."
export -n AKASH_DSEQ
export -n AKASH_GSEQ
export -n AKASH_OSEQ
OL="$($AKASH_BIN query market order list --state open --gseq 0 --oseq 0)"
export AKASH_DSEQ
export AKASH_GSEQ
export AKASH_OSEQ
orders_n="$(echo "$OL" | jq -r '.orders | length')"
if [[ "$orders_n" -eq 0 ]]; then
echo "Unable to find any open orders."
return 1
fi
echo "Found the following open deployment orders:"
echo "$OL" | jq -r '["dseq","gseq","oseq"], (.orders[].order_id | [ .dseq, .gseq, .oseq ]) | @csv' | column -t -s"," | awk '{if (NR!=1) {print NR-2 ">\t" $s} else {print "\t" $s}}'
n_last=$((orders_n-1));
read -ep "Choose your order from the list [$n_last]: " n
[[ -z "$n" ]] && n=$n_last;
[[ $n =~ ^[0-9]+$ ]] || { echo "Enter a valid number"; return 1; }
if (($n < 0 || $n > $n_last)); then
e_echo "Value '$n' is outside the 0..${n_last} range."
return 1
fi
#export AKASH_PROVIDER=$(echo "$PL" | jq -r --arg n $n '.bids['$n'].bid.bid_id.provider')
AKASH_DSEQ=$(echo "$OL"| jq -r --arg n $n '.orders['$n'].order_id.dseq')
AKASH_GSEQ=$(echo "$OL"| jq -r --arg n $n '.orders['$n'].order_id.gseq')
AKASH_OSEQ=$(echo "$OL"| jq -r --arg n $n '.orders['$n'].order_id.oseq')
if [ -z "$AKASH_DSEQ" ]; then
echo "Unable to find most recent active deployment."
return 1
fi
echo "Selected $n: $AKASH_DSEQ-$AKASH_GSEQ-$AKASH_OSEQ"
echo "AKASH_DSEQ=$AKASH_DSEQ"
echo "AKASH_GSEQ=$AKASH_GSEQ"
echo "AKASH_OSEQ=$AKASH_OSEQ"
set_ps $AKASH_DSEQ-$AKASH_GSEQ-$AKASH_OSEQ;
}
function akash_getdeployment() {
$AKASH_BIN query deployment get -o text
}
function akash_status() {
akash_findprovider
$AKASH_BIN ${PRE_MAINNET4_PROVIDER_CMD} lease-status
export -n AKASH_PROVIDER
}
function akash_findprovider() {
export -n AKASH_PROVIDER
AKASH_GSEQ=${AKASH_GSEQ:-1}
AKASH_PROVIDER=$($AKASH_BIN query market lease list --gseq 0 --oseq 0 | jq -r --argjson g $AKASH_GSEQ '.leases[].lease.lease_id | select(.gseq == $g) | .provider')
export AKASH_PROVIDER
if [ -z "$AKASH_PROVIDER" ]; then
echo "Unable to locate last active lease. It could be that it has never been created."
return 1
fi
echo "Detected provider for $AKASH_DSEQ/$AKASH_GSEQ/$AKASH_OSEQ: $AKASH_PROVIDER"
}
function akash_leases() {
check_envs AKASH_DSEQ || return 1
export -n AKASH_PROVIDER
$AKASH_BIN query market lease list | jq -r '.leases[] | [ (.lease | (.lease_id | .provider, .owner, .dseq, .gseq, .oseq), (.price.amount|tonumber), .state), (.escrow_payment | .state, (.balance.amount, .withdrawn.amount)) ] | @csv'
export AKASH_PROVIDER
}
function akash_leases_all() {
export -n AKASH_PROVIDER
export -n AKASH_DSEQ
export -n AKASH_GSEQ
export -n AKASH_OSEQ
echo "List of all active leases:"
$AKASH_BIN query market lease list --state active | jq -r '.leases[] | [ (.lease | (.lease_id | .provider, .owner, .dseq, .gseq, .oseq), (.price.amount|tonumber), .state), (.escrow_payment | .state, (.balance.amount, .withdrawn.amount)) ] | @csv'
export AKASH_PROVIDER
export AKASH_DSEQ
export AKASH_GSEQ
export AKASH_OSEQ
}
function get_akt_price() {
# cache AKT price for 60 minutes to reduce the API pressure as well as to slightly accelerate the bidding (+5s)
CACHE_FILE=/tmp/aktprice.cache
if ! test $(find $CACHE_FILE -mmin -60 2>/dev/null); then
## cache expired
usd_per_akt=$(curl -s --connect-timeout 3 --max-time 3 -X GET 'https://api-osmosis.imperator.co/tokens/v2/price/AKT' -H 'accept: application/json' | jq -r '.price' 2>/dev/null)
if [[ $? -ne 0 ]] || [[ $usd_per_akt == "null" ]] || [[ -z $usd_per_akt ]]; then
# if Osmosis API fails, try CoinGecko API
usd_per_akt=$(curl -s --connect-timeout 3 --max-time 3 -X GET "https://api.coingecko.com/api/v3/simple/price?ids=akash-network&vs_currencies=usd" -H "accept: application/json" | jq -r '[.[]][0].usd' 2>/dev/null)
fi
# update the cache only when API returns a result.
# this way provider will always keep bidding even if API temporarily breaks (unless pod gets restarted which will clear the cache)
if [ ! -z $usd_per_akt ]; then
# check price is an integer/floating number
re='^[0-9]+([.][0-9]+)?$'
if ! [[ $usd_per_akt =~ $re ]]; then
echo "ERROR: AKT price isn't an integer/floating number! Check price API."
usd_per_akt=0
fi
# make sure price is in the permitted range
if ! (( $(echo "$usd_per_akt > 0" | bc -l) && \
$(echo "$usd_per_akt <= 1000000" | bc -l) )); then
echo "ERROR: AKT price is out of bounds! Check price API."
usd_per_akt=0
fi
echo "$usd_per_akt" > $CACHE_FILE
fi
fi
usd_per_akt=$(cat $CACHE_FILE)
echo $usd_per_akt
}
function akash_accept() {
check_envs AKASH_DSEQ || return 1
PL="$($AKASH_BIN query market bid list --state open --gseq 0 --oseq 0)"
bids_n="$(echo "$PL" | jq -r '.bids | length')"
if [[ "$bids_n" -le 0 ]]; then
echo "Unable to find any bids. Try re-running in few seconds."
return 1
fi
usd_per_akt="$(get_akt_price)"
PROVIDERS="$($AKASH_BIN query provider list --page 1 --limit 1000)"
printf "\trate\tmonthly\tusd\tdseq/gseq/oseq\tprovider\t\t\t\t\thost\n"
echo "$PL" | jq -r '.bids[].bid | [.price.amount, (.bid_id | .dseq, .gseq, .oseq, .provider)] | @tsv' | while read rate dseq gseq oseq p; do
uri="$(echo $PROVIDERS | jq --arg p $p -r '.providers[] | select(.owner == $p) | .host_uri' | awk -F/ '{print $3}')"
price_m=$(echo "scale=2; $rate*((60/6.117)*60*24*30.436875)/10^6" | bc -l | sed 's/^\./0./')
printf "%.2f\t%.2f\t$%.2f\t%s/%s/%s\t%s\t%s\t%s\n" $rate $price_m $(echo "$price_m*$usd_per_akt" |bc -l) $dseq $gseq $oseq $p $uri
done | awk '{print NR-1 ">\t" $s}'
n_last=$((bids_n-1));
read -ep "Choose your bid from the list [$n_last]: " n
[[ -z "$n" ]] && n=$n_last;
[[ $n =~ ^[0-9]+$ ]] || { echo "Enter a valid number"; return 1; }
if (($n < 0 || $n > $n_last)); then
e_echo "Value '$n' is outside the 0..${n_last} range."
return 1
fi
AKASH_PROVIDER=$(echo "$PL" | jq -r --arg n $n '.bids['$n'].bid.bid_id.provider')
AKASH_GSEQ=$(echo "$PL" | jq -r --arg n $n '.bids['$n'].bid.bid_id.gseq')
AKASH_OSEQ=$(echo "$PL" | jq -r --arg n $n '.bids['$n'].bid.bid_id.oseq')
if [ -z "$AKASH_PROVIDER" ]; then
e_echo "Could not find the provider. Most likely Akash RPC issues. Try to rerun this command or change Akash RPC node."
return 1
fi
i_echo "Accepting the bid offered by $AKASH_PROVIDER provider for $AKASH_DSEQ/$AKASH_GSEQ/$AKASH_OSEQ deployment"
export AKASH_PROVIDER
export AKASH_GSEQ
export AKASH_OSEQ
set_ps $AKASH_DSEQ-$AKASH_GSEQ-$AKASH_OSEQ;
PL="$($AKASH_BIN query market bid list --state open --gseq 0 --oseq 0)"
bids_n="$(echo "$PL" | jq -r '.bids | length')"
if [[ "$bids_n" -le 0 ]]; then
echo "Unable to find any bids. Try re-running in few seconds."
return 1
fi
akash_safe_tx market lease create -y
export -n AKASH_PROVIDER
}
function akash_balance() {
$AKASH_BIN query bank balances "$AKASH_OWNER" | jq -r '(.balances[0].amount | tonumber / pow(10; 6))'
}
function akash_mkcert() {
akash tx cert generate client -y
akash_safe_tx cert publish client -y
}
function akash_send_manifest() {
[ ! -f $1 ] || [ -z $1 ] && { e_echo "Specify deployment file"; return 1; }
rc=1
akash_findprovider;
check_envs AKASH_PROVIDER AKASH_DSEQ AKASH_GSEQ AKASH_OSEQ || return 1;
LEASE_STATE="$($AKASH_BIN query market lease get | jq -r '.lease.state')"
case $LEASE_STATE in
"")
e_echo "Something went wrong and should not have happened."
e_echo "Please report the following to the devs:"
e_echo "provider: $AKASH_PROVIDER owner: $AKASH_OWNER dseq: $AKASH_DSEQ gseq: $AKASH_GSEQ oseq: $AKASH_OSEQ tx: $TX"
;;
active)
$AKASH_BIN ${PRE_MAINNET4_PROVIDER_CMD} send-manifest $1
rc=$?
if [ "$rc" -ne "0" ]; then
e_echo "$AKASH_BIN ${PRE_MAINNET4_PROVIDER_CMD} send-manifest failed with '$rc' code."
rc=1
fi
;;
*)
i_echo "Lease is not yet active for $AKASH_DSEQ deployment on $AKASH_PROVIDER"
i_echo "Lease state: ${LEASE_STATE:-unknown}"
;;
esac
export -n AKASH_PROVIDER
return $rc
}
# Test:
# akash_shell bash -c "uname -r"
# akash_shell bash -c "bash -c 'uname -r'"
# akash_shell <service> bash -c "uname -r"
function akash_shell() {
akash_findprovider
if [ $# -eq 0 ]; then
echo "Usage: akash_shell [service] <command>"
return 1
fi
arg1=$1
LS="$($AKASH_BIN ${PRE_MAINNET4_PROVIDER_CMD} lease-status)"
echo "$LS" | jq -r '.services[].name' | grep -qw $arg1
rc=$?
# if arg1 not found in the deployment, assume it is a command
# and pick SVC automatically, otherwise set SVC=$arg1
if [ "$rc" -ne "0" ]; then
SN="$(echo "$LS" | jq -r '.services | length')"
if [[ "$SN" -gt 1 ]]; then
echo "Select a service name you want to run command '$@' at."
echo "$LS" | jq -r '.services[].name' | nl -v 0
read -ep "Pick your service [0]: " n
n_last=$((SN-1));
[[ -z "$n" ]] && n=0;
[[ $n =~ ^[0-9]+$ ]] || { e_echo "Enter a valid number"; return 1; }
if (($n < 0 || $n > $n_last)); then
e_echo "Value '$n' is outside the 0..${n_last} range."
export -n AKASH_PROVIDER
return 1
fi
SVC=$(echo "$LS" | jq -r --arg n $n '[.services[].name]['$n']')
else
SVC=$(echo "$LS" | jq -r --arg n $n '.services[].name')
fi
else
SVC=$arg1;
shift;
fi
#set -x
$AKASH_BIN ${PRE_MAINNET4_PROVIDER_CMD} lease-shell --tty --stdin -- "$SVC" "${@}"
#set +x
rc=$?
if [ "$rc" -eq "0" ]; then
set_ps $AKASH_DSEQ-$AKASH_GSEQ-$AKASH_OSEQ-$SVC;
fi
export -n AKASH_PROVIDER
}
function akash_logs() {
akash_findprovider
$AKASH_BIN ${PRE_MAINNET4_PROVIDER_CMD} lease-logs -o text $@
export -n AKASH_PROVIDER
}
function akash_events() {
akash_findprovider
$AKASH_BIN ${PRE_MAINNET4_PROVIDER_CMD} lease-events $@
export -n AKASH_PROVIDER
}
function akash_providers() {
export -n AKASH_PROVIDER
$AKASH_BIN query provider list --limit 500 | jq -r '.providers[] | [ .host_uri, .owner, .attributes[].value ] | @csv' | sort -d
export AKASH_PROVIDER
}
function akash_provider() {
check_envs AKASH_PROVIDER || return 1
$AKASH_BIN query provider get $AKASH_PROVIDER | jq
}
function detect_keyring_backend() {
i_echo "Detecting keyring backend..."
# a very simple method based on the keys amount :-)
export -n AKASH_KEYRING_BACKEND
os_l=$(AKASH_KEYRING_BACKEND=os $AKASH_BIN keys list | jq -r '. | length')
file_l=$(AKASH_KEYRING_BACKEND=file $AKASH_BIN keys list | jq -r '. | length')
test_l=$(AKASH_KEYRING_BACKEND=test $AKASH_BIN keys list | jq -r '. | length')
# TODO: need to improve the logic here
[[ $os_l -ge $test_l ]] && AKASH_KEYRING_BACKEND=os || AKASH_KEYRING_BACKEND=test
[[ $file_l -ge $test_l ]] && AKASH_KEYRING_BACKEND=file
echo "AKASH_KEYRING_BACKEND=$AKASH_KEYRING_BACKEND"
export AKASH_KEYRING_BACKEND
}
function auto_select_key() {
echo "Trying to automatically determine AKASH_FROM, AKASH_OWNER ..."
detect_keyring_backend;
KL=$($AKASH_BIN keys list)
keys_n=$(echo "$KL" | jq -r '. | length')
if [[ "$keys_n" -eq 0 ]]; then
echo "Unable to find any key with AKASH_KEYRING_BACKEND=$AKASH_KEYRING_BACKEND"
return 1
fi
echo "Available keys:"
echo "$KL" | jq -r '["name","address"], (.[] | [.name, .address]) | @csv' | column -t -s"," | awk '{if (NR!=1) {print NR-2 ">\t" $s} else {print "\t" $s}}'
n_last=$((keys_n-1));
read -ep "Choose your key from the list [0]: " n
[[ -z "$n" ]] && n=0;
[[ $n =~ ^[0-9]+$ ]] || { e_echo "Enter a valid number"; return 1; }
if (($n < 0 || $n > $n_last)); then
e_echo "Value '$n' is outside the 0..${n_last} range."
return 1
fi
export AKASH_FROM="$($AKASH_BIN keys list | jq -r --arg n $n '.['$n'] | .name')"
export AKASH_OWNER="$($AKASH_BIN keys list | jq -r --arg n $n '.['$n'] | .address')"
set_ps;
}
function set_net() {
export NET=${NET:-mainnet} # edgenet, testnet
# make sure to download newest Akash release when running edgenet or testnet
# https://github.com/ovrclk/akash/releases
AKASH_NET="https://raw.githubusercontent.com/ovrclk/net/master/$NET"
export AKASH_CHAIN_ID="$(curl -s "$AKASH_NET/chain-id.txt")"
[ -z "$AKASH_NODE" ] && set_rpc;
#set_ps "$AKASH_NODE][$AKASH_FROM";
}
## SCRIPT STARTS HERE
unset AKASH_FROM
unset AKASH_OWNER
export AKASH_BIN="provider-services"
export PRE_MAINNET4_PROVIDER_CMD=""
# Pre-mainnet4 config
# export AKASH_BIN="akash"
# export PRE_MAINNET4_PROVIDER_CMD="provider"
auto_select_key;
set_net