Compare commits
No commits in common. "master" and "dev-fred" have entirely different histories.
66
Dockerfile
|
@ -1,66 +0,0 @@
|
|||
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
|
||||
|
||||
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
|
||||
|
||||
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 && \
|
||||
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
|
||||
|
||||
VOLUME [ "/home/astroport/.ssb/" ]
|
||||
EXPOSE 8008
|
||||
|
||||
ENTRYPOINT [ "/bin/bash" ]
|
||||
CMD ["docker-entrypoint.sh"]
|
After Width: | Height: | Size: 101 KiB |
After Width: | Height: | Size: 87 KiB |
Before Width: | Height: | Size: 4.0 MiB |
After Width: | Height: | Size: 820 KiB |
Before Width: | Height: | Size: 61 KiB |
After Width: | Height: | Size: 77 KiB |
BIN
doc/tip.gif
Before Width: | Height: | Size: 3.2 MiB |
Before Width: | Height: | Size: 146 KiB |
|
@ -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:
|
|
@ -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 ""
|
218
install.sh
|
@ -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
|
||||
|
|
|
@ -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"]
|
|
@ -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
|
@ -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`)
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
|
||||
{
|
||||
"link": "",
|
||||
"name": ""
|
||||
},
|
|
@ -1,4 +0,0 @@
|
|||
|
||||
{
|
||||
"link": "#"
|
||||
},
|
|
@ -1,5 +0,0 @@
|
|||
|
||||
{
|
||||
"link": "",
|
||||
"name": ""
|
||||
},
|
|
@ -0,0 +1 @@
|
|||
Subproject commit f1337fffb2467ae35d1e694221cd0fd9ba97923f
|
|
@ -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
|
@ -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"
|
||||
|
|
@ -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"]
|
56
tip/sbotc.js
|
@ -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);
|
|
@ -1,4 +0,0 @@
|
|||
#!/bin/bash
|
||||
. ~/.bashrc
|
||||
|
||||
node ~/sbotc.js $@
|
531
tip/tip.sh
|
@ -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"
|
||||
|