Compare commits

..

No commits in common. "master" and "master" have entirely different histories.

26 changed files with 312 additions and 1663 deletions

View File

@ -1,66 +1,23 @@
FROM debian@sha256:bf338ddc710dfb9b907a29ba661b35d0f6b3eae043515c4315f64c6e93409e94
LABEL MAINTAINER=chamalow <@qio8/4L4vnzq3qRD0dqKI7sTpey54u8ZWbaICfpJOZw=.ed25519>
ENV DEBIAN_FRONTEND noninteractive
ENV RUSTUP_HOME /usr/local/rustup
ENV CARGO_HOME /usr/local/cargo
ENV PATH /usr/local/cargo/bin:$PATH
ENV RUST_VERSION 1.42.0
ENV DEBIAN_FRONTEND noninteractive
COPY ./key_create_dunikey.py /usr/bin/key_create_dunikey
COPY ./find_ssb_user_G1_pubkey.sh /usr/bin/find_ssb_user_G1_pubkey
COPY ./tip.sh /usr/bin/tip
COPY ./process-likes-g1tx.sh /usr/bin/process-likes-g1tx
COPY ./secret2dunikey.sh /usr/bin/secret2dunikey
RUN apt-get update -y && \
apt-get install autoconf=2.69-11.1 build-essential=12.8 python3-pip=18.1-5 python3-setuptools=44.0.0-1 python3-wheel=0.33.6-3 libsodium-dev=1.0.18-1 jq=1.6-1 make=4.2.1-1.2 git=1:2.25.1-1 gcc=4:9.2.1-3.1 base58=1.0.3-1 libtool=2.4.6-14 curl=7.68.0-1 -y && \
chmod +x /usr/bin/secret2dunikey /usr/bin/key_create_dunikey /usr/bin/find_ssb_user_G1_pubkey /usr/bin/tip && \
apt-get install python3-pip=18.1-5 python3-setuptools=44.0.0-1 python3-wheel=0.33.6-2 libsodium-dev=1.0.18-1 jq=1.6-1 make=4.2.1-1.2 git=1:2.25.1-1 gcc=4:9.2.1-3.1 -y && \
chmod +x /usr/bin/secret2dunikey /usr/bin/process-likes-g1tx /usr/bin/key_create_dunikey&& \
pip3 install duniterpy==0.56.0 silkaj==0.7.6 && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* && \
useradd -ms /bin/bash astroport
RUN set -eux; \
dpkgArch="$(dpkg --print-architecture)"; \
case "${dpkgArch##*-}" in \
amd64) rustArch='x86_64-unknown-linux-gnu'; rustupSha256='ad1f8b5199b3b9e231472ed7aa08d2e5d1d539198a15c5b1e53c746aad81d27b' ;; \
armhf) rustArch='armv7-unknown-linux-gnueabihf'; rustupSha256='6c6c3789dabf12171c7f500e06d21d8004b5318a5083df8b0b02c0e5ef1d017b' ;; \
arm64) rustArch='aarch64-unknown-linux-gnu'; rustupSha256='26942c80234bac34b3c1352abbd9187d3e23b43dae3cf56a9f9c1ea8ee53076d' ;; \
i386) rustArch='i686-unknown-linux-gnu'; rustupSha256='27ae12bc294a34e566579deba3e066245d09b8871dc021ef45fc715dced05297' ;; \
*) echo >&2 "unsupported architecture: ${dpkgArch}"; exit 1 ;; \
esac; \
url="https://static.rust-lang.org/rustup/archive/1.21.1/${rustArch}/rustup-init"; \
curl -O "$url"; \
echo "${rustupSha256} *rustup-init" | sha256sum -c -; \
chmod +x rustup-init; \
./rustup-init -y --no-modify-path --profile minimal --default-toolchain $RUST_VERSION; \
rm rustup-init; \
chmod -R a+w $RUSTUP_HOME $CARGO_HOME; \
rustup --version; \
cargo --version; \
rustc --version;
RUN git clone https://git.scuttlebot.io/%25133ulDgs%2FoC1DXjoK04vDFy6DgVBB%2FZok15YJmuhD5Q%3D.sha256 sbotc
WORKDIR /sbotc
RUN make && make install
WORKDIR /
RUN git clone https://git.duniter.org/tools/dup-mnemonic-rs
WORKDIR /dup-mnemonic-rs
RUN cargo build --release && \
cp target/release/dup-mnemonic /usr/local/bin
COPY ./docker/docker-entrypoint.sh /home/astroport/
COPY ./samples /home/astroport/
RUN chmod +x /home/astroport/docker-entrypoint.sh
USER astroport
WORKDIR /home/astroport
RUN mkdir -p /home/astroport/.ssb/
VOLUME [ "/home/astroport/.ssb/" ]
EXPOSE 8008
ENTRYPOINT [ "/bin/bash" ]
CMD ["docker-entrypoint.sh"]
CMD ["process-likes-g1tx"]

BIN
doc/cesium-dunikey-800.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 MiB

BIN
doc/process-likes-g1tx.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 820 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

BIN
doc/ssb-g1like-logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 146 KiB

View File

@ -1,86 +0,0 @@
version: "3"
services:
redis:
image: redis
mongo:
image: mongo
volumes:
- mongo-data:/data
ohmyform:
image: ohmyform/ohmyform
#build: .
#volumes:
# - ".:/opt/app"
environment:
CREATE_ADMIN: "TRUE"
SOCKET_URL: 'localhost:5000'
SOCKET_PORT: "5000"
SOCKET_PORT_EXTERN_VISIBLE: "TRUE"
MONGODB_URI: mongodb://mongo/ohmyform
REDIS_URL: redis://redis
MAILER_SMTP_HOST: mail
MAILER_SMTP_PORT: 1025
# command: grunt dev # override command to have livereloading on file change
links:
- mongo
- redis
- mail
ports:
- "5000:5000"
depends_on:
- mongo
- redis
mail:
image: mailhog/mailhog
ports:
- "5050:8025"
mongoexpress:
image: mongo-express
environment:
ME_CONFIG_MONGODB_SERVER: mongo
ports:
- "5051:8081"
links:
- mongo
depends_on:
- mongo
secret2dunikey:
build:
context: .
dockerfile: ./secret2dunikey/Dockerfile
volumes:
- ${SSB_PATH}:/home/astroport/.ssb
oasis:
build:
context: .
dockerfile: ./oasis/Dockerfile
tty: true
ports:
- 3000:3000
volumes:
- ${SSB_PATH}:/home/astroport/.ssb
depends_on:
- secret2dunikey
tip:
build:
context: .
dockerfile: ./tip/Dockerfile
tty: true
volumes:
- ${SSB_PATH}:/home/astroport/.ssb
links:
- oasis
depends_on:
- oasis
- secret2dunikey
ipfs:
image: ipfs/go-ipfs
volumes:
- ipfs-data:/data/ipfs
ports:
- 8080:8080
- 4001:4001
- 5001:5001
volumes:
ipfs-data:
mongo-data:

View File

@ -1,15 +0,0 @@
#!/bin/bash
ssbPubkey=$1
if [[ ${ssbPubkey:0:1} == "@" ]]
then
ssbPubkey=${ssbPubkey:1}
fi
ssbPubkey=$(echo $ssbPubkey | cut -d '.' -f 1)
g1pub=$(echo "$ssbPubkey" | base64 -d | base58)
echo ""
echo $g1pub
echo ""

View File

@ -1,5 +1,5 @@
#!/bin/bash
########################################################################
################################################################################
# Authors:
# [@cel](@f/6sQ6d2CMxRUhLpspgGIulDxDCwYD7DzFzPNr7u5AU=.ed25519)
# [@Fred](@9BbJwPDjcyIqrOUPNn0nJZBduWdIrpMk3Cjz5MP361s=.ed25519)
@ -7,142 +7,92 @@
# [@poka]()
# Version: 1.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##*/}"
echo '
########################################################################
# \\///
# qo-op
############# '$MY_PATH/$ME'
########################################################################
# SSB-G1-TX :: INSTALL G1 + SSB for sending G1 Tip on SSB likes
########################################################################
'
###########################################################################################
# ADD G1 Layer 10 LOVE to message writer you like !
# INSTALL silkaj sbotc
# PREVENT DOUBLE PAYEMENT
############################################################################################
# INSTALL requirements
[[ ! $(which base58) ]] && sudo apt install build-essential base58 -y
# INSTALL Silkaj, CLI for Duniter
if [[ ! $(which silkaj) ]]; then
echo '**************************************************************
__ ___
(_ | | |/ /\ |
__) _|_ |_ |\ /--\ \_|
#Libre Money Layer
'
mkdir -p ~/.zen
echo "INSTALL silkaj"
sudo apt update || true
sudo apt install build-essential -y
sudo pip3 install base58
sudo apt install python3-pip python3-setuptools python3-wheel -y
pip3 install silkaj --user
sudo apt install python3-pip python3-setuptools python3-wheel -y && pip3 install silkaj --user
echo 'PATH=$PATH:.local/bin' >> ~/.bashrc && source ~/.bashrc
fi
# Install ScuttleButt
echo '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
__ _ ___ ___ _ _ ___ ___
(_ / | | | | | |_ |_) | | | |
__) \_ |_| | | |_ |_ |_) |_| | |
#Libre Social Layer
Is it a 24/24 Pub?
Yes/No: y? (Default No)'
read ssb_yes
nodename=$(cat /etc/hostname)
extension=$(echo $nodename | cut -d '.' -f 2)
[[ $extension == $nodename ]] && nodename=$nodename.local
if [[ ! $(which sbot) && "$ssb_yes" == "y" ]]; then
if [[ ! $(which sbot) ]]; then
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.2/install.sh | bash
source ~/.bashrc
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
nvm install --lts
sudo apt install libtool autoconf -y
npm install sodium-native ssb-backlinks ssb-ws ssb-links ssb-query ssb-secret-blob ssb-private
npm install sodium-native ssb-backlinks
npm install -g ssb-server
nodename=$(cat /etc/hostname).local
echo "SSB Node Hostname (default $nodename)?"
read EXTERNAL
[[ $EXTERNAL == "" ]] && EXTERNAL=$nodename
# LOCAL
####### BACKUP .ssb to ~/.ssb_$USER && CREATE ~/.ssb_astroport
# If exists backup ~/.ssb to ~/.ssb_$USER SSB (one time only !)
[[ -d ~/.ssb_$USER ]] && echo "BACKUP already existing... ~/.ssb_$USER !!! Manual check please..." && exit 1
[[ -d ~/.ssb ]] && [[ ! -d ~/.ssb_$USER ]] && mv ~/.ssb ~/.ssb_$USER
# CREATE ~/.ssb_astroport
[[ ! -d ~/.ssb_astroport ]] && mkdir -p ~/.ssb_astroport
# if exists, keep ~/.ssb_$USER/secret*
[[ ! -f ~/.ssb_astroport/secret ]] && [[ -f ~/.ssb_$USER/secret ]] && cp -f ~/.ssb_$USER/secret* ~/.ssb_astroport/
# Symlink ~/.ssb -> ~/.ssb_astroport
[[ -L ~/.ssb ]] && rm ~/.ssb
[[ -d ~/.ssb_astroport ]] && ln -s ~/.ssb_astroport ~/.ssb
mkdir -p ~/.ssb
cat > ~/.ssb/config <<EOF
{
"connections": {
"incoming": {
"net": [
{ "scope": "public", "host": "0.0.0.0", "external": ["$nodename"], "transform": "shs", "port": 8008 }
],
"ws": [
{ "scope": ["public", "local", "device"], "host": "0.0.0.0", "port": 8989, "transform": "shs", "http": true }
{
"scope": "public", "external": ["$EXTERNAL"], "transform": "shs", "port": 8008
},
{ "scope": "private", "transform": "shs", "port": 8008, "host": "127.0.0.1" }
]
},
"outgoing": {
"net": [{ "transform": "shs" }]
"net": [
{
"transform": "shs"
}
]
}
}
}
EOF
cat > ~/.zen/run-ssb_server.sh <<EOF
cat > ~/run-ssb-PUB_$EXTERNAL.sh <<EOF
#!/bin/bash
echo _$ > ~/.zen/ssb.pid.bash
while true; do
ssb-server start
echo _! > ~/.zen/ssb.pid
ssb-server start --host $EXTERNAL
done
EOF
# REPLACE _ with $
sed -i s/_/\$/g ~/.zen/run-ssb_server.sh
chmod 755 ~/.zen/run-ssb_server.sh
# INSTALL sbotc for CLI API
if [[ ! $(which sbotc) ]]; then
sudo apt install libsodium-dev jq -y
git clone https://git.scuttlebot.io/%25133ulDgs%2FoC1DXjoK04vDFy6DgVBB%2FZok15YJmuhD5Q%3D.sha256 sbotc
cd sbotc
make
sudo make install
fi
chmod 755 ~/run-ssb-PUB_$EXTERNAL.sh
~/run-ssb-PUB_$EXTERNAL.sh &
fi
# LOCAL NODE
if [[ $extension == $nodename ]] ; then
echo '
_ ___ _ _ _
|_) /\ | / |_| \ / / \ |_) |/
| /--\ | \_ | | \/\/ \_/ | \ |\
Install Patchwork...
'
wget -s https://github.com/ssbc/patchwork/releases/download/v3.17.6/ssb-patchwork_3.17.6_amd64.deb > /tmp/
sudo dpkg -i /tmp/ssb-patchwork_3.17.6_amd64.deb
# INSTALL sbotc
if [[ ! $(which sbotc) ]]; then
sudo apt install libsodium-dev jq -y
git clone https://git.scuttlebot.io/%25133ulDgs%2FoC1DXjoK04vDFy6DgVBB%2FZok15YJmuhD5Q%3D.sha256 sbotc
cd sbotc
make
sudo make install
fi
###########################################################################################
####################### G1 SSB ACCOUNT MANAGER ############################################
###########################################################################################
# If user already has an SSB account, we generate Duniter secret key from SSB secret key
if [[ -f ~/.ssb/secret ]]; then
@ -165,62 +115,48 @@ else
mkdir -p ~/.ssb
echo "WELCOME CREATING YOUR G1 SSB ACCOUNT !!!"
echo "
__ __ __ _
/__ /| (_ (_ |_)
\_| | __) __) |_)
CHOOSE YOU LOGIN or LEAVE BLANK & HIT ENTER FOR AUTO GENERATION"
echo "CHOOSE YOU LOGIN or LEAVE BLANK & HIT ENTER FOR AUTO GENERATION"
read salt
[[ $salt != "" ]] && echo "PASSWORD?" && read pepper && [[ $pepper == "" ]] && exit 1
[[ $salt != "" ]] && echo "PASSWORD?" && read pepper && [[ $pepper == "" ]] && exit
if [[ "$salt" == "" && "$pepper" == "" ]]; then
echo '
._ _ ._ _ ._ _ _ ._ o _
| | | | | (/_ | | | (_) | | | (_
passphrase generator...'
# INSTALL Cargo
if [[ ! $(which cargo) ]]; then
curl https://sh.rustup.rs -sSf | sh
PATH=$PATH:~/.cargo/env
source $HOME/.cargo/env
fi
# Install DUP-Mnemonic
if [[ ! $(which dup-mnemonic) ]]; then
cd /tmp
git clone https://git.duniter.org/tools/dup-mnemonic-rs
cd dup-mnemonic-rs
cargo build --release
sudo cp target/release/dup-mnemonic /usr/local/bin
fi
# GENERATE MNEMONIC KEY: 9 MOTS
if [[ $salt == "" ]]; then
declare -a makeyarray
makeyarray=($(dup-mnemonic -l $lang))
# LOGIN (=SALT) 6 WORDS
salt="${makeyarray[0]} ${makeyarray[1]} ${makeyarray[2]} ${makeyarray[3]} ${makeyarray[4]} ${makeyarray[5]}"
# PASS (=PEPPER) 3 WORDS
pepper="${makeyarray[6]} ${makeyarray[7]} ${makeyarray[8]}"
fi
echo "........."
echo "REMEMBER YOUR CREDENTIALS: $salt / $pepper"
# INSTALL Cargo
if [[ ! $(which cargo) ]]; then
curl https://sh.rustup.rs -sSf | sh
PATH=$PATH:~/.cargo/env
source $HOME/.cargo/env
fi
# Install DUP-Mnemonic
if [[ ! $(which dup-mnemonic) ]]; then
cd /tmp
git clone https://git.duniter.org/tools/dup-mnemonic-rs
cd dup-mnemonic-rs
cargo build --release
sudo cp target/release/dup-mnemonic /usr/local/bin
fi
# GENERATE MNEMONIC KEY: 9 MOTS
if [[ $salt == "" ]]; then
declare -a makeyarray
makeyarray=($(dup-mnemonic -l $lang))
# LOGIN (=SALT) 6 MOTS
salt="${makeyarray[0]} ${makeyarray[1]} ${makeyarray[2]} ${makeyarray[3]} ${makeyarray[4]} ${makeyarray[5]}"
# PASS (=PEPPER) 3 MOTS
pepper="${makeyarray[6]} ${makeyarray[7]} ${makeyarray[8]}"
fi
echo "........."
echo "REMEMBER YOUR CREDENTIALS: $salt / $pepper"
# CREATE ~/.ssb/secret.dunikey
python3 $MY_PATH/key_create_dunikey.py "$salt" "$pepper"
mv $MY_PATH/.secret.dunikey ~/.ssb/secret.dunikey
python3 ./key_create_dunikey.py "$salt" "$pepper"
mv ./.secret.dunikey ~/.ssb/secret.dunikey
# CREATE SSB secret
pub=$(cat ~/.ssb/secret.dunikey | grep "pub" | cut -d ' ' -f 2)
priv=$(cat ~/.ssb/secret.dunikey | grep "sec" | cut -d ' ' -f 2)
ssbpub=$(echo $pub | base58 -d | base64)
ssbpriv=$(echo $priv | base58 -d | base64)
cat > ~/.ssb/secret <<EOF
# This secret is related to your G1Wallet - https://cesium.app
# silkaj balance $pub

View File

@ -1,37 +0,0 @@
FROM debian@sha256:bf338ddc710dfb9b907a29ba661b35d0f6b3eae043515c4315f64c6e93409e94
LABEL MAINTAINER=chamalow <@qio8/4L4vnzq3qRD0dqKI7sTpey54u8ZWbaICfpJOZw=.ed25519>
ENV DEBIAN_FRONTEND noninteractive
ENV NVM_INSTALL_DIR /opt/nvm
ENV NVM_DIR /usr/local/nvm
ENV NODE_VERSION v12.16.1
RUN apt-get update -y && \
apt-get install autoconf=2.69-11.1 build-essential=12.8 python3-pip=20.0.2-2 python3-setuptools=44.0.0-1 libsodium-dev=1.0.18-1 jq=1.6-1 make=4.2.1-1.2 git=1:2.25.1-1 gcc=4:9.2.1-3.1 base58=1.0.3-1 libtool=2.4.6-14 curl=7.68.0-1 git=1:2.25.1-1 bc=1.07.1-2+b2 -y && \
pip3 install duniterpy==0.56.0 silkaj==0.7.6 && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* && \
useradd -ms /bin/bash astroport
RUN git clone https://github.com/creationix/nvm.git $NVM_INSTALL_DIR && \
. $NVM_INSTALL_DIR/nvm.sh && \
nvm install --lts && \
nvm alias default $NODE_VERSION && \
nvm use default && \
echo "export NVM_DIR=${NVM_DIR}" > /home/astroport/.bashrc && \
echo ". ${NVM_INSTALL_DIR}/nvm.sh" > /home/astroport/.bashrc && \
chown -R astroport:astroport $NVM_DIR
USER astroport
RUN . ~/.bashrc && \
mkdir -p /home/astroport/.ssb/ && \
npm install -g sodium-native@3.0.0 ssb-backlinks@1.0.0 && \
npm install -g fraction/oasis#semver:
VOLUME [ "/home/astroport/.ssb"]
EXPOSE 3000
EXPOSE 8008
ENTRYPOINT ["/bin/bash"]
CMD ["-c", ". ~/.bashrc && oasis --host 0.0.0.0 --open false && tail -f /dev/null"]

186
process-likes-g1tx.sh Executable file
View File

@ -0,0 +1,186 @@
#!/bin/bash
################################################################################
# Authors:
# [@cel](@f/6sQ6d2CMxRUhLpspgGIulDxDCwYD7DzFzPNr7u5AU=.ed25519)
# [@Fred](@9BbJwPDjcyIqrOUPNn0nJZBduWdIrpMk3Cjz5MP361s=.ed25519)
# [@Boris](@l5nYExWYIgDLV6BYHOJPoI97jIUyTdSm8CTLpQ0XeOg=.ed25519)
# Version: 1.0
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
###########################################################################################
# PREVENT DOUBLE PAYEMENT
# ADD G1 Layer 10 LOVE to message writer you like !
############################################################################################
# Let's get G1 public and private keys
g1pub=$(cat ~/.ssb/secret.dunikey | grep "pub" | cut -d ' ' -f 2)
g1priv=$(cat ~/.ssb/secret.dunikey | grep "sec" | cut -d ' ' -f 2)
# SSB pubkey
ssbpub=$(cat ~/.ssb/secret | grep public\" | cut -d ' ' -f 4 | cut -d '.' -f 1 | sed s/\"//g)
############################################################################################
#### CHECK LIKE AND SEND LOVE
# Let's get G1 account balance
echo ""
echo "Welcome to the G1 SSB like microdonation system!"
echo "
MMMMMMMMMMMMMNk;'cdxxd:,c0WMMMMMMMMMMMMM
MMMMMMMMMMMMMNx,. .;kWMMMMMMMMMMMMM
MMMMMMMMMMMMMMMNOdlccld0NMMMMMMMMMMMMMMM
MMMMMMMMMMMWXko:,'....',:okXWMMMMMMMMMMM
MMMMMMMMMNk:. .cOWMMMMMMMMM
MMMMMMMW0: .c0MMMMMMMM
MMMMMMWk. 'lxkOOkdc' .cOWMMMMMMM
MMMMMMO' 'kNMMMMMMMMNxcoOXWMMMMMMMMM
MMMMMNl '0MMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMX; cNMMMMMMMNOkkkkkkkkkkONMMMMM
MMMMMNc ;XMMMMMMMNd' .OMMMMM
MMMMMWx. cKMMMMMMMWKc. .OMMMMM
MMMMMMNo. .lkKXNNXKkc. .OMMMMM
MMMMMMMNd. ...... .OMMMMM
MMMMMMMMWKl. 'c:. .OMMMMM
MMMMMMMMMMWXkc,.. ..,lkXWWO:;OMMMMM
MMMMMMMMMMMMMMWX0OxddxO0XWMMMMMMWXNMMMMM
MMMMMMMMMMMMMMMMNx;'',dNMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMK, '0MMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMNd. .oNMMMMMMMMMMMMMMMM
"
sleep 1
echo ""
echo "You know your SSB pubkey:"
echo $ssbpub
sleep 1
echo ""
echo "...but did you know it is also a valid G1 wallet?"
echo $g1pub
sleep 2
echo ""
echo "Let's check the current balance of your wallet!"
sleep 2
echo ""
echo "We are interrogating the G1 blockchain to check if anyone has already sent G1..."
sleep 1
echo ""
echo "A moment please..."
echo ""
sleep 1
duniter_server="duniter-g1.p2p.legal:443"
echo "Testing server $duniter_server..."
echo ""
silkaj -p "$duniter_server" balance $g1pub 2>/dev/null
if [ $? -eq 1 ]
then
duniter_server="g1.duniter.org:443"
echo "Testing server $duniter_server..."
echo ""
silkaj -p "$duniter_server" balance $g1pub 2>/dev/null
if [ $? -eq 1 ]
then
echo "The server did not respond well. Please try again."
exit 1
fi
fi
echo "Have any money? Then let's send G1love. Press ENTER to continue. " && read
###########################################################################################
self=$(sbotc whoami | jq -r .id) || exit 1
ssb_dir=~/.${ssb_appname:-ssb}
id_part=$(echo "$self" | sed 's/\//_/g' | tail -c +2 | head -c 9)
state_file=$ssb_dir/likes-g1-$id_part.ts
if [ -s "$state_file" ]
then last_ts=$(cat "$state_file") || exit 1
else
last_ts=$(date -u +%s%N | cut -b1-13)
last_ts=$((last_ts - 3600000)) # timestamp from 1h ago
#else last_ts=null
fi
process_msg() {
msg=$1
target_id=$(printf %s "$msg" | jq -r '.value?.content?.vote?.link') || return 1
target_msg=$(sbotc -e get "$target_id") || return 1
target_author=$(printf %s "$target_msg" | jq -r .author) || return 1
author_s_name=$(sbotc query.read '{"query":[{"$filter":{"value":{"author": "'"$target_author"'", "content":{"type":"about", "about": "'"$target_author"'"}}}}]}' | jq .value?.content?.name | grep -v null | tail -n 1)
root_id=$(printf %s "$target_msg" | jq -r .content?.root) || return 1
[[ $root_id == "null" ]] && root_id=$target_id
g1_author=$(echo $target_author | cut -d '.' -f 1 | cut -d '@' -f2 | base64 -d | base58)
msg_excerpt=$(printf %s "$target_msg" | jq -r .content?.text | head -n 10) || return 1
}
bold=$(tput bold)
normal=$(tput sgr0)
sbotc query.read '{"query":[{"$filter":{"value":{"author":"'"$self"'","content":{"type":"vote", "vote":{"expression":"Like"}},"timestamp":{"$gt":'"$last_ts"'}}}}]}' | while read -r msg
do
priv=$(printf %s "$msg" | jq .value.content.private)
if [[ $priv == true ]]
then
printf "Private message $priv, continue to next one\n" >&2
continue
fi
if ! ts=$(printf %s "$msg" | jq -r .value.timestamp)
then
printf 'Unable to get message timestamp\n' >&2
exit 1
fi
if ! echo "$ts" > "$state_file"~
then
printf 'Unable to write to backup state file.\n' >&2
exit 1
fi
if ! process_msg "$msg"
then
msg_id=$(printf %s "$msg" | jq -r .key)
printf 'Unable to process message %s\n' "$msg_id" >&2
exit 1
fi
echo ""
echo "================================================================"
printf "Let's thank ${bold}@%s ${normal}for their message: \n" "${author_s_name:1:-1}"
echo "================================================================"
printf "%s" "$msg_excerpt"
echo ""
echo "----------------------------------------------------------------"
if [[ $g1_author != $g1pub ]]; then
#printf '%s\n' "silkaj -af --file ~/.ssb/secret.dunikey tx --output $g1_author --amountUD 0.1 --comment _SSB:LIKE:$target_id"
#### SEND 10 LOVE = 0.1 DU to $g1_author wallet
silkaj -p "$duniter_server" -af --file ~/.ssb/secret.dunikey tx --output $g1_author --amountUD 0.1 --comment "_SSB:LIKE:$target_id" -y 2>/dev/null
#### WRITE RESPONSE MESSAGE
if [ ! -f ~/.ssb/db/g1likes ]; then
touch ~/.ssb/db/g1likes
fi
if ! grep -Fxq $target_author ~/.ssb/db/g1likes; then
echo $target_author >> ~/.ssb/db/g1likes
thank_you_msg=$(printf '[@%s](%s) > Thanks for this post ; I have just sent you G1 libre money. Use it with [Cesium](https://cesium.app). Get it from [https://git.p2p.legal/Axiom-Team/ssb-g1like](https://git.p2p.legal/Axiom-Team/ssb-g1like)' "${author_s_name:1:-1}" "$target_author")
sbotc publish '{"type":"post","text":"'"$thank_you_msg"'", "branch": "'"$target_id"'", "root": "'"$root_id"'"}' 2>&1>/dev/null
echo "----------------------------------------------------------------"
printf "Since it's the first time you sent G1 to %s, he was sent this message: \n\n%s \n" "$author_s_name" "$thank_you_msg"
echo "----------------------------------------------------------------"
fi
#printf "0.1 G1UD sent to %s!\n" "$author_s_name"
#echo "----------------------------------------------------------------"
echo ""
echo ""
sleep 20 # DO NOT OVER CHARGE DUNITER
else
echo "I LIKE MY MESSAGE $target_id"
fi
if ! mv "$state_file"~ "$state_file"
then
msg_id=$(printf %s "$msg" | jq -r .key)
printf 'Unable to write to state file. Update state file manually to prevent %s from being processed twice.\n' "$msg_id" >&2
exit 1
fi
done

157
readme.md
View File

@ -1,137 +1,62 @@
![SSB/Ğ1 tip](https://git.p2p.legal/axiom-team/ssb-g1-tip/raw/master/doc/ssb-g1-tip-logo.png)
SSB/Ğ1 like
===
**SSB/Ğ1 tip** is a micro donation system, just like Flattr, except:
**SSB/Ğ1 like** is a micro donation system, just like Flattr, except:
- It runs on SSB instead of the centralized web
- It uses a libre currency (Ğ1) instead of a private one
![SSB/Ğ1 like logo](https://git.p2p.legal/axiom-team/ssb-g1like/raw/dev-boris/doc/ssb-g1like-logo.png)
## Authors
- **cel** from the SSB community (`@f/6sQ6d2CMxRUhLpspgGIulDxDCwYD7DzFzPNr7u5AU=.ed25519`)
- **Fred** from the Ğ1 community (`@9BbJwPDjcyIqrOUPNn0nJZBduWdIrpMk3Cjz5MP361s=.ed25519`)
- **Boris** from the Ğ1 community (`@l5nYExWYIgDLV6BYHOJPoI97jIUyTdSm8CTLpQ0XeOg=.ed25519`)
## What is a libre currency?
A [libre currency](https://libre-currency.org/) is a concept that originated from the [Relative Theory of Money](https://en.trm.creationmonetaire.info/).
It is a way to design a currency so that every human, whatever the generation they are part of, produces the same relative amount of money.
The Relative Theory of Money was written by a French mathematician in 2010, and the first libre currency (Ğ1) was born in 2017. Up to this day, Ğ1 is the only libre currency we know of.
### Ğ1, the first libre currency
Ğ1 the first libre currency we know of.
It runs on [the Duniter blockchain engine](https://duniter.org/).
The main clients for Duniter are [Cesium](https://cesium.app/) and [Silkaj](https://mystifying-nobel-66ae54.netlify.com/)
## How to spend your Ğ1
The Ğ1 currency originated in called France, so the main part of the fun happens there.
The economy is still in its infancy, but you can already [book a reservation in a B&B](https://www.gchange.fr/#/app/market/lg?last&category=cat67&type=offer).
An other way to spend your Ğ1 is use it with this micro-donation system:
![](https://git.p2p.legal/axiom-team/ssb-g1like/raw/dev-boris/doc/process-likes-g1tx.gif)
## An SSB user sent you Ğ1? Here is how to claim it:
First, you need to generate your base58 Duniter secret key from your base64 SSB secret key.
First, you need to get your Duniter secret key from your SSB secret key.
```
chmod +x secret2dunikey.sh
./secret2dunikey.sh
```
Then, all you need to do is connect to a Duniter client, using the generated ~/.ssb/secret.dunikey
Then, all you need to do is connect to a Duniter client, like [Cesium](https://cesium.app/), using the generated ~/.ssb/secret.dunikey
1. Download [Cesium](https://cesium.app/)
2. On Cesium homescreen, click "**Other methods**" and choose "**Keychain file**" :
3. Then, browse your filesystem to select your Duniter secret key stored in ~/.ssb/secret.dunikey :
4. Contemplate how rich and resilient you now are.
5. Update your Cesium+ profile to appear on the registry map.
On Cesium homescreen, click "**Other methods**" and choose "**Keychain file**" :
![Cesium authentification](https://git.p2p.legal/axiom-team/ssb-g1-tip/raw/master/doc/create-account.gif)
![Cesium authentification](https://git.p2p.legal/axiom-team/ssb-g1like/raw/dev-boris/doc/cesium-other-methods-800.png)
## You too want to send tips?
Then, browse your filesystem to select your Duniter secret key stored in ~/.ssb/secret.dunikey :
A cool way to spend your Ğ1 is use it with this micro-donation system.
### Install
First, you have to install the necessary tools using the `install.sh` script.
```
chmod +x install.sh tip.sh
./install.sh
```
This script installs tools like Silkaj, the command line Duniter client. Don't worry, you will only have to do this once 😉
### Usage
Then, once every other week, you can use the `tip.sh` script :
```
./tip.sh
```
`tip.sh` will have a look at the posts you liked and will send from your Duniter account the corresponding amount (based on the number of times you liked a post) to the appropriate recipients.
It will also generate one or more markdown formatted files to help you thank publicly your fellow butts, and make them aware you sent them a tip 😉
![](https://git.p2p.legal/axiom-team/ssb-g1-tip/raw/master/doc/tip.gif)
## Other ways to spend your Ğ1
The Ğ1 currency originated in called France, so the main part of the fun happens there.
The economy is still in its infancy, but you can already:
- [book a reservation in a B&B](https://www.gchange.fr/#/app/market/lg?last&category=cat67&type=offer),
- [buy SEO services](https://www.gchange.fr/#/app/market/lg?type=offer&q=SEO),
- [buy web hosting services](https://www.gchange.fr/#/app/market/lg?type=offer&q=h%C3%A9bergement%20web)
- [buy foreign language courses](https://www.gchange.fr/#/app/market/lg?type=offer&q=langues) (for example: [french](https://www.gchange.fr/#/app/market/view/AWybPgso8tT4T_JOSi4w/francais-langue-trangre))
- etc. etc. ([see latest offers](https://www.gchange.fr/#/app/market/lg?last&type=offer))
## Curious about libre currencies?
[Libre currencies](https://libre-currency.org/) are a concept that originated from the [Relative Theory of Money](https://en.trm.creationmonetaire.info/).
It is a way to design a currency so that every human, whatever the generation they are part of, produces the same relative amount of money.
Unlinke the majority of currencies, where money creation is centralized (money is created by big private banks via credit), in a libre currency, money creation takes place everywhere.
![](https://git.p2p.legal/axiom-team/ssb-g1-tip/raw/master/doc/value-fields.png)
The Relative Theory of Money was written in 2010 by French mathematician Stephane Laborde, and the first libre currency (Ğ1) was born in 2017. Up to this day, Ğ1 is the only libre currency we know of.
### Ğ1, the first libre currency
Ğ1 the first libre currency we know of.
Ğ1 has the particularity to use blockchain to secure transactions, and uses on a web of trust to identify unique users, in order to make sure each individual can produce only one **Universal Dividend** each day, and nobody is cheating by producing a disproportionate amount of money.
Ğ1 runs on [the Duniter blockchain engine](https://duniter.org/).
The main clients for Duniter are [Cesium](https://cesium.app/) and [Silkaj](https://mystifying-nobel-66ae54.netlify.com/)
![Cesium log with keychain file](https://git.p2p.legal/axiom-team/ssb-g1like/raw/dev-boris/doc/cesium-dunikey-800.png)
## With docker (experimental)
### install docker & docker-compose
[Docker](https://docs.docker.com/install/)
[Docker-compose](https://docs.docker.com/compose/install/)
### variables
SSB_PATH : this is important variable to locate your ssb db path and secret file don't forget to set that.
First you need to build docker image.
```
SSB_PATH=~/.ssb/ docker-compose build
```
create your dunikey
```
SSB_PATH=~/your-copy-ssb/ docker-compose up -d tip # only you need to run tiping part
SSB_PATH=~/your-copy-ssb/ docker-compose up -d # if you need to run all platform
```
run main tip script
```
container_id=$(docker ps -a -q --filter="ancestor=ssb-g1like_tip") && docker exec -ti $container_id bash -c "/home/astroport/tip"
```
For display thank you file
```
container_id=$(docker ps -a -q --filter="ancestor=ssb-g1like_tip") && docker cp $container_id:/home/astroport/thank-your-butts-$(date -u +%Y-week-%W).md ~ && docker exec -ti $container_id bash -c "rm -rf /home/astroport/thank-your-butts-$(date -u +%Y-week-%W).md"
```
## Authors
- **cel** (`@f/6sQ6d2CMxRUhLpspgGIulDxDCwYD7DzFzPNr7u5AU=.ed25519`)
- **Fred** (`@9BbJwPDjcyIqrOUPNn0nJZBduWdIrpMk3Cjz5MP361s=.ed25519`)
- **Boris** (`@l5nYExWYIgDLV6BYHOJPoI97jIUyTdSm8CTLpQ0XeOg=.ed25519`)
- **poka** (`@vDQif9KU3T78XJx+NliK+wdo1vmehHZCWqD+3X700Uk=.ed25519`)
- **chamalow** (`@qio8/4L4vnzq3qRD0dqKI7sTpey54u8ZWbaICfpJOZw=.ed25519`)

View File

@ -1,18 +0,0 @@
{
"value": {
"previous": "%bcGFgwgdCjhGQjVYCNaUSKZq6xqMBpiB23U4q2lq2uE=.sha256",
"sequence": 392,
"author": "@l5nYExWYIgDLV6BYHOJPoI97jIUyTdSm8CTLpQ0XeOg=.ed25519",
"timestamp": 1584565226366,
"hash": "sha256",
"content": {
"type": "post",
"text": "",
"mentions": [
]
},
"signature": "TZ8R5HlKvuPquS26CJkq2VhPdR+yA2LdnL0cVo1GD6jJioTufup1n6mSrQIc3jHyqy+wZ8ILJfsWnqt8WegQAg==.sig.ed25519"
},
"timestamp": 1584565226369,
"rts": 1584565226366
}

View File

@ -1,5 +0,0 @@
{
"link": "",
"name": ""
},

View File

@ -1,4 +0,0 @@
{
"link": "#"
},

View File

@ -1,5 +0,0 @@
{
"link": "",
"name": ""
},

1
sbotc Submodule

@ -0,0 +1 @@
Subproject commit f1337fffb2467ae35d1e694221cd0fd9ba97923f

View File

@ -1,18 +0,0 @@
FROM debian@sha256:bf338ddc710dfb9b907a29ba661b35d0f6b3eae043515c4315f64c6e93409e94
LABEL MAINTAINER=chamalow <@qio8/4L4vnzq3qRD0dqKI7sTpey54u8ZWbaICfpJOZw=.ed25519>
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update -y && \
apt-get install base58=1.0.3-1 python3-pip=20.0.2-2 python3-setuptools=44.0.0-1 -y && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* && \
useradd -ms /bin/bash astroport
USER astroport
WORKDIR /home/astroport/
COPY ./secret2dunikey.sh /home/astroport/secret2dunikey.sh
ENTRYPOINT ["/bin/bash"]
CMD [ "secret2dunikey.sh"]

535
tip.sh
View File

@ -1,535 +0,0 @@
#!/bin/bash
################################################################################
#
# Authors:
#
# [@cel](@f/6sQ6d2CMxRUhLpspgGIulDxDCwYD7DzFzPNr7u5AU=.ed25519)
# [@Fred](@9BbJwPDjcyIqrOUPNn0nJZBduWdIrpMk3Cjz5MP361s=.ed25519)
# [@Boris](@l5nYExWYIgDLV6BYHOJPoI97jIUyTdSm8CTLpQ0XeOg=.ed25519)
# [@poka](@vDQif9KU3T78XJx+NliK+wdo1vmehHZCWqD+3X700Uk=.ed25519)
# @[chamalow](@qio8/4L4vnzq3qRD0dqKI7sTpey54u8ZWbaICfpJOZw=.ed25519)
#
# Version: 1.0
#
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
#
###########################################################################################
# PREVENT DOUBLE PAYEMENT
# ADD Ğ1 Layer 10 LOVE to message writer you like !
############################################################################################
# Customizable
# debugMsgMode, when set to 1 does doesn't send transaction and does not update "last timestamp"
debugMsgMode=0
# If you don't want to wait
readable=1
minimumAmountPerLikeInLOVE="10"
############################################################################################
# Let's get Ğ1 public and private keys
g1pub=$(cat ~/.ssb/secret.dunikey | grep "pub" | cut -d ' ' -f 2)
g1priv=$(cat ~/.ssb/secret.dunikey | grep "sec" | cut -d ' ' -f 2)
# SSB pubkey
ssbpub=$(cat ~/.ssb/secret | grep public\" | cut -d ' ' -f 4 | cut -d '.' -f 1 | sed s/\"//g)
defaultAmountPerLikeInUD="0.1"
bold=$(tput bold)
normal=$(tput sgr0)
ssbMaxSize=8192
baseSizeOfAMessageFile=$(wc -c samples/message.json | awk '{print $1}')
sizeOfATagMention=$(wc -c samples/tag_mention.json | awk '{print $1}')
sizeOfAUserMention=$(wc -c samples/user_mention.json | awk '{print $1}')
sizeOfAPostMention=$(wc -c samples/post_mention.json | awk '{print $1}')
############################################################################################
#### CHECK LIKE AND SEND LOVE
# Let's get Ğ1 account balance
echo ""
echo -e "${bold}Welcome${normal} to the Ğ1/SSB-like microdonation system!\n"
if [[ $readable -eq 1 ]]; then sleep 1; fi
echo "MMMMMMMMMMMMMNk;'cdxxd:,c0WMMMMMMMMMMMMM
MMMMMMMMMMMMMNx,. .;kWMMMMMMMMMMMMM
MMMMMMMMMMMMMMMNOdlccld0NMMMMMMMMMMMMMMM
MMMMMMMMMMMWXko:,'....',:okXWMMMMMMMMMMM
MMMMMMMMMNk:. .cOWMMMMMMMMM
MMMMMMMW0: .c0MMMMMMMM"
if [[ $readable -eq 1 ]]; then sleep 1; fi
echo "MMMMMMWk. 'lxkOOkdc' .cOWMMMMMMM
MMMMMMO' 'kNMMMMMMMMNxcoOXWMMMMMMMMM
MMMMMNl '0MMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMX; cNMMMMMMMNOkkkkkkkkkkONMMMMM
MMMMMNc ;XMMMMMMMNd' .OMMMMM
MMMMMWx. cKMMMMMMMWKc. .OMMMMM
MMMMMMNo. .lkKXNNXKkc. .OMMMMM"
if [[ $readable -eq 1 ]]; then sleep 1; fi
echo "MMMMMMMNd. ...... .OMMMMM
MMMMMMMMWKl. 'c:. .OMMMMM
MMMMMMMMMMWXkc,.. ..,lkXWWO:;OMMMMM
MMMMMMMMMMMMMMWX0OxddxO0XWMMMMMMWXNMMMMM
MMMMMMMMMMMMMMMMNx;'',dNMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMK, '0MMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMNd. .oNMMMMMMMMMMMMMMMM
"
if [[ $readable -eq 1 ]]; then sleep 1; fi
printf "You know your SSB pubkey:\n%s\n\n" $ssbpub
if [[ $readable -eq 1 ]]; then sleep 2; fi
printf "...but did you know it is also a valid Ğ1 wallet?\n%s\n\n" $g1pub
if [[ $readable -eq 1 ]]; then sleep 2; fi
printf "Let's check the current balance of your wallet!\n\n"
if [[ $readable -eq 1 ]]; then sleep 1; fi
printf "I am interrogating the Ğ1 blockchain to check if anyone has already sent you Ğ1...\n\n"
if [[ $readable -eq 1 ]]; then sleep 2; fi
printf "A moment please...\n\n"
if [[ $readable -eq 1 ]]; then sleep 1; fi
silkajRelativeAmountPattern='Total\sRelative\s+=\s+(.*)\s+UD'
duniter_servers[0]="duniter-g1.p2p.legal:443"
duniter_servers[1]="g1.duniter.org:443"
duniter_servers[2]="g1.presles.fr:443"
duniter_servers[3]="balboa.altsysnet.com:10900"
duniter_servers[4]="remuniter.cgeek.fr:16120"
duniter_servers[5]="duniter.moul.re:443"
duniter_servers[6]="77.152.31.154:20901"
duniter_servers[7]="duniter.g1.1000i100.fr:443"
silkajExitCode=1
i=0
while [ $silkajExitCode -ne 0 ] && [ $i -lt ${#duniter_servers[@]} ]
do
echo "Testing server ${duniter_servers[$i]}..."
echo ""
silkajOutput=$(silkaj -p "${duniter_servers[$i]}" balance $g1pub 2>/dev/null)
silkajExitCode=$?
((i++))
done
if [ $silkajExitCode -eq 1 ]
then
echo "The server did not respond well. Please try again."
exit 1
fi
if [[ $silkajOutput =~ $silkajRelativeAmountPattern ]]
then
balance="${BASH_REMATCH[1]}"
else
echo "Account balance wasn't found."
exit 1
fi
printf "You have ${bold}%s LOVE${normal} on your Duniter Ğ1 wallet.\n\n" "$((balance * 100))"
if [[ $readable -eq 1 ]]; then sleep 2; fi
printf "Want to show your appreciation of your fellow butts' posts while helping spreading awareness about libre currencies?\n\n"
if [[ $readable -eq 1 ]]; then sleep 3; fi
# BEGIN timestamp computation
self=$(sbotc whoami | jq -r .id) || exit 1
ssb_dir=~/.${ssb_appname:-ssb}
id_part=$(echo "$self" | sed 's/\//_/g' | tail -c +2 | head -c 9)
state_file=$ssb_dir/likes-g1-$id_part.ts
current_ts=$(date -u +%s%N | cut -b1-13)
if [ -s "$state_file" ]
then
last_ts=$(cat "$state_file") || exit 1
else
# timestamp from 24h ago
last_ts=$((current_ts - 24*3600*1000 - 1))
#else last_ts=null
fi
days_from_last_tx=$(( (current_ts - last_ts) / (24*60*60*1000) ))
# END timestamp computation
printf "First, let's see how much ❤ you gave lately...\n\n"
if [[ $readable -eq 1 ]]; then sleep 1; fi
declare -A likesNbPerAuthor
declare -A likedPosts
declare -A likesNbPerPost
declare -A postsTimestamps
declare -A excerpts
totalLikesGiven=0
process_msg() {
msg=$1
target_id=$(printf %s "$msg" | jq -r '.value?.content?.vote?.link') || return 1
target_msg=$(sbotc -e get "$target_id") || return 1
target_author=$(printf %s "$target_msg" | jq -r .author) || return 1
msg_content=$(printf %s "$target_msg" | jq -r .content?.text) || return 1
# beware of markdown !
msg_excerpt=${msg_content:0:10}
#root_id=$(printf %s "$target_msg" | jq -r .content?.root) || return 1
#[[ $root_id = "null" ]] && root_id=$target_id
}
process_author() {
author_id=$1
g1_author=$(echo $author_id | cut -d '.' -f 1 | cut -d '@' -f2 | base64 -d | base58)
author_name=$(sbotc query.read '{"query":[{"$filter":{"value":{"author": "'"$author_id"'", "content":{"type":"about", "about": "'"$author_id"'"}}}}]}' | jq .value?.content?.name | grep -v null | tail -n 1)
author_name=${author_name:1:-1}
}
authorsNb=0
i=0
messages=$(sbotc query.read '{"query":[{"$filter":{"value":{"author":"'"$self"'","content":{"type":"vote", "vote":{"expression":"Like"}},"timestamp":{"$gt":'"$last_ts"'}}}}]}')
while read -r msg
do
priv=$(printf %s "$msg" | jq .value.content.private)
if [[ $priv = true ]]
then
printf "Private message $priv, continue to next one\n" >&2
continue
fi
if ! process_msg "$msg"
then
msg_id=$(printf %s "$msg" | jq -r .key)
printf '\nUnable to process message %s\n' "$msg_id" >&2
exit 1
fi
if [[ $g1_author = $g1pub ]]; then
echo "I LIKE MY MESSAGE $target_id"
else
((totalLikesGiven++))
if [[ ${likesNbPerAuthor[$target_author]} -eq 0 ]]
then
likesNbPerAuthor[$target_author]=1
likedPosts[$target_author]=""
else
likesNbPerAuthor[$target_author]=$((${likesNbPerAuthor[$target_author]} + 1))
fi
if [[ ${likesNbPerPost[$target_id]} -eq 0 ]]
then
likesNbPerPost[$target_id]=1
likedPosts[$target_author]+=$target_id
likedPosts[$target_author]+="\n"
else
((likesNbPerPost[$target_id]++))
fi
excerpts[$target_id]=$msg_excerpt
# We cannot use this anymore
# (now saving current_ts once all tx have been sent)
#
# if ! postsTimestamps[$target_id]=$(printf %s "$msg" | jq -r .value.timestamp)
#then
# printf 'Unable to get message timestamp\n' >&2
# exit 1
#fi
((i++))
fi
done < <(printf '%s\n' "$messages")
if [[ $totalLikesGiven -eq 0 ]]
then
printf "You did not give any like during the past %s days or they have already been processed.\n\n" "$days_from_last_tx"
printf "Try again in a few days.\n\n"
fi
printf "You gave ${bold}%s❤${normal} during the past %s days.\n\n" "$totalLikesGiven" "$days_from_last_tx"
if [[ $readable -eq 1 ]]; then sleep 2; fi
tx_are_possible=0
while [[ $tx_are_possible -eq 0 ]]
do
printf "How many LOVE do you want to send per each like you gave? (minimum is ${bold}%s LOVE${normal}) " "$((minimumAmountPerLikeInLOVE))"
read a
printf "\n"
if [[ -z $a ]]
then
amountPerLikeInUD=$(bc -l <<< "scale=2; $minimumAmountPerLikeInLOVE / 100")
else
amountPerLikeInUD=$(bc -l <<< "scale=2; $a / 100")
fi
amountGiven=$(echo "$totalLikesGiven * $amountPerLikeInUD" | bc -l)
has_enough_money=$(( $(echo "$amountGiven <= $balance" | bc -l) ))
amountPerLike_is_enough=$(( $(echo "$amountPerLikeInUD >= $minimumAmountPerLikeInLOVE" | bc -l) ))
tx_are_possible=$(( $has_enough_money && $amountPerLike_is_enough ))
if [[ $readable -eq 1 ]]; then sleep 1; fi
if [[ $tx_are_possible -eq 0 ]] ; then
if [[ $has_enough_money -eq 0 ]] ; then
printf "You don't have enough LOVE to send all transactions.\n\n"
if [[ $readable -eq 1 ]]; then sleep 1; fi
printf "${bold}%s LOVE${normal} are needed.\n\n" "$((amountGiven * 100))"
if [[ $readable -eq 1 ]]; then sleep 1; fi
elif [[ $amountPerLike_is_enough -eq 0 ]] ; then
printf "Minimum amount per like is %s LOVE.\n\n" $minimumAmountPerLikeInLOVE
if [[ $readable -eq 1 ]]; then sleep 1; fi
fi
printf "Try again with a different amount per like.\n\n"
maxAmountPerLike=$(awk -vp=$balance -vq=$totalLikesGiven 'BEGIN{printf "%.2f" ,p / q}')
if [[ $readable -eq 1 ]]; then sleep 1; fi
printf "Maximum amount per like possible: ${bold}%s LOVE${normal}\n\n" "$((maxAmountPerLike * 100))"
if [[ $readable -eq 1 ]]; then sleep 1; fi
else
newBalance=$(echo "$balance - $amountGiven" | bc -l)
printf "${bold}%s LOVE${normal} will be given.\n\n" "$((amountGiven * 100))"
if [[ $readable -eq 1 ]]; then sleep 1; fi
printf "After sending transactions, your new balance will be ${bold}%s LOVE${normal}\n\n" "$((newBalance * 100))"
if [[ $readable -eq 1 ]]; then sleep 1; fi
printf "Press ENTER to continue: " && read
printf "\n"
fi
done
# Let's construct thank you posts (tyPosts) and send transactions!
tyPostIndex=0
tyPosts[0]=""
tyPosts[0]+="# I tipped you for your posts!\n\n"
tyPosts[0]+=$(printf "Huge thanks to the ScuttleButt community for all the fascinating posts you allowed me to read in the past %s days." "$days_from_last_tx")
tyPosts[0]+="\n\nAs a means to thank you further, I have just sent you #Ğ1 libre money.\n\n"
tyPosts[0]+="These messages, though they might feel spammy (sorry) are also a way for the Ğ1 community to spread awareness about [libre currencies](https://libre-currency.org/) so we can build #resilience at every level.\n\n"
tyPosts[0]+="You can learn how to spend your freshly earned money at [https://git.p2p.legal/Axiom-Team/ssb-g1-tip](https://git.p2p.legal/Axiom-Team/ssb-g1-tip)\n\n"
tyPosts[0]+="Below is the list of SSB users whose content I liked recently, and the amount each one was given:\n\n"
tableHeaders='| thanks to | for their posts | tip |\n'
tableHeaders+='| --- | --- | ---- |\n'
sizeOfTableHeaders=$(printf "%s" "$tableHeaders" | wc -c)
tyPosts[0]+=$tableHeaders
# for message size calculation
# update following if you add tags in the message :
tags[0]="Ğ1"
tags[1]="resilience"
sizeOfTags=0
for t in ${!tags[@]}
do
tagSize=$(printf "%s" "${tags[t]}" | wc -c)
(( sizeOfTags+=sizeOfATagMention + tagSize ))
done
firstPostContentSize=$(printf "%s" "${tyPosts[0]}" | wc -c)
tyPostsSizes[0]=$((baseSizeOfAMessageFile + firstPostContentSize + sizeOfTags))
nbOfAuthors=${#likesNbPerAuthor[@]}
authorNum=1
for author_id in ${!likesNbPerAuthor[@]}
do
process_author $author_id
# (Legacy) saving authors we have already mentionned in a message
likedAuthorsFile=$ssb_dir/db/g1likes
if [ ! -f $likedAuthorsFile ]; then
touch $likedAuthorsFile
fi
if ! grep -Fxq $author_id $likedAuthorsFile; then
echo $author_id >> $likedAuthorsFile
fi
tipAmount=$(bc <<< "${likesNbPerAuthor[$author_id]} * $amountPerLikeInUD")
newLine=''
newLine+=$(printf "| [@%s](%s) " "$author_name" "$author_id")
newLine+="| "
sizeOfAuthorName=$(printf "%s" "$author_name" | wc -c)
sizeOfAuthorId=$(printf "%s" "$author_id" | wc -c)
newLineSize=0
(( newLineSize+=sizeOfAUserMention + sizeOfAuthorName + sizeOfAuthorId))
p=${likedPosts[$author_id]}
thisAuthorLikedPosts=( ${p//\\n/ } )
isFirstPostOfThisAuthor=1
for likedPostId in ${thisAuthorLikedPosts[@]}
do
if [[ $isFirstPostOfThisAuthor -eq 1 ]]
then
isFirstPostOfThisAuthor=0
else
newLine+=", "
(( newLineSize+=2 ))
fi
newLine+=$(printf " %s❤" "${likesNbPerPost[$likedPostId]}")
newLine+=$(printf "[\`%s\`](%s)" "${excerpts[$likedPostId]}" "$likedPostId")
sizeOfExcerpt=${#excerpts[$likedPostId]}
(( sizeOfExcerpt+=2 )) # for before ` and after `
sizeOfLikedPostId=$(printf "%s" "$likedPostId" | wc -c)
(( newLineSize+=sizeOfAPostMention + sizeOfExcerpt + sizeOfLikedPostId ))
done
newLine+=$(printf "| %s LOVE " "$((tipAmount * 100))")
newLine+="|\n"
(( newLineSize+=$(printf "%s" "$newLine" | wc -c) ))
# printf "total size: %s\n\n" "$((${tyPostsSizes[$tyPostIndex]} + $newLineSize))"
# If adding new line would exceed max size, we create a new thank you post
sizeWithNewLine=${tyPostsSizes[$tyPostIndex]}
(( sizeWithNewLine+=newLineSize ))
if [[ $sizeWithNewLine -gt $ssbMaxSize ]]
then
printf "size before split: %s\n\n" "${tyPostsSizes[$tyPostIndex]}"
printf "size with new line: %s\n\n" "$sizeWithNewLine"
printf "size of new line: %s\n\n" "$newLineSize"
(( tyPostIndex++ ))
tyPosts[$tyPostIndex]+=$tableHeaders
(( tyPostsSizes[$tyPostIndex]=baseSizeOfAMessageFile + sizeOfTableHeaders ))
fi
tyPosts[$tyPostIndex]+=$newLine
(( tyPostsSizes[$tyPostIndex]+=newLineSize ))
if [[ $debugMsgMode -eq 0 ]]
then
if [[ $authorNum -ne 1 ]]
then
sleep 20 # DO NOT OVER CHARGE DUNITER
fi
#printf '%s\n' "silkaj -af --file ~/.ssb/secret.dunikey tx --output $g1_author --amountUD $tipAmount --comment "Thx for your cool posts on ScuttleButt"
silkaj -p "$duniter_server" -af --file ~/.ssb/secret.dunikey tx --output $g1_author --amountUD $tipAmount --comment "Thx for your cool posts on ScuttleButt" -y 2>/dev/null
printf "\n${bold}%s LOVE${normal} sent to %s!\n\n" "$((tipAmount * 100))" "$author_name"
fi
(( authorNum++ ))
done
# Let's save the current timestamp
if [[ $debugMsgMode -eq 0 ]]
then
if ! echo "$current_ts" > "$state_file"~
then
printf 'Unable to write to backup state file.\n' >&2
exit 1
fi
if ! mv "$state_file"~ "$state_file"
then
printf 'Unable to write to state file. Update state file manually to prevent tips to %s from being processed twice.\n' "$author_name" >&2
exit 1
fi
fi
printf "\n%s LOVE sent to %s butts!\n\n" "$((amountGiven * 100))" "${#likesNbPerAuthor[@]}"
# Let's publicly thank everyone!
#echo -e "${tyPosts[$n]}"
# the following produces error:
# "sbotc: unexpected end of parent stream"
# must be a non-escaped quote problem...
#thank_you_msg=$(printf "%q" "${tyPosts[$n]}")
#sbotc publish '{"type":"post","text":"'"$thank_you_msg"'"}' 2>&1>/dev/null
printf "What now ?\n\n"
if [[ $readable -eq 1 ]]; then sleep 1; fi
date=$(date -u +%Y-week-%W)
if [[ ${#tyPosts[@]} -eq 1 ]]
then
msg_filename=thank-your-butts-$date
echo -e ${tyPosts[$n]} > ~/$msg_filename.md
else
for i in ${!tyPosts[@]}
do
part=$((i + 1))
msg_filename=thank-your-butts-$date
echo -e ${tyPosts[$i]} > ~/$msg_filename-part-$part.md
done
fi
printf "A surprise is awaiting in your home dir (~).\n\n"
if [[ $readable -eq 1 ]]; then sleep 2; fi
if [[ ${#tyPosts[@]} -eq 1 ]]
then
printf "It's a file.\n\n"
if [[ $readable -eq 1 ]]; then sleep 2; fi
printf "It's called $msg_filename.md\n\n"
# Open file with xed
[[ $(which xed) ]] && xed ~/$msg_filename.md &
else
printf "It's %s files.\n\n" "${#tyPosts[@]}"
if [[ $readable -eq 1 ]]; then sleep 2; fi
printf "The first one is called $msg_filename-part-1.md.\n\n"
fi
if [[ $readable -eq 1 ]]; then sleep 2; fi
printf "Customize it to your needs to thank your fellow butts publicly and help spread awareness about libre currencies :-)\n\n"
if [[ $readable -eq 1 ]]; then sleep 3; fi
printf "Then delete it.\n\n"
if [[ $readable -eq 1 ]]; then sleep 2; fi
printf "...because it won't self-destruct, haha :D \n\n"

View File

@ -1,42 +0,0 @@
FROM debian@sha256:bf338ddc710dfb9b907a29ba661b35d0f6b3eae043515c4315f64c6e93409e94
LABEL MAINTAINER=chamalow <@qio8/4L4vnzq3qRD0dqKI7sTpey54u8ZWbaICfpJOZw=.ed25519>
ENV DEBIAN_FRONTEND noninteractive
ENV NVM_INSTALL_DIR /opt/nvm
ENV NVM_DIR /usr/local/nvm
ENV NODE_VERSION v12.16.1
COPY ./tip/sbotc.sh /usr/bin/sbotc
RUN apt-get update -y && \
apt-get install autoconf=2.69-11.1 build-essential=12.8 python3-pip=20.0.2-2 python3-setuptools=44.0.0-1 libsodium-dev=1.0.18-1 jq=1.6-1 make=4.2.1-1.2 git=1:2.25.1-1 gcc=4:9.2.1-3.1 base58=1.0.3-1 libtool=2.4.6-14 curl=7.68.0-1 git=1:2.25.1-1 bc=1.07.1-2+b2 -y && \
pip3 install duniterpy==0.56.0 silkaj==0.7.6 && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* && \
useradd -ms /bin/bash astroport && \
chmod +x /usr/bin/sbotc
RUN git clone https://github.com/creationix/nvm.git $NVM_INSTALL_DIR && \
. $NVM_INSTALL_DIR/nvm.sh && \
nvm install --lts && \
nvm alias default $NODE_VERSION && \
nvm use default && \
echo "export NVM_DIR=${NVM_DIR}" > /home/astroport/.bashrc && \
echo ". ${NVM_INSTALL_DIR}/nvm.sh" > /home/astroport/.bashrc && \
chown -R astroport:astroport $NVM_DIR
COPY ./samples /home/astroport/samples
COPY ./tip/tip.sh /home/astroport/tip
COPY ./tip/sbotc.js /home/astroport/sbotc.js
RUN chmod +x /home/astroport/samples /home/astroport/tip /home/astroport/sbotc.js
USER astroport
WORKDIR /home/astroport/
RUN . ~/.bashrc && \
mkdir -p /home/astroport/.ssb/ && \
npm install -g sodium-native@3.0.0 ssb-backlinks@1.0.0 && \
npm install commander@5.0.0 ssb-client@4.9.0 pull-stream@3.6.14
VOLUME [ "/home/astroport/.ssb"]
ENTRYPOINT ["/bin/bash"]
CMD ["-c", "tail" ,"-f", "/dev/null"]

View File

@ -1,56 +0,0 @@
const {program} = require("commander");
const ssbClient = require('ssb-client');
const pull = require('pull-stream');
let convertToInt = (value) => {
return parseInt(value);
}
let throwProgram = (err) => {
console.error(err.message);
process.exit(1);
}
program.version('.0.0.1');
program
.requiredOption('-s, --host <value>', 'host name or ip of ssb-server', 'oasis')
.requiredOption('-p, --port <number>', 'port of ssb-server', convertToInt, 8008)
/**
* whoami command
*/
program
.command('whoami')
.description('return your identity')
.action(() => {
ssbClient({host:program.host, port:program.port}, (err, sbot) => {
if(err) throwProgram(err)
sbot.whoami((err, identity) =>{
if(err) throwProgram
console.log(JSON.stringify(identity));
sbot.close();
})
})
});
/**
* query
*/
program
.command('query <query>')
.description('you can execute a query')
.action((query) => {
ssbClient({host:program.host, port:program.port}, (err, sbot) =>{
if(err) throwProgram(err);
pull(sbot.query.read({query:JSON.parse(query)}),pull.collect( (err, array) => {
if(err) throwProgram(err);
array.forEach((result) => {
console.log(JSON.stringify(result));
})
sbot.close();
}))
})
});
program.parse(process.argv);

View File

@ -1,4 +0,0 @@
#!/bin/bash
. ~/.bashrc
node ~/sbotc.js $@

View File

@ -1,531 +0,0 @@
#!/bin/bash
################################################################################
#
# Authors:
#
# [@cel](@f/6sQ6d2CMxRUhLpspgGIulDxDCwYD7DzFzPNr7u5AU=.ed25519)
# [@Fred](@9BbJwPDjcyIqrOUPNn0nJZBduWdIrpMk3Cjz5MP361s=.ed25519)
# [@Boris](@l5nYExWYIgDLV6BYHOJPoI97jIUyTdSm8CTLpQ0XeOg=.ed25519)
# [@poka](@vDQif9KU3T78XJx+NliK+wdo1vmehHZCWqD+3X700Uk=.ed25519)
# @[chamalow](@qio8/4L4vnzq3qRD0dqKI7sTpey54u8ZWbaICfpJOZw=.ed25519)
#
# Version: 1.0
#
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
#
###########################################################################################
# PREVENT DOUBLE PAYEMENT
# ADD Ğ1 Layer 10 LOVE to message writer you like !
############################################################################################
# Customizable
# debugMsgMode, when set to 1 does doesn't send transaction and does not update "last timestamp"
debugMsgMode=0
# If you don't want to wait
readable=1
minimumAmountPerLikeInUD="0.1"
############################################################################################
# Let's get Ğ1 public and private keys
g1pub=$(cat ~/.ssb/secret.dunikey | grep "pub" | cut -d ' ' -f 2)
g1priv=$(cat ~/.ssb/secret.dunikey | grep "sec" | cut -d ' ' -f 2)
# SSB pubkey
ssbpub=$(cat ~/.ssb/secret | grep public\" | cut -d ' ' -f 4 | cut -d '.' -f 1 | sed s/\"//g)
defaultAmountPerLikeInUD="0.1"
bold=$(tput bold)
normal=$(tput sgr0)
ssbMaxSize=8192
baseSizeOfAMessageFile=$(wc -c samples/message.json | awk '{print $1}')
sizeOfATagMention=$(wc -c samples/tag_mention.json | awk '{print $1}')
sizeOfAUserMention=$(wc -c samples/user_mention.json | awk '{print $1}')
sizeOfAPostMention=$(wc -c samples/post_mention.json | awk '{print $1}')
############################################################################################
#### CHECK LIKE AND SEND LOVE
# Let's get Ğ1 account balance
echo ""
echo -e "${bold}Welcome${normal} to the Ğ1/SSB-like microdonation system!\n"
if [[ $readable -eq 1 ]]; then sleep 1; fi
echo "MMMMMMMMMMMMMNk;'cdxxd:,c0WMMMMMMMMMMMMM
MMMMMMMMMMMMMNx,. .;kWMMMMMMMMMMMMM
MMMMMMMMMMMMMMMNOdlccld0NMMMMMMMMMMMMMMM
MMMMMMMMMMMWXko:,'....',:okXWMMMMMMMMMMM
MMMMMMMMMNk:. .cOWMMMMMMMMM
MMMMMMMW0: .c0MMMMMMMM"
if [[ $readable -eq 1 ]]; then sleep 1; fi
echo "MMMMMMWk. 'lxkOOkdc' .cOWMMMMMMM
MMMMMMO' 'kNMMMMMMMMNxcoOXWMMMMMMMMM
MMMMMNl '0MMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMX; cNMMMMMMMNOkkkkkkkkkkONMMMMM
MMMMMNc ;XMMMMMMMNd' .OMMMMM
MMMMMWx. cKMMMMMMMWKc. .OMMMMM
MMMMMMNo. .lkKXNNXKkc. .OMMMMM"
if [[ $readable -eq 1 ]]; then sleep 1; fi
echo "MMMMMMMNd. ...... .OMMMMM
MMMMMMMMWKl. 'c:. .OMMMMM
MMMMMMMMMMWXkc,.. ..,lkXWWO:;OMMMMM
MMMMMMMMMMMMMMWX0OxddxO0XWMMMMMMWXNMMMMM
MMMMMMMMMMMMMMMMNx;'',dNMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMK, '0MMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMNd. .oNMMMMMMMMMMMMMMMM
"
if [[ $readable -eq 1 ]]; then sleep 1; fi
printf "You know your SSB pubkey:\n%s\n\n" $ssbpub
if [[ $readable -eq 1 ]]; then sleep 2; fi
printf "...but did you know it is also a valid Ğ1 wallet?\n%s\n\n" $g1pub
if [[ $readable -eq 1 ]]; then sleep 2; fi
printf "Let's check the current balance of your wallet!\n\n"
if [[ $readable -eq 1 ]]; then sleep 1; fi
printf "I am interrogating the Ğ1 blockchain to check if anyone has already sent you Ğ1...\n\n"
if [[ $readable -eq 1 ]]; then sleep 2; fi
printf "A moment please...\n\n"
if [[ $readable -eq 1 ]]; then sleep 1; fi
silkajRelativeAmountPattern='Total\sRelative\s+=\s+(.*)\s+UD'
duniter_servers[0]="duniter-g1.p2p.legal:443"
duniter_servers[1]="g1.duniter.org:443"
duniter_servers[2]="g1.presles.fr:443"
duniter_servers[3]="balboa.altsysnet.com:10900"
duniter_servers[4]="remuniter.cgeek.fr:16120"
duniter_servers[5]="duniter.moul.re:443"
duniter_servers[6]="77.152.31.154:20901"
duniter_servers[7]="duniter.g1.1000i100.fr:443"
silkajExitCode=1
i=0
while [ $silkajExitCode -ne 0 ] && [ $i -lt ${#duniter_servers[@]} ]
do
echo "Testing server ${duniter_servers[$i]}..."
echo ""
silkajOutput=$(silkaj -p "${duniter_servers[$i]}" balance $g1pub 2>/dev/null)
silkajExitCode=$?
((i++))
done
if [ $silkajExitCode -eq 1 ]
then
echo "The server did not respond well. Please try again."
exit 1
fi
if [[ $silkajOutput =~ $silkajRelativeAmountPattern ]]
then
balance="${BASH_REMATCH[1]}"
else
echo "Account balance wasn't found."
exit 1
fi
printf "You have ${bold}%s UDĞ1${normal} on your Duniter Ğ1 wallet.\n\n" "$balance"
if [[ $readable -eq 1 ]]; then sleep 2; fi
printf "Want to show your appreciation of your fellow butts' posts while helping spreading awareness about libre currencies?\n\n"
if [[ $readable -eq 1 ]]; then sleep 3; fi
# BEGIN timestamp computation
self=$(sbotc whoami | jq -r .id) || exit 1
ssb_dir=~/.${ssb_appname:-ssb}
id_part=$(echo "$self" | sed 's/\//_/g' | tail -c +2 | head -c 9)
state_file=$ssb_dir/likes-g1-$id_part.ts
current_ts=$(date -u +%s%N | cut -b1-13)
if [ -s "$state_file" ]
then
last_ts=$(cat "$state_file") || exit 1
else
# timestamp from 24h ago
last_ts=$((current_ts - 24*3600*1000 - 1))
#else last_ts=null
fi
days_from_last_tx=$(( (current_ts - last_ts) / (24*60*60*1000) ))
# END timestamp computation
printf "First, let's see how much ❤ you gave lately...\n\n"
if [[ $readable -eq 1 ]]; then sleep 1; fi
declare -A likesNbPerAuthor
declare -A likedPosts
declare -A likesNbPerPost
declare -A postsTimestamps
declare -A excerpts
totalLikesGiven=0
process_msg() {
msg=$1
target_id=$(printf %s "$msg" | jq -r '.value?.content?.vote?.link') || return 1
target_msg=$(sbotc query '[{"$filter":{"value":{"content":{}},"key":"'"$target_id"'"}}]') || return 1
target_author=$(printf %s "$target_msg" | jq -r .author) || return 1
msg_content=$(printf %s "$target_msg" | jq -r .content?.text) || return 1
# beware of markdown !
msg_excerpt=${msg_content:0:10}
#root_id=$(printf %s "$target_msg" | jq -r .content?.root) || return 1
#[[ $root_id = "null" ]] && root_id=$target_id
}
process_author() {
author_id=$1
g1_author=$(echo $author_id | cut -d '.' -f 1 | cut -d '@' -f2 | base64 -d | base58)
author_name=$(sbotc query '[{"$filter":{"value":{"content":{"about":"'"$author_id"'"}}}}]' | jq .value?.content?.name | grep -v null | tail -n 1)
author_name=${author_name:1:-1}
}
authorsNb=0
i=0
messages=$(sbotc query '[{"$filter":{"value":{"author":"'"$self"'","content":{"type":"vote","vote":{"expression":"Like"}},"timestamp":{"$gt":'"$last_ts"'}}}}]')
while read -r msg
do
priv=$(printf %s "$msg" | jq .value.content.private)
if [[ $priv = true ]]
then
printf "Private message $priv, continue to next one\n" >&2
continue
fi
if ! process_msg "$msg"
then
msg_id=$(printf %s "$msg" | jq -r .key)
printf '\nUnable to process message %s\n' "$msg_id" >&2
exit 1
fi
if [[ $g1_author = $g1pub ]]; then
echo "I LIKE MY MESSAGE $target_id"
else
((totalLikesGiven++))
if [[ ${likesNbPerAuthor[$target_author]} -eq 0 ]]
then
likesNbPerAuthor[$target_author]=1
likedPosts[$target_author]=""
else
likesNbPerAuthor[$target_author]=$((${likesNbPerAuthor[$target_author]} + 1))
fi
if [[ ${likesNbPerPost[$target_id]} -eq 0 ]]
then
likesNbPerPost[$target_id]=1
likedPosts[$target_author]+=$target_id
likedPosts[$target_author]+="\n"
else
((likesNbPerPost[$target_id]++))
fi
excerpts[$target_id]=$msg_excerpt
# We cannot use this anymore
# (now saving current_ts once all tx have been sent)
#
# if ! postsTimestamps[$target_id]=$(printf %s "$msg" | jq -r .value.timestamp)
#then
# printf 'Unable to get message timestamp\n' >&2
# exit 1
#fi
((i++))
fi
done < <(echo "$messages" | jq -c)
if [[ $totalLikesGiven -eq 0 ]]
then
printf "You did not give any like during the past %s days or they have already been processed.\n\n" "$days_from_last_tx"
printf "Try again in a few days.\n\n"
fi
printf "You gave ${bold}%s❤${normal} during the past %s days.\n\n" "$totalLikesGiven" "$days_from_last_tx"
if [[ $readable -eq 1 ]]; then sleep 2; fi
tx_are_possible=0
while [[ $tx_are_possible -eq 0 ]]
do
printf "How many UDĞ1 do you want to send per each like you gave? (minimum is ${bold}%s UDĞ1${normal}) " "$minimumAmountPerLikeInUD"
read a
printf "\n"
if [[ -z $a ]]
then
amountPerLikeInUD=$minimumAmountPerLikeInUD
else
amountPerLikeInUD=$a
fi
amountGiven=$(echo "$totalLikesGiven * $amountPerLikeInUD" | bc -l)
has_enough_money=$(( $(echo "$amountGiven <= $balance" | bc -l) ))
amountPerLike_is_enough=$(( $(echo "$amountPerLikeInUD >= $minimumAmountPerLikeInUD" | bc -l) ))
tx_are_possible=$(( $has_enough_money && $amountPerLike_is_enough ))
if [[ $readable -eq 1 ]]; then sleep 1; fi
if [[ $tx_are_possible -eq 0 ]] ; then
if [[ $has_enough_money -eq 0 ]] ; then
printf "You don't have enough UDĞ1 to send all transactions.\n\n"
if [[ $readable -eq 1 ]]; then sleep 1; fi
printf "${bold}%s UDĞ1${normal} are needed.\n\n" "$amountGiven"
if [[ $readable -eq 1 ]]; then sleep 1; fi
elif [[ $amountPerLike_is_enough -eq 0 ]] ; then
printf "Minimum amount per like is %s UDĞ1.\n\n" $minimumAmountPerLikeInUD
if [[ $readable -eq 1 ]]; then sleep 1; fi
fi
printf "Try again with a different amount per like.\n\n"
maxAmountPerLike=$(awk -vp=$balance -vq=$totalLikesGiven 'BEGIN{printf "%.2f" ,p / q}')
if [[ $readable -eq 1 ]]; then sleep 1; fi
printf "Maximum amount per like possible: ${bold}%s UDĞ1${normal}\n\n" "$maxAmountPerLike"
if [[ $readable -eq 1 ]]; then sleep 1; fi
else
newBalance=$(echo "$balance - $amountGiven" | bc -l)
printf "${bold}%s UDĞ1${normal} will be given.\n\n" "$amountGiven"
if [[ $readable -eq 1 ]]; then sleep 1; fi
printf "After sending transactions, your new balance will be ${bold}%s UDĞ1${normal}\n\n" "$newBalance"
if [[ $readable -eq 1 ]]; then sleep 1; fi
printf "Press ENTER to continue: " && read
printf "\n"
fi
done
# Let's construct thank you posts (tyPosts) and send transactions!
tyPostIndex=0
tyPosts[0]=""
tyPosts[0]+="# I tipped you for your posts!\n\n"
tyPosts[0]+=$(printf "Huge thanks to the ScuttleButt community for all the fascinating posts you allowed me to read in the past %s days." "$days_from_last_tx")
tyPosts[0]+="\n\nAs a means to thank you further, I have just sent you #Ğ1 libre money.\n\n"
tyPosts[0]+="These messages, though they might feel spammy (sorry) are also a way for the Ğ1 community to spread awareness about [libre currencies](https://libre-currency.org/) so we can build #resilience at every level.\n\n"
tyPosts[0]+="You can learn how to spend your freshly earned money at [https://git.p2p.legal/Axiom-Team/ssb-g1-tip](https://git.p2p.legal/Axiom-Team/ssb-g1-tip)\n\n"
tyPosts[0]+="Below is the list of SSB users whose content I liked recently, and the amount each one was given:\n\n"
tableHeaders='| thanks to | for their posts | tip |\n'
tableHeaders+='| --- | --- | ---- |\n'
sizeOfTableHeaders=$(printf "%s" "$tableHeaders" | wc -c)
tyPosts[0]+=$tableHeaders
# for message size calculation
# update following if you add tags in the message :
tags[0]="Ğ1"
tags[1]="resilience"
sizeOfTags=0
for t in ${!tags[@]}
do
tagSize=$(printf "%s" "${tags[t]}" | wc -c)
(( sizeOfTags+=sizeOfATagMention + tagSize ))
done
firstPostContentSize=$(printf "%s" "${tyPosts[0]}" | wc -c)
tyPostsSizes[0]=$((baseSizeOfAMessageFile + firstPostContentSize + sizeOfTags))
nbOfAuthors=${#likesNbPerAuthor[@]}
authorNum=1
for author_id in ${!likesNbPerAuthor[@]}
do
process_author $author_id
# (Legacy) saving authors we have already mentionned in a message
likedAuthorsFile=$ssb_dir/db/g1likes
if [ ! -f $likedAuthorsFile ]; then
touch $likedAuthorsFile
fi
if ! grep -Fxq $author_id $likedAuthorsFile; then
echo $author_id >> $likedAuthorsFile
fi
tipAmount=$(bc <<< "${likesNbPerAuthor[$author_id]} * $amountPerLikeInUD")
newLine=''
newLine+=$(printf "| [@%s](%s) " "$author_name" "$author_id")
newLine+="| "
sizeOfAuthorName=$(printf "%s" "$author_name" | wc -c)
sizeOfAuthorId=$(printf "%s" "$author_id" | wc -c)
newLineSize=0
(( newLineSize+=sizeOfAUserMention + sizeOfAuthorName + sizeOfAuthorId))
p=${likedPosts[$author_id]}
thisAuthorLikedPosts=( ${p//\\n/ } )
isFirstPostOfThisAuthor=1
for likedPostId in ${thisAuthorLikedPosts[@]}
do
if [[ $isFirstPostOfThisAuthor -eq 1 ]]
then
isFirstPostOfThisAuthor=0
else
newLine+=", "
(( newLineSize+=2 ))
fi
newLine+=$(printf " %s❤" "${likesNbPerPost[$likedPostId]}")
newLine+=$(printf "[\`%s\`](%s)" "${excerpts[$likedPostId]}" "$likedPostId")
sizeOfExcerpt=${#excerpts[$likedPostId]}
(( sizeOfExcerpt+=2 )) # for before ` and after `
sizeOfLikedPostId=$(printf "%s" "$likedPostId" | wc -c)
(( newLineSize+=sizeOfAPostMention + sizeOfExcerpt + sizeOfLikedPostId ))
done
newLine+=$(printf "| %s UDĞ1 " "$tipAmount")
newLine+="|\n"
(( newLineSize+=$(printf "%s" "$newLine" | wc -c) ))
# printf "total size: %s\n\n" "$((${tyPostsSizes[$tyPostIndex]} + $newLineSize))"
# If adding new line would exceed max size, we create a new thank you post
sizeWithNewLine=${tyPostsSizes[$tyPostIndex]}
(( sizeWithNewLine+=newLineSize ))
if [[ $sizeWithNewLine -gt $ssbMaxSize ]]
then
printf "size before split: %s\n\n" "${tyPostsSizes[$tyPostIndex]}"
printf "size with new line: %s\n\n" "$sizeWithNewLine"
printf "size of new line: %s\n\n" "$newLineSize"
(( tyPostIndex++ ))
tyPosts[$tyPostIndex]+=$tableHeaders
(( tyPostsSizes[$tyPostIndex]=baseSizeOfAMessageFile + sizeOfTableHeaders ))
fi
tyPosts[$tyPostIndex]+=$newLine
(( tyPostsSizes[$tyPostIndex]+=newLineSize ))
if [[ $debugMsgMode -eq 0 ]]
then
if [[ $authorNum -ne 1 ]]
then
sleep 20 # DO NOT OVER CHARGE DUNITER
fi
#printf '%s\n' "silkaj -af --file ~/.ssb/secret.dunikey tx --output $g1_author --amountUD $tipAmount --comment "Thx for your cool posts on ScuttleButt"
silkaj -p "$duniter_server" -af --file ~/.ssb/secret.dunikey tx --output $g1_author --amountUD $tipAmount --comment "Thx for your cool posts on ScuttleButt" -y 2>/dev/null
printf "\n${bold}%s UDĞ1${normal} sent to %s!\n\n" "$tipAmount" "$author_name"
fi
(( authorNum++ ))
done
# Let's save the current timestamp
if [[ $debugMsgMode -eq 0 ]]
then
if ! echo "$current_ts" > "$state_file"~
then
printf 'Unable to write to backup state file.\n' >&2
exit 1
fi
if ! mv "$state_file"~ "$state_file"
then
printf 'Unable to write to state file. Update state file manually to prevent tips to %s from being processed twice.\n' "$author_name" >&2
exit 1
fi
fi
printf "\n%s UDĞ1 sent to %s butts!\n\n" "$amountGiven" "${#likesNbPerAuthor[@]}"
# Let's publicly thank everyone!
#echo -e "${tyPosts[$n]}"
# the following produces error:
# "sbotc: unexpected end of parent stream"
# must be a non-escaped quote problem...
#thank_you_msg=$(printf "%q" "${tyPosts[$n]}")
#sbotc publish '{"type":"post","text":"'"$thank_you_msg"'"}' 2>&1>/dev/null
printf "What now ?\n\n"
if [[ $readable -eq 1 ]]; then sleep 1; fi
date=$(date -u +%Y-week-%W)
if [[ ${#tyPosts[@]} -eq 1 ]]
then
msg_filename=thank-your-butts-$date
echo -e ${tyPosts[$n]} > ~/$msg_filename.md
else
for i in ${!tyPosts[@]}
do
part=$((i + 1))
msg_filename=thank-your-butts-$date
echo -e ${tyPosts[$i]} > ~/$msg_filename-part-$part.md
done
fi
printf "A surprise is awaiting in your home dir (~).\n\n"
if [[ $readable -eq 1 ]]; then sleep 2; fi
if [[ ${#tyPosts[@]} -eq 1 ]]
then
printf "It's a file.\n\n"
if [[ $readable -eq 1 ]]; then sleep 2; fi
printf "It's called $msg_filename.md\n\n"
else
printf "It's %s files.\n\n" "${#tyPosts[@]}"
if [[ $readable -eq 1 ]]; then sleep 2; fi
printf "The first one is called $msg_filename-part-1.md.\n\n"
fi
if [[ $readable -eq 1 ]]; then sleep 2; fi
printf "Customize it to your needs to thank your fellow butts publicly and help spread awareness about libre currencies :-)\n\n"
if [[ $readable -eq 1 ]]; then sleep 3; fi
printf "Then delete it.\n\n"
if [[ $readable -eq 1 ]]; then sleep 2; fi
printf "...because it won't self-destruct, haha :D \n\n"