#!/bin/bash ######################################################################## # Author: Fred (support@qo-op.com) # Version: 2020.03.18 # 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##*/}" echo ' ######################################################################## # \\/// # qo-op ############# '$ME' creates ZenTag (+ Passenger)' ZEN="$1" # Zen amount ZENSOURCE="$2" # G1 TX HASH OR PASSENGER timestamp ~/.zen/miam/timestamp/ PASSENGER="$3" # ~/.zen/miam/timestamp/src_id.ext in ZenTag (add to IPFS datastructure) METADATA="$4" READ="$5" # Zen amount asked to allow passenger reading PARK="$6" # Zen amount payed for IPFS PIN by passenger everyday # Add any "parameters" needed by CONTRACT.sh echo " ######################################################################## # $MY_PATH/$ME $ZEN $ZENSOURCE $PASSENGER $READ $PARK $METADATA # IPFS DATASTRUCTURE ~/.zen/tag/sha256sum(_tag.uid) ######################################################################## # [ASTROPORT](https://astroport.com) ########################################################################" # If PASSENGER file, then must provide METADATA! [[ $PASSENGER != "" ]] && [[ $METADATA == "" ]] && echo "ERROR PASSENGER needs METADATA !!! Please verify and correct..." && exit 1 [[ $READ == "" ]] && READ=1 [[ $PARK == "" ]] && PARK=10 ############################################## # NODE ENVIRONEMENT DETECTION ############################################## IPFSNODEID=$(ipfs id -f='\n') [[ ! -f ~/.ssb/secret.dunikey ]] && $MY_PATH/tools/secret2dunikey.sh G1PUB=$(cat ~/.ssb/secret.dunikey | grep 'pub:' | cut -d ' ' -f 2) echo "G1SSB Wallet: $G1PUB IPFS: $IPFSNODEID __ __ _ _ _______ _______ _ __ | \/ | / \ | |/ / ____| |_ / _ \ '_ \ | |\/| | / _ \ | ' /| _| / / __/ | | | | | | |/ ___ \| . \| |___ /___\___|_| |_| |_| |_/_/ \_\_|\_\_____| " ######################################################################## # ZenTag is an IPFS/IPNS datastructure shared into IPFS, publish # ~~~ Draft ~~~~ Draft ~~~~ Draft ~~~~ Draft ~~~~ Draft ~~~~ # _chain # ZenTag IPFS Hash # _chain.n # Sequence Number # _chain.nanodate # Current nanodate # _chain.prev # Previous IPFS Hash # _g1.node.creator # G1SSB wallet pubkey # _tag.issuer # G1TX ISSUER pubkey # _tag.zensource # G1TX HASH or SSB timestamp # _ipfs.node.creatorcat # NODE IPFS ID # _ipfs.publishkey.BB.aes # BB SYMcypher of IPNS publish key # _ipfs.publishkey.crypt # G1SSB ASYMcypher of IPNS publish key # _tag.BB.sha # BB sha256sum # _tag.uid # ZenTag UID # _tag.zen # ZentTag balance # _ipns # /ipns/ address # PASSENGER FILE (put to IPFS and cypher link in IPNS ZenTag) # _passenger.filename # Passenger filename # _passenger.ipfs.crypt # G1SSB cyphered IPFS Passenger link # _passenger.read # Zen value asked for READING # _passenger.park # Zen value paid for PARKING # Only if contract executed => add new cyphered links # _passenger.contract.sh # Zen CONTRACT TODO # COmpare with code to verify and extend Draft # TODO: Could be converted into yaml or json if you like... ######################################################################## #TAG IS MANAGED BY NODE KEY OR BB KEY to change IPNS latest status #INDEX UPDATE ON CURRENT NODE IPFS SWARM CHANNEL [[ $ZEN == "" || $ZENSOURCE == "" ]] && echo "ERROR... Please provide Zen value" && exit 1 if [[ "$METADATA" == "" ]]; then echo " # LOVE BANK - PrePaid Card ZenTag # FULLY BACKED ON IRL G1 LIBRE MONEY (https://cesium.app) # ____ ____ _____ _____ _ _ # / ___| _ \| ____| ____| \ | | _______ _ __ # | | _| |_) | _| | _| | \| | |_ / _ \ '_ \ # | |_| | _ <| |___| |___| |\ | / / __/ | | | # \____|_| \_\_____|_____|_| \_| /___\___|_| |_| # " # COMMENT WILL BREAK (G1 <=> ZEN) STRICT RELATION [[ ! -f ~/.zen/cache/g1_TX_inputs/zen.$ZENSOURCE ]] && echo "ERROR# UNKNOWN ~/.zen/cache/g1_TX_inputs/zen.$ZENSOURCE !!" && exit 1 ISSUER=$(cat ~/.zen/cache/g1_TX_inputs/zen.$ZENSOURCE) [[ $ISSUER == "" ]] && echo "ERROR# NO ISSUER FOUND FOR TX $ZENSOURCE !!" && exit 1 echo "ISSUER = $ISSUER SENT TX $ZENSOURCE !!" else echo " _|_ o ._ _ _ _ _|_ _. ._ _ ._ |_ | | | | (/_ _> |_ (_| | | | |_) | SSB PASSENGER ~/.zen/miam/$ZENSOURCE " [[ ! -d ~/.zen/miam/$ZENSOURCE ]] && echo "ERROR# UNKNOWN ~/.zen/miam/$ZENSOURCE !!" && exit 1 ISSUER=$(cat ~/.zen/miam/$ZENSOURCE/msg_key) [[ $ISSUER == "" ]] && echo "ERROR# NO ISSUER FOUND FOR miam $ZENSOURCE !!" && exit 1 echo "ISSUER = SSB Message $ISSUER !!" fi ######################################################################## # CREATE ZEN TAG ######################################################################## # Produce unique 6 words diceware to give a name _tag.uid AA=$(echo $($MY_PATH/tools/diceware.sh 6 | xargs) | sed s/\ /_/g ) # ZenTag Name = Diceware_6_words AAH=$(echo -n ${AA} | sha256sum | cut -d ' ' -f 1) # ZenTag Name SHA256 # TODO ACTIVATE SWARM UNICITY CHECK # Create Unique Zentag for all IPFS SWARM! while [[ $(grep -Rwl "$AA" ~/.zen/ipfs_swarm/.12D3KooW*/TAG/*/_tag.uid) ]]; do AA=$(echo $($MY_PATH/tools/diceware.sh 6 | xargs) | sed s/\ /_/g ) AAH=$(echo -n ${AA} | sha256sum | cut -d ' ' -f 1) done # BB key is a 4 word diceware printed on QRCode for Human use. # SHA256 PASSWORD CHECK FOR ALLOWING WRITE ACTION BB=$($MY_PATH/tools/diceware.sh 4 | xargs); BBH=$(echo -n "$BB" | sha256sum | cut -d ' ' -f 1) ######################################################################## # INITIAL DATA STRUCTURE ######################################################################## mkdir -p ~/.zen/tag/${AAH} # LOG echo " _____ _____ _ ____ |__ /___ _ _|_ _|/ \ / ___| __/\__ / // _ \ °_ \| | / _ \| | _ \ / / /| __/ | | | |/ ___ \ |_| | /_ _\ /____\___|_| |_|_/_/ \_\____| \/ ******************************************************* | $AA | $ZEN Zen ******************************************************* CREATING ~/.zen/tag/${AAH}/ " # COPY ZENTAG TO LOCAL ~/.zen/tag echo "$AA" > ~/.zen/tag/${AAH}/_tag.uid # Nom du ZenTAG echo "$ZEN" > ~/.zen/tag/${AAH}/_tag.zen # Tag ZEN amount echo "${IPFSNODEID}" > ~/.zen/tag/${AAH}/_ipfs.node.creator # NODE IPFS ID echo "$ZENSOURCE" > ~/.zen/tag/${AAH}/_tag.zensource # ZENSOURCE echo "$G1PUB" > ~/.zen/tag/${AAH}/_g1.node.creator # CREATOR IPFS NODE G1PUBKEY echo "$ISSUER" > ~/.zen/tag/${AAH}/_tag.issuer # TX ISSUER G1PUBKEY OR SSB_MESSAGE ID ######################################################################## # Create IPNS publishing key ${AA}.key # ===================================== # BB encrypted version for IRL use # G1PUB for current G1SSB Node later access... # Using sha256sum / openssl / natools.py (libsodium) ######################################################################## #timestamp=$(date -u +%s%N | cut -b1-13) keyname="${ZENSOURCE}_${AA}.key" [[ ! $(ipfs key list | grep -F ${AA}.key) ]] && J0=$(ipfs key gen -t rsa -s 2048 $keyname) # WRITE BBH for QRCode BB verification echo "$BBH" > ~/.zen/tag/${AAH}/_tag.BB.sha # BB pgp symetric publishkey keyfilename=$(ls ~/.ipfs/keystore/ | tail -n 1) openssl aes-256-cbc -pbkdf2 -k "$BB" -salt -in ~/.ipfs/keystore/${keyfilename} -out ~/.zen/tag/${AAH}/_ipfs.publishkey.BB.aes # GIVE IPFS CREATOR NODE ACCESS TO ZEN TAG $MY_PATH/tools/natools.py encrypt -p $G1PUB -i ~/.ipfs/keystore/${keyfilename} -o ~/.zen/tag/${AAH}/_ipfs.publishkey.crypt # LOG echo " ${AA}.key CYPHERING PUBLISH KEY __ _ _/_/ __/|_ __/|_ | | / / | / | / / / / / /_ __| /_ __| / / / / |/ |/ _/_/ |_| /_/ KEY : $BB BBH : $BBH " ####################################################################### # PASSENGER FILE is added to IPFS (then link is cyphered: NO!) # https://beechat.network/how-beechats-encryption-works/ # SECURITY IS OBSOLETE AS WE ARE SHARING COPY WITH FRIENDS ;) # ACTIVATE ZEN CONTRACT... 100 readers impresari # LOVE ECONOMY IS FREE. EVERYBODY IS DONATING TO THE OTHERS NOW. # INCOME != MONEY FORGE (Realtive Moey Theory applies HERE) # CODE WILL BE CERTIFIED AS IPFS HASH. if [[ -f $PASSENGER ]]; then echo " _ _ _ _ _ _ _ _ _ / \ / \ / \ / \ / \ / \ / \ / \ / \ ( p | a | s | s | e | n | g | e | r ) \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ " # SEARCH FOR SAME SOURCE in IPFS... Not to make it twice... CHECKSWARM=$(grep -Rwl "$ZENSOURCE" ~/.zen/ipfs_swarm/.12D3KooW*/TAG/*/_tag.zensource | tail -n 1 | cut -f 6 -d '/') [[ $CHECKSWARM == "" ]] && CHECKSWARM=$(grep -Rwl "$ZENSOURCE" ~/.zen/ipfs/.$IPFSNODEID/TAG/*/_tag.zensource | tail -n 1 | cut -f 6 -d '/') [[ -s ~/.zen/ipfs/.$IPFSNODEID/TAG/$ZENSOURCE/_tag.issuer ]] && ISSUERSWARM=$(cat ~/.zen/ipfs/.$IPFSNODEID/TAG/$ZENSOURCE/_tag.issuer) [[ "$CHECKSWARM" != "" && "$ISSUERSWARM" == "$ISSUER" ]] && ipfs key rm $keyname && rm -Rf ~/.zen/tag/${AAH} \ && echo "$ZENSOURCE ALREADY COPIED IN IPFS SWARM. $CHECKSWARM CANCEL" && exit 1 # NO DUPLICATE echo "ADDING TO IPFS.................$(date)" # ADD PASSENGER TO IPFS # COULD BE SUPER LONG !!! IPASSENGER=$(ipfs add -q "$PASSENGER" -w | tail -n 1) # TODO COMPARE DISK WRITING SPEED AND AVAILABLE SPACE TO CHOOSE BEST IN SWARM echo "$(date) ............... YES /ipfs/$IPASSENGER" echo "$IPASSENGER" > ~/.zen/tag/${AAH}/_passenger.ipfs # GET FILE NAME PASSENGERNAME=$(basename -- "$PASSENGER") echo "$PASSENGERNAME" > ~/.zen/tag/${AAH}/_passenger.filename # G1SSB NODE ACCESS $MY_PATH/tools/natools.py encrypt -p $G1PUB -i ~/.zen/tag/${AAH}/_passenger.ipfs -o ~/.zen/tag/${AAH}/_passenger.ipfs.crypt # BB OWNER ACCESS openssl aes-256-cbc -pbkdf2 -k "$BB" -salt -in ~/.zen/tag/${AAH}/_passenger.ipfs -out ~/.zen/tag/${AAH}/_passenger.ipfs.BB.aes # CLEAN CLEARTEXT IPFS link ? LATER MAYBE rm ~/.zen/tag/${AAH}/_passenger.ipfs # ZEN ECONOMY: ZEN READ payment + PARK rental echo "$READ" > ~/.zen/tag/${AAH}/_passenger.read echo "$PARK" > ~/.zen/tag/${AAH}/_passenger.park echo " _passenger.filename : $PASSENGERNAME _passenger.ipfs : $IPASSENGER http://127.0.0.1:8080/ipfs/$IPASSENGER/$PASSENGERNAME # #### ## ##### ###### ##### # # # # # # # # # # # # # # # # # ##### # # # # # ###### # # # # # # # # # # # # # # # ###### #### # # ##### ###### ##### ################################################################## # DECODE AND READ _passenger.ipfs with BB Passphrase ################################################################## openssl aes-256-cbc -pbkdf2 -k \"$BB\" -d -salt -in ~/.zen/tag/${AAH}/_passenger.ipfs.BB.aes -out /tmp/_passenger.ipfs ipfs get -o /tmp \"/ipfs/$IPASSENGER/$PASSENGERNAME\" && vlc \"/tmp/$PASSENGERNAME\" 2>/dev/null " cat > ~/.zen/tag/${AAH}/CONTRACT.sh < ~/.zen/tag/${AAH}/_chain.n # Tag modification number (0 first) NANODATE=$(date -u +%s%N) echo "$NANODATE" > ~/.zen/tag/${AAH}/_chain.nanodate # Nanodate notification I0=$(ipfs add -qr ~/.zen/tag/${AAH} | tail -n 1) echo "${I0}" > ~/.zen/tag/${AAH}/_chain # Double IPFS add for _chain INIT cp -f ~/.zen/tag/${AAH}/_chain ~/.zen/tag/${AAH}/_chain.prev I=$(ipfs add -qr ~/.zen/tag/${AAH} | tail -n 1) echo "${I}" > ~/.zen/tag/${AAH}/_chain echo " _|_ _.o._ (_| |(_||| | : $NANODATE J0=${J0} I0=${I0} I=${I} " # IPNS name publish J=$(ipfs name publish -k $keyname --quieter /ipfs/${I}) [[ ! ${J} ]] && echo "ipfs pin rm ${I}; ipfs pin rm ${I0}; rm -Rf ~/.zen/tag/${AAH}; ipfs key rm $keyname " [[ ! ${J} ]] && J=${J0} echo "${J}" > ~/.zen/tag/${AAH}/_ipns # INDEXING ZenTag into SWARM mkdir -p ~/.zen/ipfs/.$IPFSNODEID/TAG/${ZENSOURCE}/ echo "${AA}" > ~/.zen/ipfs/.$IPFSNODEID/TAG/${ZENSOURCE}/_tag.uid echo "${ZENSOURCE}" > ~/.zen/ipfs/.$IPFSNODEID/TAG/${ZENSOURCE}/_tag.zensource echo "${ISSUER}" > ~/.zen/ipfs/.$IPFSNODEID/TAG/${ZENSOURCE}/_tag.issuer echo "${J}" > ~/.zen/ipfs/.$IPFSNODEID/TAG/${ZENSOURCE}/_tag.ipns if [[ "${PASSENGERNAME}" != "" ]]; then echo "${PASSENGERNAME}" > ~/.zen/ipfs/.$IPFSNODEID/TAG/${ZENSOURCE}/_tag.passenger.filename # COPY METADATA!! TODO : Please Extend filesource FOR new metadata types. torrent ? extractor=$(cat "$METADATA" | jq -r '.extractor') youtubeid=$(cat "$METADATA" | jq -r '.id') fulltitle=$(cat "$METADATA" | jq -r '.fulltitle') echo "$fulltitle" > ~/.zen/ipfs/.$IPFSNODEID/TAG/${ZENSOURCE}/_tag.passenger.fulltitle # description=$(cat "$METADATA" | jq -r '.description') artist=$(cat "$METADATA" | jq -r '.artist') album=$(cat "$METADATA" | jq -r '.album') duration=$(cat "$METADATA" | jq -r '.duration') upload_date=$(cat "$METADATA" | jq -r '.upload_date') uploader_id=$(cat "$METADATA" | jq -r '.uploader_id') extractor=$(cat "$METADATA" | jq -r '.extractor') [[ ! -f ~/.zen/ipfs/.$IPFSNODEID/TAG/${ZENSOURCE}/_tag.passenger.metadata.${extractor}.json ]] \ && cp -f "${METADATA}" /tmp/ mv /tmp/${youtubeid}.info.json ~/.zen/ipfs/.$IPFSNODEID/TAG/${ZENSOURCE}/_tag.passenger.metadata.${extractor}.json fi ls ~/.zen/ipfs/.$IPFSNODEID/TAG/${ZENSOURCE}/ IWALLETS=$(ipfs add -rHq ~/.zen/ipfs | tail -n 1) NODEIPNS=$(ipfs name publish --quieter /ipfs/$IWALLETS) echo " _ ____ (_)___ / __/____ / / __ \/ /_/ ___/ / / /_/ / __(__ ) /_/ .___/_/ /____/ /_/ ipfs ls /ipfs/${I} ZenTAG : ipfs ls /ipns/${J} NODE index : ipfs ls /ipns/$IPFSNODEID/.$IPFSNODEID/TAG/${ZENSOURCE} " ######################################################################## # CREATE ZenTAG READ/WRITE QRCODES ### PRINTER IS HOOKED TO G1SSB NODE = G1DAB ######################################################################## echo " _ _ _ _ _ _ / \|_) / / \| \|_ \_X| \ \_\_/|_/|_ ................................. " # READ QRCODE qrencode -s 5 -o ~/.zen/tag/${AAH}/_QRCODE.read.png "RJ:${AA}#${J}" # WRITE QRCODE qrencode -s 5 -o ~/.zen/tag/${AAH}/_QRCODE.write.png "BJ:${BB}#${J}" ## TODO PROD REMOVE WRITE FILE echo "QRCodes CREATED !! See it : xviewer ~/.zen/tag/${AAH}/_QRCODE.read.png & xviewer ~/.zen/tag/${AAH}/_QRCODE.write.png & ${AA} " [[ $(which xviewer) ]] && xviewer ~/.zen/tag/${AAH}/_QRCODE.read.png & [[ $(which xviewer) ]] && xviewer ~/.zen/tag/${AAH}/_QRCODE.write.png & ######################################################################## # SBOT PUBLISH ######################################################################## if [[ "${PASSENGERNAME}" != "" ]]; then echo "$ISSUER" msg="$(sbotc get '{"id":"'"$ISSUER"'"}')" # echo "$msg" | jq #DEBUG [[ $msg == "" ]] && echo "ERROR No SSB message for PASSENGER (timestamp: $tstamp)" && exit 1 msg_root=$(printf %s "$msg" | jq -r .value.content.root) [[ $msg_root == "null" ]] && msg_root=$ISSUER msg_branch=$(printf %s "$msg" | jq -r .value.content.branch) [[ $msg_branch == "null" ]] && msg_branch=$ISSUER # ATTACH ~/.zen/miam/$ZENSOURCE/ssb_thumb.jpg name="ssb_thumb.jpg" id="$(sbotc blobs.add < ~/.zen/miam/$ZENSOURCE/ssb_thumb.jpg)" type="$(file -b --mime-type ~/.zen/miam/$ZENSOURCE/ssb_thumb.jpg)" size="$(wc -c < ~/.zen/miam/$ZENSOURCE/ssb_thumb.jpg)" export MESSAGE=$(cat << EOF [![ssb_thumb.jpg](${id})](http://127.0.0.1:8080/ipfs/$IPASSENGER/$PASSENGERNAME) :extractor:${extractor} :fulltitle:${fulltitle} :duration:${duration} :uploader_id:${uploader_id} [:pig:IPFS:pig_nose:](http://127.0.0.1:8080/ipfs/$IPASSENGER/$PASSENGERNAME) --- **ZEN=$ZEN($READ/$PARK)** [:flying_saucer:Essaim IPFS:sparkle:](http://127.0.0.1:8080/ipns/${J}/CONTRACT.sh) [:sunglasses:**ZenTAG**:heart:DEBUG:pager:](http://127.0.0.1:8080/ipns/$IPFSNODEID/.$IPFSNODEID/TAG/${ZENSOURCE}) #zenbot #astroport EOF ) echo " __ _ ____ (_ |_)/ \| __)|_)\_/| POST root: $msg_root branch: $msg_branch " echo "$MESSAGE" INLINE=$(node -p "JSON.stringify(process.env.MESSAGE)") ### TODO find sboyc text COMMA PROBLEM... Cannot send beautiful md formated SSB messages !!! # echo '{"type":"post", "branch": "'"$msg_branch"'", "root": "'"$msg_root"'", "text":"'"${INLINE}"'","mentions":[{"link":"'"$id"'","name":"'"$name"'","size":"'"$size"'","type":"'"$type"'"},{"link":"#zenbot"},{"link":"#astroport"}]}' sbotc publish '{"type":"post", "branch": "'"$msg_branch"'", "root": "'"$msg_root"'", "text":'${INLINE}',"mentions":[{"link":"'"$id"'","name":"'"$name"'","size":"'"$size"'","type":"'"$type"'"},{"link":"#zenbot"},{"link":"#astroport"}]}' else # This code is activated for qrcode (zentx terminal) @piniche # REGULAR ZenTAG, Send QRCode to INPUT TX emitter ### TODO PRINT AND SEND BY SSB WITH WHEN PASSENGER TOO # CAREFULL IN THAT CASE ISSUER IS A G1WALLET ssbid="@$(echo $ISSUER | base58 -d | base64).ed25519" file=~/.zen/tag/${AAH}/_QRCODE.read.png #recps='@f/6sQ6d2CMxRUhLpspgGIulDxDCwYD7DzFzPNr7u5AU=.ed25519 @5XaVcAJ5DklwuuIkjGz4lwm2rOnMHHovhNg7BFFnyJ8=.ed25519' recps="$ssbid" name=${file##*/} link="$(sblob encrypt "$file")" type="$(file -b --mime-type "$file")" id=${link%?unbox=*} key=${link#*?unbox=} size="$(sbotc -e blobs.size "$id")" recps_array="[$(for recp in $recps; do printf '"%s"\n' "$recp"; done | paste -sd,)]" sbotc private.publish '{"type":"post","text":"['"$name"']('"$link"')","mentions":[{"link":"'"$id"'","name":"'"$name"'","size":'"$size"',"type":"'"$type"'","query":{"unbox":"'"$key"'"}}],"recps":'"$recps_array"'}' "$recps_array" fi ######################################################################## exit 0