diff --git a/ASTROBOT/TAG.copy.sh b/ASTROBOT/TAG.copy.sh
new file mode 100755
index 00000000..5dac31fd
--- /dev/null
+++ b/ASTROBOT/TAG.copy.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+########################################################################
+# Version: 0.4
+# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
+########################################################################
+MY_PATH="`dirname \"$0\"`" # relative
+MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
+ME="${0##*/}"
+
+## AUTONOMOUS BOT
+# SEARCH FOR "voeu" TAG to create "g1voeu" TW
+# PLAYER G1VOEU NAME is considered as "tag" searh in Ŋ1
+# PARAM = tag / PLAYER
+# Search for "g1tag"
+
diff --git a/ASTROBOT/VOEUX.create.sh b/ASTROBOT/VOEUX.create.sh
new file mode 100755
index 00000000..9d5b56fe
--- /dev/null
+++ b/ASTROBOT/VOEUX.create.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+########################################################################
+# Version: 0.4
+# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
+########################################################################
+MY_PATH="`dirname \"$0\"`" # relative
+MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
+ME="${0##*/}"
+
+# Need TW index.html path + IPNS publication Key (available in IPFS keystore)
+# Search for "voeu" tagged tiddlers to get URL
+# Use G1VOEUX.sh to create and add TW to PLAYER TW
+
+INDEX="$1"
+[[ ! $INDEX ]] && echo "Please provide path to source TW index.html" && exit 1
+[[ ! -f $INDEX ]] && echo "Fichier TW absent. $INDEX" && exit 1
+
+PLAYER="$2" ## IPNS KEY NAME - G1PUB - PLAYER ...
+[[ ! $PLAYER ]] && echo "Please provide IPFS publish key" && exit 1
+ASTRONAUTENS=$(ipfs key list -l | grep -w $PLAYER | cut -d ' ' -f1)
+
+myIP=$(hostname -I | awk '{print $1}' | head -n 1)
+
+## EXPORT FROM PLAYER TW "[tag[voeu]]"
+rm -f ~/.zen/tmp/voeu.json
+tiddlywiki --verbose --load ${INDEX} --output ~/.zen/tmp --render '.' 'voeu.json' 'text/plain' '$:/core/templates/exporters/JsonFile' 'exportFilter' '[tag[voeu]]'
+
+## Tous les tiddlers comportant le tag "voeu" lancent la création d'un G1VOEU ayant le titre du Voeu comme génrateur de clef TW (pepper).
+for VOEU in $(cat ~/.zen/tmp/voeu.json | jq -r '.[].title')
+do
+ echo "Detected $VOEU"
+ echo "Creating Voeu TW"
+ ~/.zen/Astroport.ONE/G1VOEUX.sh "$VOEU" "$PLAYER" "$INDEX"
+
+
+done
diff --git a/ASTROBOT/ipns_TAG_refresh.sh b/ASTROBOT/ipns_TAG_refresh.sh
deleted file mode 100755
index d4279856..00000000
--- a/ASTROBOT/ipns_TAG_refresh.sh
+++ /dev/null
@@ -1,256 +0,0 @@
-#!/bin/bash
-########################################################################
-# Author: Fred (support@qo-op.com)
-# Version: 2020.04.28
-# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
-########################################################################
-MY_PATH="`dirname \"$0\"`" # relative
-MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
-ME="${0##*/}"
-countMErunning=$(ps auxf --sort=+utime | grep -w $ME | grep -v -E 'color=auto|grep' | wc -l)
-[[ $countMErunning -gt 2 ]] && echo "$ME already running $countMErunning time" && exit 0
-
-echo '########################################################################
-# \\///
-# qo-op
-############# '$MY_PATH/$ME'
-########################################################################
-# ex: ./'$ME'
-########################################################################'
-
-echo "CHOOSE THE WAY YOU ARE GIVING ACCES TO YOUR MEDIAKEY !!"
-echo "CONCEPT IS HERE. REWRITE NEEDED"
-exit 1
-
-########################################################################
-########################################################################
-IPFSNODEID=$(cat ~/.ipfs/config | jq -r .Identity.PeerID)
-[[ ! $IPFSNODEID ]] && echo 'ERROR missing IPFS Node id !! IPFS is not installed !?' && exit 1
-########################################################################
-[[ ! -f ~/.zen/secret.dunikey ]] && exit 1
-G1PUB=$(cat ~/.zen/secret.dunikey | grep 'pub:' | cut -d ' ' -f 2)
-########################################################################
-YOU=$(ps auxf --sort=+utime | grep -w ipfs | grep -v -E 'color=auto|grep' | tail -n 1 | cut -d " " -f 1);
-[[ ! $YOU ]] && echo "IPFS NOT RUNNING. EXIT" && exit 1
-########################################################################
-XZUID=$(cat ~/.zen/ipfs/.$IPFSNODEID/.player)
-# echo "## FRIENDS IPFS PINGing"
-# for g1pub in $(ls -t ~/.zen/ipfs/.$IPFSNODEID/FRIENDS/); do [[ $g1pub ]] && ipfs ping --timeout=3s -n 3 /ipfs/$(~/.zen/astrXbian/zen/tools/g1_to_ipfs.py $g1pub 2>/dev/null) 2>/dev/null; done
-
-
-echo "
- _ _ _ _
- / \ / \ / \ / \
-( I | P | N | S )
- \_/ \_/ \_/ \_/
-
-ZENTAG / MEDIAKEY : IPNS REFRESH
-"
-echo "I am /ipns/$IPFSNODEID controling and refreshing my MEDIAKEY IPNS"
-########################################################################
-# REFRESH IPNS SELF PUBLISH
-########################################################################
-# ~/.zen/astrXbian/zen/ipns_self_publish.sh
-########################################################################
-
-count=0
-# [[ ! -d ~/.zen/ipfs/.${IPFSNODEID}/KEY/ ]] && exit 0
-
-## TAKE CARE OF MY KEY
-for mediakey in $(ls ~/.zen/ipfs/.${IPFSNODEID}/KEY/ 2>/dev/null | shuf ); # Alternative search
-do
- [[ "${mediakey}" == "" ]] && continue ## prevent empty mediakey
-# [[ ! $(echo "${mediakey}" | grep "TMDB_") ]] && continue ## REFRESH ONLY TMDB (level 1), youtube is level 0
- IPNSLINK=$(ipfs key list -l | grep ${mediakey} | cut -d ' ' -f 1)
- [[ "${IPNSLINK}" == "" ]] && continue ## prevent empty IPNSLINK
- echo "We are refreshing http://127.0.0.1:8080/ipns/${IPNSLINK}"
- count=$((count+1)) && echo "$count) "
- FILE_NAME=$(cat ~/.zen/ipfs/.${IPFSNODEID}/KEY/${mediakey}/${G1PUB}/.ipfs.filename)
- TITLE=$(cat ~/.zen/ipfs/.${IPFSNODEID}/KEY/${mediakey}/${G1PUB}/.title)
-
- ## REFRESH MORE THAN 6 HOURS TIMESTAMP KEY
- TIMESTAMP=$(cat ~/.zen/ipfs/.${IPFSNODEID}/KEY/${mediakey}/${G1PUB}/.timestamp) # INITIAL TIMESTAMP
- [[ -f ~/.zen/ipfs/.${IPFSNODEID}/KEY/${mediakey}/.timestamp ]] && TIMESTAMP=$(cat ~/.zen/ipfs/.${IPFSNODEID}/KEY/${mediakey}/.timestamp) # LAST REFRESH
- timestamp=$(date -u +%s%N | cut -b1-13)
- STAMPDIFF=$((timestamp - TIMESTAMP))
- echo "Last Update : $(date -d @$TIMESTAMP | cut -b1-10)" # remove millisecond part
- echo "${mediakey} LAST UPDATED $STAMPDIFF milliseconds AGO"
- [ $STAMPDIFF -lt 21600000 ] && continue # 6h = 21600000 ms , 10h = 36000000 ms
-
- source=$(echo $mediakey | cut -d '_' -f 1)
-
- ANNONCE=$(cat ~/.zen/ipfs/.${IPFSNODEID}/KEY/${mediakey}/${G1PUB}/.gchange.ad 2>/dev/null)
-
- ## Use natools to decrypt "/tmp/${mediakey}_filelink.txt
- [[ -f ~/.zen/ipfs/.${IPFSNODEID}/KEY/${mediakey}/${G1PUB}/.ipfs.filelink.natools.encrypt ]] && $MY_PATH/tools/natools.py decrypt -f pubsec -k "$HOME/.zen/secret.dunikey" -i "$HOME/.zen/ipfs/.${IPFSNODEID}/KEY/${mediakey}/${G1PUB}/.ipfs.filelink.natools.encrypt" -o "/tmp/${mediakey}_filelink.txt"
- URLENCODE_FILE_NAME=$(cat /tmp/${mediakey}_filelink.txt | rev | cut -d '/' -f 1 | rev | jq -Rr @uri)
- IPFSREPFILEID=$(cat /tmp/${mediakey}_filelink.txt | rev | cut -d '/' -f 2- | rev | cut -d '/' -f 3)
-
- echo "IPFS MEDIA link : /ipfs/$IPFSREPFILEID/$URLENCODE_FILE_NAME"
-
- ## TREAT OLD DATA from new_file_in_astroport.sh (LATER can be removed)
- if [[ ! -f $HOME/.zen/ipfs/.${IPFSNODEID}/KEY/${mediakey}/content.json && -f ~/.zen/ipfs/.${IPFSNODEID}/KEY/${mediakey}/${G1PUB}/video.json ]]; then
- mediakeyfile=$($MY_PATH/tools/give_me_keystore_filename.py $mediakey)
- $MY_PATH/tools/natools.py privkey -f ipfs-keystore -k $HOME/.ipfs/keystore/$mediakeyfile -F pubsec -o /tmp/${mediakey}.dunikey
- # PubFromDunikey=$(cat /tmp/${mediakey}.dunikey | grep "sec" | cut -d ' ' -f2 | base58 -d | tail -c+33 | base58)
- PubFromDunikey=$(cat /tmp/${mediakey}.dunikey | grep "pub" | cut -d ' ' -f2)
- echo "$PubFromDunikey" > $HOME/.zen/ipfs/.${IPFSNODEID}/KEY/${mediakey}/MEDIAPUBKEY
- fi
-
- MEDIAPUBKEY=$(cat $HOME/.zen/ipfs/.${IPFSNODEID}/KEY/${mediakey}/MEDIAPUBKEY)
- echo "MEDIA G1 WALLET = $MEDIAPUBKEY"
- BALANCE=$(~/.zen/astrXbian/zen/jaklis/jaklis.py balance -p ${MEDIAPUBKEY}) && [[ $BALANCE == null || "$BALANCE" == "" ]] && BALANCE=0
- ZENBALANCE=$(echo "100 * $BALANCE" | bc -l | cut -d '.' -f 1)
-
- TUBELINK="https://tube.copylaradio.com$(cat /tmp/${mediakey}_filelink.txt)"
- LOCALTUBELINK="http://127.0.0.1:8080$(cat /tmp/${mediakey}_filelink.txt)"
-
- ### IPNS LINK CAN EVOLVE (REFRESH EVERY 12 H TO MAINTAIN ALIVE IN THE SWARM)
- ### This index.html is ipns link root, 1st welcome page for MEDIAKEY -> *** Redirect to CONTRACTS or LOGIN processing HERE ***
-
- echo "=======> Mediakey Welcome index.html
- IPNSLINK=$IPNSLINK
- IPFSNODEID=$IPFSNODEID
- XZUID=$XZUID
- G1PUB=$G1PUB
- TITLE=$TITLE"
- cat /home/$YOU/.zen/astrXbian/www/boris/youtube_watch_step2.html \
- | sed "s/\${IPNSLINK}/$IPNSLINK/g" \
- | sed "s/\${IPFSNODEID}/$IPFSNODEID/g" \
- | sed "s/\${XZUID}/$XZUID/g" \
- | sed "s/\${G1PUB}/$G1PUB/g" \
- | sed "s/\${TITLE}/$TITLE/g" \
- > /tmp/${mediakey}_index.html
- mv /tmp/${mediakey}_index.html ~/.zen/ipfs/.${IPFSNODEID}/KEY/${mediakey}/index.html
-
- [ ! -s ~/.zen/ipfs/.${IPFSNODEID}/KEY/${mediakey}/index.html ] && echo "Problem creating ~/.zen/ipfs/.${IPFSNODEID}/KEY/${mediakey}/index.html. EXIT" && exit 1
-
-########################################################################
-### Scenario are G1PUB subdivized. Thus each friend can establish own contract
-# ~/.zen/ipfs/.${IPFSNODEID}/KEY/${INDEXPREFIX}${REFERENCE}/${G1PUB}/index.html
-########################################################################
-
- ## Write KEY id (provide verification)
- [[ ! -f ~/.zen/ipfs/.${IPFSNODEID}/KEY/${mediakey}/${G1PUB}/.id ]] && echo ${mediakey} > ~/.zen/ipfs/.${IPFSNODEID}/KEY/${mediakey}/${G1PUB}/.id
-
-## THIS MAKES FRENCH COPY RIGHT LAW RESPECT
-## LOCALHOST REDIRECT FOR INTERNAL KODI DEFCON 3 (swarm.key) ASTROPORT STATION MODE
- # echo "" > ~/.zen/ipfs/.${IPFSNODEID}/KEY/${mediakey}/${G1PUB}/index.html
- # echo "" > ~/.zen/ipfs/.${IPFSNODEID}/KEY/${mediakey}/${G1PUB}/index.html
-
-## DEMO PERIOD
-## NICE FINAL STREAMING PAGE # TODO ACTIVATE DOWNLOAD FOR AVI or MKV
- FILETYPE="${LOCALTUBELINK##*.}"
- MIMETYPE="video/$FILETYPE" && HTMLTAG="video"
- [[ "$FILETYPE" == "avi" ]] && MIMETYPE="video/x-msvideo"
- [[ "$FILETYPE" == "mkv" ]] && MIMETYPE="video/x-matroska"
- [[ "$FILETYPE" == "mp3" ]] && MIMETYPE="audio/mpeg" && HTMLTAG="audio"
-
- echo "=======> Mediakey Contract index.html "
- cat /home/$YOU/.zen/astrXbian/www/boris/youtube_watch_step3.html \
- | sed "s/\${TITLE}/$TITLE/g" \
- | sed "s/\${IPFSNODEID}/$IPFSNODEID/g" \
- | sed "s/\${XZUID}/$XZUID/g" \
- | sed "s/\${IPFSREPFILEID}/$IPFSREPFILEID/g" \
- | sed "s/\${URLENCODE_FILE_NAME}/$URLENCODE_FILE_NAME/g" \
- > ~/.zen/ipfs/.${IPFSNODEID}/KEY/${mediakey}/${G1PUB}/index.html
-
-
- if [[ "$source" == "YOUTUBE" ]]
- then
- echo "$source"
- # mutiTUBE - activate .views.counter
- # echo "" > ~/.zen/ipfs/.${IPFSNODEID}/KEY/${mediakey}/${G1PUB}/index.html
- # TODO go/index.php from nginx proxy acting act as gateway (= Easy Round robin DNS tube.copylaradio.com is dynamic IP swap swarm nodes from node performance...)
- fi
- # ln -s /$HOME/.zen/astrXbian/www /var/www/astrxbian
- # Testez vos application à même la blockchain en la copiant dans ~/.zen/ipfs/.${IPFSNODEID}/KEY/${mediakey}/${G1PUB}/go/
- # Proposez de l'ajouter au dépot des applications web2.0 dans ../www/
-
-########################################################################
- # EXAMPLE TO ACTIVATE SECURITY : FORCE SIGNATURE VERIFICATION for each sensible file
-########################################################################
- echo "~/.zen/ipfs/.${IPFSNODEID}/KEY/${mediakey}/${G1PUB}/.views.counter"
- if [[ ! -f ~/.zen/ipfs/.${IPFSNODEID}/KEY/${mediakey}/${G1PUB}/.views.counter.sign ]]; then
- echo "0" > ~/.zen/ipfs/.${IPFSNODEID}/KEY/${mediakey}/${G1PUB}/.views.counter
- $MY_PATH/tools/natools.py sign -f pubsec -k "$HOME/.zen/secret.dunikey" -i ~/.zen/ipfs/.${IPFSNODEID}/KEY/${mediakey}/${G1PUB}/.views.counter -o ~/.zen/ipfs/.${IPFSNODEID}/KEY/${mediakey}/${G1PUB}/.views.counter.sign
- fi
-
- $MY_PATH/tools/natools.py verify -p "${G1PUB}" -i "$HOME/.zen/ipfs/.${IPFSNODEID}/KEY/${mediakey}/${G1PUB}/.views.counter.sign" -o "/tmp/verified_msg" && echo "c'est bon" || echo "c'est pas bon"
- # Each time a station modify .views.counter it signs, log and timestamp then publish new IPNS to swarm.
- # If a "faulty" blockchain appears (Mediakey collision)...
- # Message are sent to warn friends they have to manualy validate data conflict and merge back their mutual chain.
-
-########################################################################
-## CHAIN & IPNS REFRESH
-########################################################################
- # ipfs nanochain progression
- I=$(ipfs add -qrH ~/.zen/ipfs/.${IPFSNODEID}/KEY/${mediakey}/ | tail -n 1)
- echo "CHAIN: $I"
- OLDCHAIN=$(cat ~/.zen/ipfs/.${IPFSNODEID}/KEY/${mediakey}/.chain)
- echo "OLDCHAIN: $OLDCHAIN"
- if [[ "$OLDCHAIN" != "$I" ]] # MODIFY CHAIN only if something was changed
- then
- echo "UPDATING CHAIN"
- echo "$(date -u +%s%N | cut -b1-13)" > ~/.zen/ipfs/.${IPFSNODEID}/KEY/${mediakey}/.timestamp
- echo $I > ~/.zen/ipfs/.${IPFSNODEID}/KEY/${mediakey}/.chain
- fi
- echo "${mediakey} NAME PUBLISHING "
- # KEY ZenTag IPNS name publish
- J=$(ipfs name publish --quieter -k ${mediakey} /ipfs/${I})
-
- echo "$id REFRESHED ${I}
- https://tube.copylaradio.com/ipns/$J
- http://127.0.0.1:8080/ipns/$J"
-########################################################################
-########################################################################
- break ## ONE BY ONE (cron_MINUTE.sh task every 7 mn)
-done
-
-########################################################################
-########################################################################
-## TAKE CARE OF PIN CREATED THROUGH autoPINfriends.sh
-## Then refresh MEDIAKEY IPNS/IPFS RELATION
-## CORRECT ISSUE : https://git.p2p.legal/axiom-team/astrXbian/issues/25
-########################################################################
-for ipnslink in $(ls ~/.zen/PIN/*/IPNSLINK 2>/dev/null | shuf ); do
- ipnsid=$(cat $ipnslink)
- ipfsid=$(echo $ipnslink | cut -d '/' -f 6)
- mediakey=$(cat ~/.zen/PIN/${ipfsid}/MEDIAKEY)
-
-# [[ ! $(echo "${mediakey}" | grep "TMDB_") ]] && continue ## REFRESH ONLY TMDB (level 1), youtube is level 0
-
- [[ ! $(ipfs key list | grep ${mediakey}) ]] && echo "ERROR MISSING MEDIAKEY" && continue
-
- ## GET ACTUAL IPNS .chain VALUE
- mkdir -p /tmp/${mediakey}
- echo "${mediakey} GET IPNS"
- ipfs get -o /tmp/${mediakey} /ipns/$ipnsid
- [ $? -ne 0 ] && continue
- [ ! -s /tmp/${mediakey}/index.html ] && continue ## DO NOT REPUBLISH empty index.html
-
- ## REFRESH MORE THAN 6 HOURS TIMESTAMP KEY
- TIMESTAMP=$(cat /tmp/${mediakey}/.timestamp 2>/dev/null) # LAST REFRESH
- [[ ! $TIMESTAMP ]] && TIMESTAMP=$(cat /tmp/${mediakey}/*/.timestamp 2>/dev/null | tail -n 1 ) # INITIAL TIMESTAMP
- timestamp=$(date -u +%s%N | cut -b1-13)
- STAMPDIFF=$((timestamp - TIMESTAMP))
- echo "Last Update : $(date -d @$TIMESTAMP | cut -b1-10)" # remove millisecond part
- echo "PIN WAS LAST UPDATED $STAMPDIFF milliseconds AGO"
- [ $STAMPDIFF -lt 39600000 ] && continue # 11h = 39600000 ms / 12h = 43200000 ms
-
- echo "Refresh MEDIAKEY PIN"
- NEWIPFS=$(ipfs add -rHq /tmp/${mediakey}/ | tail -n 1)
-
- ## PUBLISH IT
- ipfs name publish -k ${mediakey} --quieter /ipfs/$NEWIPFS
-
- echo "$id PIN PUBLISH REFRESHED /ipfs/$NEWIPFS
- https://tube.copylaradio.com/ipns/$ipnsid
- http://127.0.0.1:8080/ipns/$ipnsid"
-
- rm -Rf /tmp/${mediakey}
-
- break ## DO ONE BY ONE
-done
-
-########################################################################
diff --git a/images/g1magicien.gif b/images/g1magicien.gif
new file mode 100644
index 00000000..c6f22e21
Binary files /dev/null and b/images/g1magicien.gif differ
diff --git a/install_astroport.sh b/install_astroport.sh
new file mode 100644
index 00000000..215d8cb3
--- /dev/null
+++ b/install_astroport.sh
@@ -0,0 +1,257 @@
+#!/bin/bash
+########################################################################
+{ # this ensures the entire script is downloaded #
+MY_PATH="`dirname \"$0\"`" # relative
+MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
+ME="${0##*/}"
+
+# CHECK not root user !!
+if [ "$EUID" -eq 0 ]
+ then echo -e "DO NOT EXECUTE AS root. Choose a user for your Astroport Station (we like pi)"
+ exit 1
+else echo -e "OK $USER, let's go!";
+fi
+
+echo "Hello,
+
+This script (you could read and modify as it is open source software) is about to transform your computer into an astroport station.
+
+This process involve different upgrades to be made on your system.
+1. install IPFS, the interplanetary file system (https://ipfs.io)
+2. install python cryptographic libraries to run natools, your key wizard companion
+3. download 'astroport' code release you have choosen.
+
+~/.zen directory and datastructure will emerge
+~/.zen/ipfs & ~/.zen/ipfs_swarm contains all meshed media index from you and your friends.
+
+ASTROPORT is activated by cron every minute it maintains the connection with your friends.
+It is the vessel that gives you avvess to your p2p AVATAR.
+You carry and share your data around your friends through a confidence network
+established through 1 to 5 'hearts' exchanged, opening 5 stargates where any can push/pull data.
+
+TODO
+Just indicate which is the directory assigned to each star.
+Then any of your friends from such star level can replicate (modify) those data with you.
+
+Your station is publishing its index every time it changes and every 6 hours for all MEDIAKEY from PIN station.
+Following that principle add new directory into ~/.zen/ipfs and index any dataset, it will be published on your IPFS semaphore.
+
+Now you need to enter your password to obtain sudo access.
+Please.
+"
+# Ask user password on start
+sudo true
+
+## Error funciton
+err() {
+ echo -e "ERREUR: $1"
+ exit 1
+}
+
+# CHECK if daemon is already running
+if [[ $(ps auxf --sort=+utime | grep -w ipfs | grep -v -E 'color=auto|grep' | tail -n 1 | cut -d " " -f 1) ]]; then
+ ipfs id && echo "ipfs swarm peers: " && ipfs swarm peers
+ echo "ipfs bootstrap list: " && ipfs bootstrap list
+ echo "ipfs daemon already running...! Must STOP ipfs AND remove ~/.ipfs to install again !!"
+ echo "Please RUN : sudo service ipfs stop"
+ exit 1
+fi
+
+[[ -d ~/.ipfs ]] && echo "IPFS install exist! Please remove or backup before executing this script EXIT" && exit 1
+
+echo -e "Check and install python curl, git and tools."
+
+[[ $(which pip3) ]] && python3 -m pip install -U pip && python3 -m pip install -U wheel cryptography Ed25519 base58 google protobuf duniterpy==0.62.0 termcolor python-dotenv gql==3.0.0a5 requests pybase64 || (echo "python3 pip3 is missing on your device. EXIT" && exit 1)
+[[ ! $(which curl) ]] && sudo apt-get install curl -y
+[[ ! $(which git) ]] && sudo apt-get install git -y
+
+[[ ! -d ~/.zen ]] && mkdir ~/.zen
+
+# CHECK node IP isLAN?
+myIP=$(hostname -I | awk '{print $1}')
+echo "Your IP is $myIP"
+isLAN=$(echo $myIP | grep -E "/(^127\.)|(^192\.168\.)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^::1$)|(^[fF][cCdD])/")
+[[ $isLAN ]] && echo "You are located in a LAN" || echo "You have a public IP address"
+MACHINE_TYPE=`uname -m`
+echo "You are running $MACHINE_TYPE CPU"
+
+echo "Downloading ipfs binaries"
+if [ ${MACHINE_TYPE} == 'x86_64' ]; then
+ curl -s https://dist.ipfs.io/ipfs-update/v1.6.0/ipfs-update_v1.6.0_linux-amd64.tar.gz -o $MY_PATH/ipfs-update.tar.gz
+elif [ ${MACHINE_TYPE:0:3} == 'arm' ]; then
+ curl -s https://dist.ipfs.io/ipfs-update/v1.6.0/ipfs-update_v1.6.0_linux-arm.tar.gz -o $MY_PATH/ipfs-update.tar.gz
+elif [ ${MACHINE_TYPE} == 'aarch64' ]; then
+ curl -s https://dist.ipfs.io/go-ipfs/v0.9.1/go-ipfs_v0.9.1_linux-arm64.tar.gz -o /tmp/ipfs_aarch64_v0.9.1.tar.gz
+else
+ echo "Your $MACHINE_TYPE is not supported yet... Please add an issue." && exit 1
+fi
+
+if [ -f $MY_PATH/ipfs-update.tar.gz ]; then
+ echo "INSTALL ipfs-update >>>>>>>>>>>>>>>>>>>>>>>>>>"
+ sudo tar -xvzf $MY_PATH/ipfs-update.tar.gz -C /usr/src/ || err "Untar ipfs-update"
+ rm $MY_PATH/ipfs-update.tar.gz
+ cd /usr/src/ipfs-update/
+ sudo ./install.sh || err "Install ipfs-update"
+ cd $MY_PATH
+
+ echo "INSTALL ipfs 0.9.1 >>>>>>>>>>>>>>>>>>>>>>>>>>"
+ sudo ipfs-update install 0.9.1 || err "Install IPFS"
+
+else
+ ## TERRAPI4 aarch64 install ipfs_aarch64_v0.9.1
+ echo "INSTALL ipfs 0.9.1 >>>>>>>>>>>>>>>>>>>>>>>>>> arm64"
+ sudo tar -xvzf /tmp/ipfs_aarch64_v0.9.1.tar.gz -C /usr/src/ || err "Untar ipfs_aarch64"
+ rm /tmp/ipfs_aarch64_v0.9.1.tar.gz
+ cd /usr/src/go-ipfs/
+ sudo ./install.sh || err "Install ipfs_aarch64"
+ cd $MY_PATH
+
+fi
+
+# INIT ipfs
+[[ $isLAN ]] && ipfs init -p lowpower \
+|| ipfs init -p server
+
+## Special Xbian init.d config
+ ## DEBIAN SYSTEMCTL
+ echo "SYSTEMD ipfs SERVICE >>>>>>>>>>>>>>>> ON"
+cat > /tmp/ipfs.service <>>>>>>>>>>>>>>>>> "
+# echo "Vous pouvez régler la ressouce CPU maximum (60%)?" && read cpuy
+
+ [[ -d ~/.ipfs ]] && sudo chown -R $USER:$USER ~/.ipfs
+ sudo systemctl daemon-reload
+ sudo systemctl enable ipfs
+
+
+###########################################
+echo "# ACTIVATE IPFS OPTIONS: #swarm0 INIT"
+###########################################
+### IMPORTANT !!!!!!! IMPORTANT !!!!!!
+###########################################
+# DHT PUBSUB mode
+ipfs config Pubsub.Router gossipsub
+# MAXSTORAGE = 1/2 available
+availableDiskSize=$(df -P ~/ | awk 'NR>1{sum+=$4}END{print sum}')
+diskSize="$((availableDiskSize / 2))"
+ipfs config Datastore.StorageMax $diskSize
+## Activate Rapid "ipfs p2p"
+ipfs config --json Experimental.Libp2pStreamMounting true
+ipfs config --json Experimental.P2pHttpProxy true
+ipfs config --json Swarm.ConnMgr.LowWater 50
+ipfs config --json Swarm.ConnMgr.HighWater 100
+
+## Install gateway on 8181 port
+ipfs config Addresses.Gateway "/ip4/127.0.0.1/tcp/8181"
+
+########################################################################
+# GET IPFS KEYS & CONVERSIONS
+########################################################################
+IPFSNODEID=$(ipfs config Identity.PeerID)
+## TODO convert to secret.dunikey
+
+########################################################################
+echo "CREATION IDENTITE BALISE IPFS ~/.zen/ipfs/.${IPFSNODEID} /G1SSB"
+########################################################################
+rm -Rf ~/.zen/ipfs
+mkdir -p ~/.zen/ipfs/.${IPFSNODEID}/G1SSB
+########################################################################
+# Give $XZUID to your (gchange friends)
+########################################################################
+XZUID="$(hostname)-$RANDOM$RANDOM"
+echo "SETTING .player PROFILE NAME = $XZUID"
+echo "$XZUID" > ~/.zen/ipfs/.${IPFSNODEID}/.player
+echo 'balise /ipns/$IPFSNODEID/.$IPFSNODEID/.player'
+
+########################################################################
+########################################################################
+echo "Getting tryme.addr & .mycode from OASIS
+-- Change oasis address to fork your Astroport Code Universe --"
+########################################################################
+ipfs bootstrap rm --all
+
+OASIS=12D3KooWBYme2BsNUrtx4mEdNX6Yioa9AV7opWzQp6nrPs6ZKabN
+# aries=12D3KooWSQYTxeoZZ39SNosEKxi7RUdGTtAQAqpKeZJxjzqqrZTx
+for bootnode in $(curl -s https://tube.copylaradio.com/ipns/$OASIS/.$OASIS/tryme.addr)
+do
+ ## ADD $bootnode TO BOOTSTRAP
+ ipfs bootstrap add $bootnode
+done
+
+codesign=$(curl -s https://tube.copylaradio.com/ipns/$OASIS/.$OASIS/.mycode)
+
+## ADD NETWORK EXPLORATION FROM LIKES
+########################################################################
+echo "RESTARTING ipfs"
+########################################################################
+sudo service ipfs restart
+echo ".... WAIT for SWARM to connect ..."
+sleep 10
+
+echo ".... ACTUAL SWARM PEERS ..."
+ipfs swarm peers
+
+echo "IPFS DONE
+====================
+Station Astroport INSTALL
+Activation ~/.zen/astrXbian/zen/cron_VRFY.sh
+Récupération CODE /ipfs/$codesign
+"
+
+## GETTING SAME SOURCE CODE AS OASIS
+mkdir -p /home/$USER/.zen/astrXbian/
+ipfs get --output=/home/$USER/.zen/astrXbian/ /ipfs/$codesign
+
+## Make scripts executable
+find /home/$USER/.zen/astrXbian/ -name "*.sh" -exec chmod u+x '{}' \;
+find /home/$USER/.zen/astrXbian/ -name "*.py" -exec chmod u+x '{}' \;
+
+########################################################################
+echo "# Setting $USER SUDO permissions ON fail2ban mount umount apt-get apt systemctl"
+########################################################################
+## USED FOR fail2ban-client (DEFCON)
+echo "$USER ALL=(ALL) NOPASSWD:/usr/bin/fail2ban-client" | (sudo su -c 'EDITOR="tee" visudo -f /etc/sudoers.d/fail2ban-client')
+## USED FOR RAMDISK (video live streaming)
+echo "$USER ALL=(ALL) NOPASSWD:/bin/mount" | (sudo su -c 'EDITOR="tee" visudo -f /etc/sudoers.d/mount')
+echo "$USER ALL=(ALL) NOPASSWD:/bin/umount" | (sudo su -c 'EDITOR="tee" visudo -f /etc/sudoers.d/umount')
+## USED FOR SYSTEM UPGRADE
+echo "$USER ALL=(ALL) NOPASSWD:/usr/bin/apt-get" | (sudo su -c 'EDITOR="tee" visudo -f /etc/sudoers.d/apt-get')
+echo "$USER ALL=(ALL) NOPASSWD:/usr/bin/apt" | (sudo su -c 'EDITOR="tee" visudo -f /etc/sudoers.d/apt')
+## USED FOR "systemctl restart ipfs"
+echo "$USER ALL=(ALL) NOPASSWD:/bin/systemctl" | (sudo su -c 'EDITOR="tee" visudo -f /etc/sudoers.d/systemctl')
+
+## TODO G1SSB CONFIG
+echo "## INSTALL TiddlyWiki /ipns/${IPFSNODEID}/.${IPFSNODEID}/index.html"
+[[ ! -f ~/.zen/ipfs/.${IPFSNODEID}/index.html ]] && mkdir -p ~/.zen/ipfs/.${IPFSNODEID} && cp ~/.zen/astrXbian/.install/templates/tiddlywiki/index.html ~/.zen/ipfs/.${IPFSNODEID}/index.html
+
+
+echo "Congratulation ! You are part of the astroport interplanetary fleet.
+
+New. Activate your station offline storage.
+Install ipfs companion : https://docs.ipfs.io/install/ipfs-companion/
+FR : https://translate.google.com/translate?sl=auto&tl=fr&u=https://docs.ipfs.io/install/ipfs-companion/
+"
+
+echo "FIND AND CONNECT WITH YOUR FRIENDS
+https://tube.copylaradio.com/ipns/$OASIS/.$OASIS/"
+## OPEN https://translate.google.com/translate?sl=auto&tl=fr&u=https://docs.ipfs.io/install/ipfs-companion/
+
+} # this ensures the entire script is downloaded #
+# IPFS CONFIG documentation: https://github.com/ipfs/go-ipfs/blob/master/docs/config.md#addressesswarm
diff --git a/tools/G1Barre4Player.sh b/tools/G1Barre4Player.sh
new file mode 100644
index 00000000..9c8790a3
--- /dev/null
+++ b/tools/G1Barre4Player.sh
@@ -0,0 +1,100 @@
+#!/bin/bash
+########################################################################
+# Author: Fred (support@qo-op.com)
+# Version: 1.0
+# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
+########################################################################
+PLAYER="$1"
+[[ $PLAYER == "" ]] && PLAYER=$(cat ~/.zen/game/players/.current/.player 2>/dev/null)
+
+
+##########################
+# Generate G1BARRE for each wish
+for g1wish in $(ls ~/.zen/game/players/$PLAYER/voeux/); do
+ wishname=$(cat ~/.zen/game/players/$PLAYER/voeux/$g1wish/.title)
+ wishns=$(ipfs key list -l | grep $g1wish | cut -d ' ' -f1)
+
+ echo "MISE A JOUR G1BARRE pour VOEU $wishname : "
+ echo "G1WALLET $g1wish"
+ echo "G1VOEUTW /ipns/$wishns"
+
+ # Create last g1barre
+ G1BARRE="https://g1sms.fr/g1barre/image.php?pubkey=$g1wish&target=1000&title=$wishname&node=g1.duniter.org&start_date=2022-08-01&display_pubkey=true&display_qrcode=true&progress_color=ff07a4"
+ echo "curl -m 12 -o ~/.zen/tmp/g1barre.png $G1BARRE"
+ rm -f ~/.zen/tmp/g1barre.png
+ curl -m 12 -so ~/.zen/tmp/g1barre.png "$G1BARRE"
+ # Verify file exists & non/empy before copy new version in "world/$g1wish"
+ [[ ! -s ~/.zen/tmp/g1barre.png ]] && echo "No Image ! ERROR. PLEASE VERIFY NETWORK LOCATION FOR G1BARRE" && continue
+ DIFF=$(diff ~/.zen/tmp/g1barre.png ~/.zen/game/world/$g1wish/g1barre.png)
+ [[ $DIFF ]] && cp ~/.zen/tmp/g1barre.png ~/.zen/game/world/$g1wish/g1barre.png
+ ##################################################################"
+ OLDIG1BAR=$(cat ~/.zen/game/world/$g1wish/.ig1barre)
+
+ BAL=$($MY_PATH/../tools/jaklis/jaklis.py balance -p $g1wish )
+ echo "MONTANT (G1) $BAL"
+ ##################################################################"
+ IG1BAR=$(ipfs add -Hq ~/.zen/game/world/$g1wish/g1barre.png | tail -n 1)
+ if [[ $OLDIG1BAR != "" && $OLDIG1BAR != $IG1BAR ]]; then # Update
+ echo "NEW VALUE !! Updating G1VOEU Tiddler /ipfs/$IG1BAR"
+
+ ## Replace IG1BAR "in TW" ipfs value (hash unicity is cool !!)
+ sed -i "s~${OLDIG1BAR}~${IG1BAR}~g" ~/.zen/game/players/$PLAYER/ipfs/moa/index.html
+ echo $IG1BAR > ~/.zen/game/world/$g1wish/.ig1barre
+ echo "Update new g1barre: /ipfs/$IG1BAR"
+
+ MOATS=$(date -u +"%Y%m%d%H%M%S%4N")
+ echo "Avancement blockchain TW $PLAYER : $MOATS"
+ cp ~/.zen/game/players/$PLAYER/ipfs/moa/.chain ~/.zen/game/players/$PLAYER/ipfs/moa/.chain.$MOATS
+
+ TW=$(ipfs add -Hq ~/.zen/game/players/$PLAYER/ipfs/moa/index.html | tail -n 1)
+ echo "ipfs name publish --key=$PLAYER /ipfs/$TW"
+ ipfs name publish --allow-offline --key=$PLAYER /ipfs/$TW
+
+ # MAJ CACHE TW $PLAYER
+ echo $TW > ~/.zen/game/players/$PLAYER/ipfs/moa/.chain
+ echo $MOATS > ~/.zen/game/players/$PLAYER/ipfs/moa/.moats
+ echo "##################################################################"
+ ##################################################################
+
+ fi
+
+ ### NO OLDIG1BAR, MEANS FIRST RUN
+ if [[ $OLDIG1BAR == "" ]]; then # CREATE Tiddler
+
+ TEXT="
"${wishname}""
+
+ # NEW G1BAR TIDDLER
+ echo "## Creation json tiddler : G1${wishname} /ipfs/${IG1BAR}"
+ echo '[
+ {
+ "title": "'G1${wishname}'",
+ "type": "'text/vnd.tiddlywiki'",
+ "ipns": "'/ipns/$wishns'",
+ "ipfs": "'/ipfs/$IG1BAR'",
+ "player": "'/ipfs/$PLAYER'",
+ "text": "'$TEXT'",
+ "tags": "'g1voeu g1${wishname} $PLAYER'"
+ }
+ ]
+ ' > ~/.zen/tmp/g1${wishname}.bank.json
+
+ rm -f ~/.zen/tmp/newindex.html
+
+ echo "Nouveau G1${wishname} : http://127.0.0.1:8080/ipns/$ASTRONAUTENS"
+ tiddlywiki --load ~/.zen/game/players/$PLAYER/ipfs/moa/index.html \
+ --import ~/.zen/tmp/g1${wishname}.bank.json "application/json" \
+ --output ~/.zen/tmp --render "$:/core/save/all" "newindex.html" "text/plain"
+
+ echo "PLAYER TW Update..."
+ if [[ -s ~/.zen/tmp/newindex.html ]]; then
+ echo "Mise à jour ~/.zen/game/players/$PLAYER/ipfs/moa/index.html"
+ cp -f ~/.zen/tmp/newindex.html ~/.zen/game/players/$PLAYER/ipfs/moa/index.html
+ fi
+
+ echo $IG1BAR > ~/.zen/game/world/$g1wish/.ig1barre
+
+ fi
+
+done
+ ##############################################################
+ ##############################################################
diff --git a/tools/gchange2tw.sh b/tools/gchange2tw.sh
new file mode 100644
index 00000000..c0e3b068
--- /dev/null
+++ b/tools/gchange2tw.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+########################################################################
+# Version: 0.1
+# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
+########################################################################
+MY_PATH="`dirname \"$0\"`" # relative
+MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
+ME="${0##*/}"
+
+####################################
+#### HERE WE SCAN G1PUB GCHANGE ENV ####
+# PART OF TW SYNCHRONIZATION #
+####################################
+G1PUB="$1"
+
+## CHECK FOR KEY AVAILABLE
+g1pubpath=$(grep $G1PUB ~/.zen/game/players/*/.g1pub | cut -d ':' -f 1 2>/dev/null)
+PLAYER=$(echo "$g1pubpath" | rev | cut -d '/' -f 2 | rev 2>/dev/null)
+[[ !$PLAYER ]] && echo "NO Astronaut Key Found. Please use 12345.sh to activate your ID on this gateway." && exit 1
+ASTRONAUTENS=$(ipfs key list -l | grep -w "$PLAYER" | cut -d ' ' -f 1)
+
+## Getting Gchange liking_me list
+~/.zen/Astroport.ONE/tools/timeout.sh -t 20 ~/.zen/Astroport.ONE/tools/jaklis/jaklis.py -k ~/.zen/game/players/$PLAYER/secret.dunikey -n "https://data.gchange.fr" stars | jq -r '.likes[].issuer' | uniq > ~/.zen/tmp/liking_me
+
+