diff --git a/zen/jaklis.old/.env b/zen/jaklis.old/.env deleted file mode 100644 index ea6bd51..0000000 --- a/zen/jaklis.old/.env +++ /dev/null @@ -1,5 +0,0 @@ -DUNIKEY="/.zen/secret.dunikey" # Chemin du fichier de trousseau Ḡ1 de l'émetteur, au format PubSec -POD="https://data.gchange.fr" # Noeud Gchange utilisé pour l'envoi du message -#POD="https://g1.data.duniter.fr" # Noeud Cecium+ utilisé pour l'envoi du message -#POD="https://g1.data.le-sou.org" # Adresse du pod Cesium de secours -#POD="https://g1.data.e-is.pro" diff --git a/zen/jaklis.old/.env.template b/zen/jaklis.old/.env.template deleted file mode 100644 index dd81446..0000000 --- a/zen/jaklis.old/.env.template +++ /dev/null @@ -1,6 +0,0 @@ -DUNIKEY="" # Chemin de la clé privé Ḡ1 de l'émetteur, au format PubSec -#POD="https://g1.data.duniter.fr" # Adresse du pod Cesium ou Gchange à utiliser -POD="https://g1.data.le-sou.org" # Adresse du pod Cesium de secours -#POD="https://data.gchange.fr" # Adresse du pod ḠChange à utiliser - -NODE="https://g1.librelois.fr/gva" diff --git a/zen/jaklis.old/README.md b/zen/jaklis.old/README.md deleted file mode 100644 index 59f1e61..0000000 --- a/zen/jaklis.old/README.md +++ /dev/null @@ -1,76 +0,0 @@ -# Client CLI for Cesium+/Ḡchange pod -## Installation - -Linux: -``` -bash setup.sh -``` - -Autre: -``` -Débrouillez-vous. -``` - -## Utilisation - -Renseignez optionnellement le fichier **.env** (Généré lors de la première tentative d'execution, ou à copier depuis .env.template). - -``` -./jaklis.py -h -``` - -``` -usage: jaklis.py [-h] [-v] [-k KEY] [-n NODE] {read,send,delete,get,set,erase,like,unlike,pay,history,balance} ... - -Client CLI pour Cesium+ et Ḡchange - -optional arguments: - -h, --help show this help message and exit - -v, --version Affiche la version actuelle du programme - -k KEY, --key KEY Chemin vers mon trousseau de clé (PubSec) - -n NODE, --node NODE Adresse du noeud Cesium+, Gchange ou Duniter à utiliser - -Commandes de jaklis: - {read,send,delete,get,set,erase,like,unlike,pay,history,balance} - read Lecture des messages - send Envoi d'un message - delete Supression d'un message - get Voir un profile Cesium+ - set Configurer son profile Cesium+ - erase Effacer son profile Cesium+ - like Voir les likes d'un profile / Liker un profile (option -s NOTE) - unlike Supprimer un like - pay Payer en Ḡ1 - history Voir l'historique des transactions d'un compte Ḡ1 - balance Voir le solde d'un compte Ḡ1 - -``` - -Utilisez `./jaklis CMD -h` où `CMD` est la commande souhaité pour obtenir l'aide détaillé de cette commande. - -### Exemples: - -Lire les 10 derniers messages de mon compte indiqué dans le fichier `.env` (par defaut 3 messages): -``` -./jaklis read -n10 -``` - -Envoyer un message à la clé publique `Do99s6wQR2JLfhirPdpAERSjNbmjjECzGxHNJMiNKT3P` avec un fichier de trousseau particulier: -``` -./jaklis.py -k /home/saucisse/mon_fichier_de_trousseau.dunikey send -d Do99s6wQR2JLfhirPdpAERSjNbmjjECzGxHNJMiNKT3P -t "Objet du message" -m "Corps de mon message" -``` - -Noter 4 étoiles le profile `S9EJbjbaGPnp26VuV6fKjR7raE1YkNhUGDgoydHvAJ1` sur gchange: -``` -./jaklis.py -n https://data.gchange.fr like -p S9EJbjbaGPnp26VuV6fKjR7raE1YkNhUGDgoydHvAJ1 -s 4 -``` - -Paramétrer mon profile Cesium+: -``` -./jaklis.py set -n "Sylvain Durif" -v "Bugarach" -a "42 route de Vénus" -d "Christ cosmique" -pos 48.539927 2.6608169 -s https://www.creationmonetaire.info -A mon_avatar.png -``` - -Effacer mon profile Gchange: -``` -./jaklis.py -n https://data.gchange.fr erase -``` diff --git a/zen/jaklis.old/jaklis.py b/zen/jaklis.old/jaklis.py deleted file mode 100755 index 0f40166..0000000 --- a/zen/jaklis.old/jaklis.py +++ /dev/null @@ -1,226 +0,0 @@ -#!/usr/bin/env python3 - -import argparse, sys, os, getpass, string, random -from os.path import join, dirname -from shutil import copyfile -from dotenv import load_dotenv -from duniterpy.key import SigningKey - -__version__ = "0.0.2" - -MY_PATH = os.path.realpath(os.path.dirname(sys.argv[0])) + '/' - -# Get variables environment -if not os.path.isfile(MY_PATH + '.env'): - copyfile(MY_PATH + ".env.template",MY_PATH + ".env") -dotenv_path = join(dirname(__file__),MY_PATH + '.env') -load_dotenv(dotenv_path) - -# Parse arguments -parser = argparse.ArgumentParser(description="Client CLI pour Cesium+ et Ḡchange") -parser.add_argument('-v', '--version', action='store_true', help="Affiche la version actuelle du programme") -parser.add_argument('-k', '--key', help="Chemin vers mon trousseau de clé (PubSec)") -parser.add_argument('-n', '--node', help="Adresse du noeud Cesium+, Gchange ou Duniter à utiliser") - -subparsers = parser.add_subparsers(title="Commandes de jaklis", dest="cmd") -read_cmd = subparsers.add_parser('read', help="Lecture des messages") -send_cmd = subparsers.add_parser('send', help="Envoi d'un message") -delete_cmd = subparsers.add_parser('delete', help="Supression d'un message") -getProfile_cmd = subparsers.add_parser('get', help="Voir un profile Cesium+") -setProfile_cmd = subparsers.add_parser('set', help="Configurer son profile Cesium+") -eraseProfile_cmd = subparsers.add_parser('erase', help="Effacer son profile Cesium+") -like_cmd = subparsers.add_parser('like', help="Voir les likes d'un profile / Liker un profile (option -s NOTE)") -unlike_cmd = subparsers.add_parser('unlike', help="Supprimer un like") -pay_cmd = subparsers.add_parser('pay', help="Payer en Ḡ1") -history_cmd = subparsers.add_parser('history', help="Voir l'historique des transactions d'un compte Ḡ1") -balance_cmd = subparsers.add_parser('balance', help="Voir le solde d'un compte Ḡ1") - -# Messages management -read_cmd.add_argument('-n', '--number',type=int, default=3, help="Affiche les NUMBER derniers messages") -read_cmd.add_argument('-j', '--json', action='store_true', help="Sort au format JSON") -read_cmd.add_argument('-o', '--outbox', action='store_true', help="Lit les messages envoyés") - -send_cmd.add_argument('-d', '--destinataire', required=True, help="Destinataire du message") -send_cmd.add_argument('-t', '--titre', help="Titre du message à envoyer") -send_cmd.add_argument('-m', '--message', help="Message à envoyer") -send_cmd.add_argument('-f', '--fichier', help="Envoyer le message contenu dans le fichier 'FICHIER'") -send_cmd.add_argument('-o', '--outbox', action='store_true', help="Envoi le message sur la boite d'envoi") - -delete_cmd.add_argument('-i', '--id', action='append', nargs='+', required=True, help="ID(s) du/des message(s) à supprimer") -delete_cmd.add_argument('-o', '--outbox', action='store_true', help="Suppression d'un message envoyé") - -# Profiles management -setProfile_cmd.add_argument('-n', '--name', help="Nom du profile") -setProfile_cmd.add_argument('-d', '--description', help="Description du profile") -setProfile_cmd.add_argument('-v', '--ville', help="Ville du profile") -setProfile_cmd.add_argument('-a', '--adresse', help="Adresse du profile") -setProfile_cmd.add_argument('-pos', '--position', nargs=2, help="Points géographiques (lat + lon)") -setProfile_cmd.add_argument('-s', '--site', help="Site web du profile") -setProfile_cmd.add_argument('-A', '--avatar', help="Chemin vers mon avatar en PNG") - -getProfile_cmd.add_argument('-p', '--profile', help="Nom du profile") -getProfile_cmd.add_argument('-a', '--avatar', action='store_true', help="Récupérer également l'avatar au format raw base64") - -# Likes management -like_cmd.add_argument('-p', '--profile', help="Profile cible") -like_cmd.add_argument('-s', '--stars', type=int, help="Nombre d'étoile") -unlike_cmd.add_argument('-p', '--profile', help="Profile à déliker") - -# GVA usage -pay_cmd.add_argument('-p', '--pubkey', help="Destinataire du paiement") -pay_cmd.add_argument('-a', '--amount', type=float, help="Montant de la transaction") -pay_cmd.add_argument('-c', '--comment', default="", help="Commentaire de la transaction") -pay_cmd.add_argument('-m', '--mempool', action='store_true', help="Utilise les sources en Mempool") -pay_cmd.add_argument('-v', '--verbose', action='store_true', help="Affiche le résultat JSON de la transaction") - -history_cmd.add_argument('-p', '--pubkey', help="Clé publique du compte visé") -history_cmd.add_argument('-j', '--json', action='store_true', help="Affiche le résultat en format JSON") -history_cmd.add_argument('--nocolors', action='store_true', help="Affiche le résultat en noir et blanc") - -balance_cmd.add_argument('-p', '--pubkey', help="Clé publique du compte visé") -balance_cmd.add_argument('-m', '--mempool', action='store_true', help="Utilise les sources en Mempool") - - -args = parser.parse_args() -cmd = args.cmd - -if args.version: - print(__version__) - sys.exit(0) - -if not cmd: - parser.print_help() - sys.exit(1) - -def createTmpDunikey(): - # Generate pseudo-random nonce - nonce=[] - for _ in range(32): - nonce.append(random.choice(string.ascii_letters + string.digits)) - nonce = ''.join(nonce) - keyPath = "/tmp/secret.dunikey-" + nonce - - key = SigningKey.from_credentials(getpass.getpass("Identifiant: "), getpass.getpass("Mot de passe: "), None) - key.save_pubsec_file(keyPath) - - return keyPath - -# Check if we need dunikey -try: - pubkey = args.pubkey -except: - pubkey = False -try: - profile = args.profile -except: - profile = False - -if cmd in ('history','balance','get') and (pubkey or profile): - noNeedDunikey = True - keyPath = False - try: - dunikey = args.pubkey - except: - dunikey = args.profile -else: - noNeedDunikey = False - if args.key: - dunikey = args.key - keyPath = False - else: - dunikey = os.getenv('DUNIKEY') - if not dunikey: - keyPath = createTmpDunikey() - dunikey = keyPath - else: - keyPath = False - if not os.path.isfile(dunikey): - HOME = os.getenv("HOME") - dunikey = HOME + dunikey - if not os.path.isfile(dunikey): - sys.stderr.write('Le fichier de trousseau {0} est introuvable.\n'.format(dunikey)) - sys.exit(1) - - -# Construct CesiumPlus object -if cmd in ("read","send","delete","set","get","erase","like","unlike"): - from lib.cesium import CesiumPlus - - if args.node: - pod = args.node - else: - pod = os.getenv('POD') - if not pod: - pod="https://g1.data.le-sou.org" - - cesium = CesiumPlus(dunikey, pod, noNeedDunikey) - - # Messaging - if cmd == "read": - cesium.read(args.number, args.outbox, args.json) - elif cmd == "send": - if args.fichier: - with open(args.fichier, 'r') as f: - msgT = f.read() - titre = msgT.splitlines(True)[0].replace('\n', '') - msg = ''.join(msgT.splitlines(True)[1:]) - if args.titre: - titre = args.titre - msg = msgT - elif args.titre and args.message: - titre = args.titre - msg = args.message - else: - titre = input("Indiquez le titre du message: ") - msg = input("Indiquez le contenu du message: ") - - cesium.send(titre, msg, args.destinataire, args.outbox) - - elif cmd == "delete": - cesium.delete(args.id[0], args.outbox) - - # Profiles - elif cmd == "set": - cesium.set(args.name, args.description, args.ville, args.adresse, args.position, args.site, args.avatar) - elif cmd == "get": - cesium.get(args.profile, args.avatar) - elif cmd == "erase": - cesium.erase() - - # Likes - elif cmd == "like": - if args.stars or args.stars == 0: - cesium.like(args.stars, args.profile) - else: - cesium.readLikes(args.profile) - elif cmd == "unlike": - cesium.unLike(args.profile) - -# Construct GVA object -elif cmd in ("pay","history","balance"): - from lib.gva import GvaApi - - if args.node: - node = args.node - else: - node = os.getenv('NODE') - if not node: - node="https://g1.librelois.fr/gva" - - if args.pubkey: - destPubkey = args.pubkey - else: - destPubkey = False - - gva = GvaApi(dunikey, node, destPubkey, noNeedDunikey) - - if cmd == "pay": - gva.pay(args.amount, args.comment, args.mempool, args.verbose) - if cmd == "history": - gva.history(args.json, args.nocolors) - if cmd == "balance": - gva.balance(args.mempool) - - -if keyPath: - os.remove(keyPath) diff --git a/zen/jaklis.old/lib/__pycache__/cesium.cpython-36.pyc b/zen/jaklis.old/lib/__pycache__/cesium.cpython-36.pyc deleted file mode 100644 index 08355fc..0000000 Binary files a/zen/jaklis.old/lib/__pycache__/cesium.cpython-36.pyc and /dev/null differ diff --git a/zen/jaklis.old/lib/__pycache__/cesium.cpython-38.pyc b/zen/jaklis.old/lib/__pycache__/cesium.cpython-38.pyc deleted file mode 100644 index 87af3c1..0000000 Binary files a/zen/jaklis.old/lib/__pycache__/cesium.cpython-38.pyc and /dev/null differ diff --git a/zen/jaklis.old/lib/__pycache__/cesiumCommon.cpython-36.pyc b/zen/jaklis.old/lib/__pycache__/cesiumCommon.cpython-36.pyc deleted file mode 100644 index d6fd2d2..0000000 Binary files a/zen/jaklis.old/lib/__pycache__/cesiumCommon.cpython-36.pyc and /dev/null differ diff --git a/zen/jaklis.old/lib/__pycache__/cesiumCommon.cpython-38.pyc b/zen/jaklis.old/lib/__pycache__/cesiumCommon.cpython-38.pyc deleted file mode 100644 index cc67099..0000000 Binary files a/zen/jaklis.old/lib/__pycache__/cesiumCommon.cpython-38.pyc and /dev/null differ diff --git a/zen/jaklis.old/lib/__pycache__/gva.cpython-36.pyc b/zen/jaklis.old/lib/__pycache__/gva.cpython-36.pyc deleted file mode 100644 index 5429345..0000000 Binary files a/zen/jaklis.old/lib/__pycache__/gva.cpython-36.pyc and /dev/null differ diff --git a/zen/jaklis.old/lib/__pycache__/gvaPay.cpython-36.pyc b/zen/jaklis.old/lib/__pycache__/gvaPay.cpython-36.pyc deleted file mode 100644 index e1fdfb5..0000000 Binary files a/zen/jaklis.old/lib/__pycache__/gvaPay.cpython-36.pyc and /dev/null differ diff --git a/zen/jaklis.old/lib/__pycache__/likes.cpython-36.pyc b/zen/jaklis.old/lib/__pycache__/likes.cpython-36.pyc deleted file mode 100644 index ad140ef..0000000 Binary files a/zen/jaklis.old/lib/__pycache__/likes.cpython-36.pyc and /dev/null differ diff --git a/zen/jaklis.old/lib/__pycache__/likes.cpython-38.pyc b/zen/jaklis.old/lib/__pycache__/likes.cpython-38.pyc deleted file mode 100644 index 107a43b..0000000 Binary files a/zen/jaklis.old/lib/__pycache__/likes.cpython-38.pyc and /dev/null differ diff --git a/zen/jaklis.old/lib/__pycache__/messaging.cpython-36.pyc b/zen/jaklis.old/lib/__pycache__/messaging.cpython-36.pyc deleted file mode 100644 index 4034716..0000000 Binary files a/zen/jaklis.old/lib/__pycache__/messaging.cpython-36.pyc and /dev/null differ diff --git a/zen/jaklis.old/lib/__pycache__/messaging.cpython-38.pyc b/zen/jaklis.old/lib/__pycache__/messaging.cpython-38.pyc deleted file mode 100644 index ecd1ba0..0000000 Binary files a/zen/jaklis.old/lib/__pycache__/messaging.cpython-38.pyc and /dev/null differ diff --git a/zen/jaklis.old/lib/__pycache__/natools.cpython-36.pyc b/zen/jaklis.old/lib/__pycache__/natools.cpython-36.pyc deleted file mode 100644 index 06f0acf..0000000 Binary files a/zen/jaklis.old/lib/__pycache__/natools.cpython-36.pyc and /dev/null differ diff --git a/zen/jaklis.old/lib/__pycache__/natools.cpython-38.pyc b/zen/jaklis.old/lib/__pycache__/natools.cpython-38.pyc deleted file mode 100644 index 043f078..0000000 Binary files a/zen/jaklis.old/lib/__pycache__/natools.cpython-38.pyc and /dev/null differ diff --git a/zen/jaklis.old/lib/__pycache__/profiles.cpython-36.pyc b/zen/jaklis.old/lib/__pycache__/profiles.cpython-36.pyc deleted file mode 100644 index f316106..0000000 Binary files a/zen/jaklis.old/lib/__pycache__/profiles.cpython-36.pyc and /dev/null differ diff --git a/zen/jaklis.old/lib/__pycache__/profiles.cpython-38.pyc b/zen/jaklis.old/lib/__pycache__/profiles.cpython-38.pyc deleted file mode 100644 index 1ab12f7..0000000 Binary files a/zen/jaklis.old/lib/__pycache__/profiles.cpython-38.pyc and /dev/null differ diff --git a/zen/jaklis.old/lib/cesium.py b/zen/jaklis.old/lib/cesium.py deleted file mode 100644 index 6a07fd9..0000000 --- a/zen/jaklis.old/lib/cesium.py +++ /dev/null @@ -1,93 +0,0 @@ -import re, string, random, base64 -from lib.cesiumCommon import CesiumCommon, PUBKEY_REGEX -from lib.messaging import ReadFromCesium, SendToCesium, DeleteFromCesium -from lib.profiles import Profiles -from lib.likes import ReadLikes, SendLikes, UnLikes - -class CesiumPlus(CesiumCommon): - - #################### Messaging #################### - - def read(self, nbrMsg, outbox, isJSON): - readCesium = ReadFromCesium(self.dunikey, self.pod) - jsonMsg = readCesium.sendDocument(nbrMsg, outbox) - if isJSON: - jsonFormat = readCesium.jsonMessages(jsonMsg, nbrMsg, outbox) - print(jsonFormat) - else: - readCesium.readMessages(jsonMsg, nbrMsg, outbox) - - def send(self, title, msg, recipient, outbox): - sendCesium = SendToCesium(self.dunikey, self.pod) - sendCesium.recipient = recipient - - # Generate pseudo-random nonce - nonce=[] - for _ in range(32): - nonce.append(random.choice(string.ascii_letters + string.digits)) - sendCesium.nonce = base64.b64decode(''.join(nonce)) - - finalDoc = sendCesium.configDoc(sendCesium.encryptMsg(title), sendCesium.encryptMsg(msg)) # Configure JSON document to send - sendCesium.sendDocument(finalDoc, outbox) # Send final signed document - - def delete(self, idsMsgList, outbox): - deleteCesium = DeleteFromCesium(self.dunikey, self.pod) - # deleteCesium.issuer = recipient - for idMsg in idsMsgList: - finalDoc = deleteCesium.configDoc(idMsg, outbox) - deleteCesium.sendDocument(finalDoc, idMsg) - - #################### Profiles #################### - - def set(self, name=None, description=None, ville=None, adresse=None, position=None, site=None, avatar=None): - setProfile = Profiles(self.dunikey, self.pod) - document = setProfile.configDocSet(name, description, ville, adresse, position, site, avatar) - result = setProfile.sendDocument(document,'set') - - print(result) - return result - - def get(self, profile=None, avatar=None): - getProfile = Profiles(self.dunikey, self.pod, self.noNeedDunikey) - if not profile: - profile = self.pubkey - if not re.match(PUBKEY_REGEX, profile) or len(profile) > 45: - scope = 'title' - else: - scope = '_id' - - document = getProfile.configDocGet(profile, scope, avatar) - resultJSON = getProfile.sendDocument(document, 'get') - result = getProfile.parseJSON(resultJSON) - - print(result) - - def erase(self): - eraseProfile = Profiles(self.dunikey, self.pod) - document = eraseProfile.configDocErase() - result = eraseProfile.sendDocument(document,'erase') - - print(result) - - #################### Likes #################### - - def readLikes(self, profile=False): - likes = ReadLikes(self.dunikey, self.pod, self.noNeedDunikey) - document = likes.configDoc(profile) - result = likes.sendDocument(document) - result = likes.parseResult(result) - - print(result) - - def like(self, stars, profile=False): - likes = SendLikes(self.dunikey, self.pod) - document = likes.configDoc(profile, stars) - if document: - likes.sendDocument(document, profile) - - def unLike(self, pubkey, silent=False): - likes = UnLikes(self.dunikey, self.pod) - idLike = likes.checkLike(pubkey) - if idLike: - document = likes.configDoc(idLike) - likes.sendDocument(document, silent) diff --git a/zen/jaklis.old/lib/cesiumCommon.py b/zen/jaklis.old/lib/cesiumCommon.py deleted file mode 100644 index b68337d..0000000 --- a/zen/jaklis.old/lib/cesiumCommon.py +++ /dev/null @@ -1,51 +0,0 @@ -import sys, re, json -from hashlib import sha256 -from lib.natools import fmt, sign, get_privkey - -PUBKEY_REGEX = "(?![OIl])[1-9A-Za-z]{42,45}" - -def pp_json(json_thing, sort=True, indents=4): - # Print beautifull JSON - if type(json_thing) is str: - print(json.dumps(json.loads(json_thing), sort_keys=sort, indent=indents)) - else: - print(json.dumps(json_thing, sort_keys=sort, indent=indents)) - return None - -class CesiumCommon: - def __init__(self, dunikey, pod, noNeedDunikey=False): - self.pod = pod - self.noNeedDunikey = noNeedDunikey - # Get my pubkey from my private key - try: - self.dunikey = dunikey - if not dunikey: - raise ValueError("Dunikey is empty") - except: - sys.stderr.write("Please fill the path to your private key (PubSec)\n") - sys.exit(1) - - if noNeedDunikey: - self.pubkey = self.dunikey - else: - self.pubkey = get_privkey(dunikey, "pubsec").pubkey - - if not re.match(PUBKEY_REGEX, self.pubkey) or len(self.pubkey) > 45: - sys.stderr.write("La clé publique n'est pas au bon format.\n") - sys.exit(1) - - def signDoc(self, document): - # Generate hash of document - hashDoc = sha256(document.encode()).hexdigest().upper() - - # Generate signature of document - signature = fmt["64"](sign(hashDoc.encode(), get_privkey(self.dunikey, "pubsec"))[:-len(hashDoc.encode())]).decode() - - # Build final document - data = {} - data['hash'] = hashDoc - data['signature'] = signature - signJSON = json.dumps(data) - finalJSON = {**json.loads(signJSON), **json.loads(document)} - - return json.dumps(finalJSON) diff --git a/zen/jaklis.old/lib/crypt.py b/zen/jaklis.old/lib/crypt.py deleted file mode 100755 index ee4cfb2..0000000 --- a/zen/jaklis.old/lib/crypt.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env python3 - -import base64, base58, sys, string, random -from natools import get_privkey, box_decrypt, box_encrypt, fmt - -def getargv(arg:str, default:str="", n:int=1, args:list=sys.argv) -> str: - if arg in args and len(args) > args.index(arg)+n: - return args[args.index(arg)+n] - else: - return default - -cmd = sys.argv[1] - -dunikey = getargv("-k", "private.dunikey") -msg = getargv("-m", "test") -pubkey = getargv("-p") - -def decrypt(msg): - msg64 = base64.b64decode(msg) - return box_decrypt(msg64, get_privkey(dunikey, "pubsec"), pubkey).decode() - -def encrypt(msg): - return fmt["64"](box_encrypt(msg.encode(), get_privkey(dunikey, "pubsec"), pubkey)).decode() - -if cmd == 'decrypt': - clear = decrypt(msg) - print(clear) -elif cmd == 'encrypt': - clear = encrypt(msg) - print(clear) - diff --git a/zen/jaklis.old/lib/gva.py b/zen/jaklis.old/lib/gva.py deleted file mode 100644 index eaf22fd..0000000 --- a/zen/jaklis.old/lib/gva.py +++ /dev/null @@ -1,59 +0,0 @@ -import sys, re -from lib.natools import get_privkey -from lib.gvaPay import Transaction, PUBKEY_REGEX -from lib.gvaHistory import History -from lib.gvaBalance import Balance - -class GvaApi(): - def __init__(self, dunikey, node, pubkey, noNeedDunikey=False): - self.noNeedDunikey = noNeedDunikey - self.dunikey = dunikey - self.node = node - if noNeedDunikey: - self.pubkey = self.dunikey - else: - self.pubkey = get_privkey(dunikey, "pubsec").pubkey - - if pubkey: - self.destPubkey = pubkey - else: - self.destPubkey = self.pubkey - - try: - if not re.match(PUBKEY_REGEX, self.pubkey) or len(self.pubkey) > 45: - raise ValueError("La clé publique n'est pas au bon format.") - except: - sys.stderr.write("La clé publique n'est pas au bon format.\n") - raise - - try: - if not re.match(PUBKEY_REGEX, self.destPubkey) or len(self.destPubkey) > 45: - raise ValueError("La clé publique n'est pas au bon format.") - except: - sys.stderr.write("La clé publique n'est pas au bon format.\n") - raise - - #################### Payments #################### - - def pay(self, amount, comment, mempool, verbose): - gva = Transaction(self.dunikey, self.node, self.destPubkey, amount, comment, mempool, verbose) - gva.genDoc() - gva.checkTXDoc() - gva.signDoc() - return gva.sendTXDoc() - - def history(self, isJSON=False, noColors=False): - gva = History(self.dunikey, self.node, self.destPubkey) - gva.sendDoc() - transList = gva.parseHistory() - - if isJSON: - transJson = gva.jsonHistory(transList) - print(transJson) - else: - gva.printHistory(transList, noColors) - - def balance(self, useMempool): - gva = Balance(self.dunikey, self.node, self.destPubkey, useMempool) - balanceValue = gva.sendDoc() - print(balanceValue) diff --git a/zen/jaklis.old/lib/gvaBalance.py b/zen/jaklis.old/lib/gvaBalance.py deleted file mode 100644 index b148e7e..0000000 --- a/zen/jaklis.old/lib/gvaBalance.py +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env python3 - -import sys, re, os.path, json, ast -from termcolor import colored -from lib.natools import fmt, sign, get_privkey -from gql import gql, Client -from gql.transport.aiohttp import AIOHTTPTransport - -PUBKEY_REGEX = "(?![OIl])[1-9A-Za-z]{42,45}" - -class Balance: - - def __init__(self, dunikey, node, pubkey, useMempool=False): - self.dunikey = dunikey - self.pubkey = pubkey if pubkey else get_privkey(dunikey, "pubsec").pubkey - self.useMempool = useMempool - if not re.match(PUBKEY_REGEX, self.pubkey) or len(self.pubkey) > 45: - sys.stderr.write("La clé publique n'est pas au bon format.\n") - sys.exit(1) - - # Define Duniter GVA node - transport = AIOHTTPTransport(url=node) - self.client = Client(transport=transport, fetch_schema_from_transport=True) - - def sendDoc(self): - # Build balance generation document - queryBuild = gql( - """ - query ($pubkey: String!){ - balance(script: $pubkey) { - amount - } - } - """ - ) - paramsBuild = { - "pubkey": self.pubkey - } - - # Send balance document - try: - balanceResult = self.client.execute(queryBuild, variable_values=paramsBuild) - except Exception as e: - message = ast.literal_eval(str(e))["message"] - sys.stderr.write("Echec de récupération du solde:\n" + message + "\n") - sys.exit(1) - - balanceValue = balanceResult['balance']['amount']/100 - # print(balanceValue) - return balanceValue diff --git a/zen/jaklis.old/lib/gvaHistory.py b/zen/jaklis.old/lib/gvaHistory.py deleted file mode 100644 index a4f6400..0000000 --- a/zen/jaklis.old/lib/gvaHistory.py +++ /dev/null @@ -1,209 +0,0 @@ -#!/usr/bin/env python3 - -import sys, re, os.path, json, ast, time -from datetime import datetime -from termcolor import colored -from lib.natools import fmt, sign, get_privkey -from gql import gql, Client -from gql.transport.aiohttp import AIOHTTPTransport - -PUBKEY_REGEX = "(?![OIl])[1-9A-Za-z]{42,45}" - -class History: - - def __init__(self, dunikey, node, pubkey): - self.dunikey = dunikey - self.pubkey = pubkey if pubkey else get_privkey(dunikey, "pubsec").pubkey - self.node = node - if not re.match(PUBKEY_REGEX, self.pubkey) or len(self.pubkey) > 45: - sys.stderr.write("La clé publique n'est pas au bon format.\n") - sys.exit(1) - - # Define Duniter GVA node - transport = AIOHTTPTransport(url=node) - self.client = Client(transport=transport, fetch_schema_from_transport=True) - - def sendDoc(self): - # Build history generation document - queryBuild = gql( - """ - query ($pubkey: String!){ - transactionsHistory(pubkey: $pubkey) { - received { - writtenTime - issuers - outputs - comment - } - sent { - writtenTime - issuers - outputs - comment - } - receiving { - issuers - outputs - comment - } - sending { - issuers - outputs - comment - } - } - balance(script: $pubkey) { - amount - base - } - node { - peer { - currency - } - } - currentUd { - amount - base - } - } - """ - ) - paramsBuild = { - "pubkey": self.pubkey - } - - # Send history document - try: - self.historyDoc = self.client.execute(queryBuild, variable_values=paramsBuild) - except Exception as e: - message = ast.literal_eval(str(e))["message"] - sys.stderr.write("Echec de récupération de l'historique:\n" + message + "\n") - sys.exit(1) - - - def parseHistory(self): - trans = [] - i = 0 - - currentBase = int(self.historyDoc['currentUd']['base']) - self.UD = self.historyDoc['currentUd']['amount']/100 - - for sens in 'received','sent','receiving','sending': - res = self.historyDoc['transactionsHistory'][sens] - for bloc in res: - output = bloc['outputs'][0] - outPubkey = output.split("SIG(")[1].replace(')','') - if sens in ('received','receiving') or self.pubkey != outPubkey: - trans.append(i) - trans[i] = [] - trans[i].append(sens) - if sens in ('receiving','sending'): - trans[i].append(int(time.time())) - else: - trans[i].append(bloc['writtenTime']) - if sens in ('sent','sending'): - trans[i].append(outPubkey) - amount = int('-' + output.split(':')[0]) - else: - trans[i].append(bloc['issuers'][0]) - amount = int(output.split(':')[0]) - base = int(output.split(':')[1]) - applyBase = base-currentBase - amount = round(amount*pow(10,applyBase)/100, 2) - # if referential == 'DU': amount = round(amount/UD, 2) - trans[i].append(amount) - trans[i].append(round(amount/self.UD, 2)) - trans[i].append(bloc['comment']) - trans[i].append(base) - i += 1 - - # Order transactions by date - trans.sort(key=lambda x: x[1]) - - # Keep only base if there is base change - lastBase = 0 - for i in trans: - if i[6] == lastBase: i[6] = None - else: lastBase = i[6] - - return trans - - def printHistory(self, trans, noColors): - # Get balance - balance = self.historyDoc['balance']['amount']/100 - balanceUD = round(balance/self.UD, 2) - - # Get currency - currency = self.historyDoc['node']['peer']['currency'] - if currency == 'g1': currency = 'Ḡ1' - elif currency == 'g1-test': currency = 'GT' - # if referential == 'DU': currency = 'DU/' + currency.lower() - - # Get terminal size - rows = int(os.popen('stty size', 'r').read().split()[1]) - - # Display history - print('+', end='') - print('-'.center(rows-1, '-')) - if noColors: isBold = isBoldEnd = '' - else: - isBold = '\033[1m' - isBoldEnd = '\033[0m' - print(isBold + "|{: <19} | {: <12} | {: <7} | {: <7} | {: <30}".format(" Date"," De / À"," {0}".format(currency)," DU/{0}".format(currency.lower()),"Commentaire") + isBoldEnd) - print('|', end='') - for t in trans: - if t[0] == "received": color = "green" - elif t[0] == "receiving": color = "yellow" - elif t[0] == "sending": color = "red" - else: color = "blue" - if noColors: - color = None - if t[0] in ('receiving','sending'): - comment = '(EN ATTENTE) ' + t[5] - else: - comment = t[5] - else: - comment = t[5] - - date = datetime.fromtimestamp(t[1]).strftime("%d/%m/%Y à %H:%M") - print('-'.center(rows-1, '-')) - if t[6]: - print('|', end='') - print(' Changement de base : {0} '.format(t[6]).center(rows-1, '#')) - print('|', end='') - print('-'.center(rows-1, '-')) - print('|', end='') - printKey = t[2][0:8] + '\u2026' + t[2][-3:] - if noColors: - print(" {: <18} | {: <12} | {: <7} | {: <7} | {: <30}".format(date, printKey, t[3], t[4], comment)) - else: - print(colored(" {: <18} | {: <12} | {: <7} | {: <7} | {: <30}".format(date, printKey, t[3], t[4], comment), color)) - print('|', end='') - print('-'.center(rows-1, '-')) - print('|', end='') - print(isBold + 'Solde du compte: {0} {1} ({2} DU/{3})'.format(balance, currency, balanceUD, currency.lower()).center(rows-1, ' ') + isBoldEnd) - print('+', end='') - print(''.center(rows-1, '-')) - if not noColors: - print(colored('Reçus', 'green'), '-', colored('En cours de réception', 'yellow'), '-', colored('Envoyé', 'blue'), '-', colored("En cours d'envoi", 'red')) - - return trans - - def jsonHistory(self, transList): - dailyJSON = [] - for i, trans in enumerate(transList): - dailyJSON.append(i) - dailyJSON[i] = {} - dailyJSON[i]['date'] = trans[1] - dailyJSON[i]['pubkey'] = trans[2] - dailyJSON[i]['amount'] = trans[3] - dailyJSON[i]['amountUD'] = trans[4] - dailyJSON[i]['comment'] = trans[5] - - dailyJSON = json.dumps(dailyJSON, indent=2) - # If we want to write JSON to a file - #jsonFile = open("history-{0}.json".format(self.pubkey[0:8]), "w") - #jsonFile.writelines(dailyJSON + '\n') - #jsonFile.close() - return dailyJSON - diff --git a/zen/jaklis.old/lib/gvaPay.py b/zen/jaklis.old/lib/gvaPay.py deleted file mode 100644 index e017c88..0000000 --- a/zen/jaklis.old/lib/gvaPay.py +++ /dev/null @@ -1,172 +0,0 @@ -#!/usr/bin/env python3 - -import sys, re, os.path, json, ast -from termcolor import colored -from lib.natools import fmt, sign, get_privkey -from gql import gql, Client -from gql.transport.aiohttp import AIOHTTPTransport - -PUBKEY_REGEX = "(?![OIl])[1-9A-Za-z]{42,45}" - -class Transaction: - - def __init__(self, dunikey, node, recipient, amount, comment='', useMempool=False, verbose=False): - self.dunikey = dunikey - self.recipient = recipient - self.amount = int(amount*100) - self.comment = comment - self.issuer = get_privkey(dunikey, "pubsec").pubkey - self.useMempool = useMempool - self.verbose = verbose - self.node = node - self._isChange = False - - try: - if not re.match(PUBKEY_REGEX, recipient) or len(recipient) > 45: - raise ValueError("La clé publique n'est pas au bon format.") - except: - sys.stderr.write("La clé publique n'est pas au bon format.\n") - raise - - - try: - if recipient == self.issuer: - raise ValueError('Le destinataire ne peut pas être vous même.') - except: - sys.stderr.write("Le destinataire ne peut pas être vous même.\n") - raise - - - # Define Duniter GVA node - transport = AIOHTTPTransport(url=node) - self.client = Client(transport=transport, fetch_schema_from_transport=True) - - def genDoc(self): - # Build TX generation document - if self.verbose: print("useMempool:", str(self.useMempool)) - queryBuild = gql( - """ - query ($recipient: String!, $issuer: String!, $amount: Int!, $comment: String!, $useMempool: Boolean!){ genTx( - amount: $amount - comment: $comment - issuer: $issuer - recipient: $recipient - useMempoolSources: $useMempool - ) - } - """ - ) - paramsBuild = { - "recipient": self.recipient, - "issuer": self.issuer, - "amount": int(self.amount), - "comment": self.comment, - "useMempool": self.useMempool - } - - # Send TX document - try: - # self.txDoc = [] - self.txDoc = self.client.execute(queryBuild, variable_values=paramsBuild)['genTx'] - if self.verbose: print(self.txDoc[0]) - return self.txDoc - except Exception as e: - message = ast.literal_eval(str(e))["message"] - sys.stderr.write("Echec de la génération du document:\n" + message + "\n") - raise - - - # Check document - def checkTXDoc(self): - issuerRaw=[];outAmount=[];outPubkey=[];commentRaw=[] - for docs in self.txDoc: - docList = docs.splitlines() - for i, line in enumerate(docList): - if re.search("Issuers:", line): - issuerRaw.append(docList[(i + 1) % len(docList)]) - if re.search("Outputs:", line): - outputRaw = docList[(i + 1) % len(docList)].split(":") - outAmount.append(int(outputRaw[0])) - outPubkey.append(outputRaw[2].split("SIG(")[1].replace(')','')) - if re.search("Comment:", line): - commentRaw.append(line.split(': ', 1)[1]) - - # Check if it's only a change transaction - if all(i == self.issuer for i in outPubkey): - print("Le document contient une transaction de change") - self.isChange = True - # Check validity of the document - elif all(i != self.issuer for i in issuerRaw) or sum(outAmount) != self.amount or all(i != self.recipient for i in outPubkey) or all(i != self.comment for i in commentRaw): - sys.stderr.write(colored("Le document généré est corrompu !\nLe noeud " + self.node + "a peut être un dysfonctionnement.\n", 'red')) - sys.stderr.write(colored(issuerRaw[0] + " envoi " + str(outAmount[0]) + " vers " + outPubkey[0] + " with comment: " + commentRaw[0] + "\n", "yellow")) - raise ValueError('Le document généré est corrompu !') - else: - print("Le document généré est conforme.") - self.isChange = False - return self.txDoc - - def signDoc(self): - # Sign TX documents - signature=[] - self.signedDoc=[] - for i, docs in enumerate(self.txDoc): - signature.append(fmt["64"](sign(docs.encode(), get_privkey(self.dunikey, "pubsec"))[:-len(docs.encode())])) - self.signedDoc.append(docs + signature[i].decode()) - return self.signedDoc - - - def sendTXDoc(self): - # Build TX documents - txResult=[] - for docs in self.signedDoc: - querySign = gql( - """ - mutation ($signedDoc: String!){ tx( - rawTx: $signedDoc - ) { - version - issuers - outputs - } - } - """ - ) - paramsSign = { - "signedDoc": docs - } - - # Send TX Signed document - try: - txResult.append(str(self.client.execute(querySign, variable_values=paramsSign))) - except Exception as e: - message = ast.literal_eval(str(e))["message"] - sys.stderr.write("Echec de la transaction:\n" + message + "\n") - if self.verbose: - sys.stderr.write("Document final:\n" + docs) - raise ValueError(message) - else: - if self.isChange: - self.send() - else: - print(colored("Transaction effectué avec succès !", "green")) - if self.verbose: - print(docs) - break - - return txResult - - def _getIsChange(self): - return self._isChange - def _setIsChange(self, newChange): - if self.verbose: print("_setIsChange: ", str(newChange)) - self._isChange = newChange - if newChange: self.useMempool == True - isChange = property(_getIsChange, _setIsChange) - - def send(self): - result = self.genDoc() - result = self.checkTXDoc() - result = self.signDoc() - result = self.sendTXDoc() - return result - diff --git a/zen/jaklis.old/lib/likes.py b/zen/jaklis.old/lib/likes.py deleted file mode 100644 index 5eee339..0000000 --- a/zen/jaklis.old/lib/likes.py +++ /dev/null @@ -1,242 +0,0 @@ -import os, sys, ast, requests, json, base58, base64, time, string, random, re -from lib.natools import fmt, sign, get_privkey, box_decrypt, box_encrypt -from time import sleep -from hashlib import sha256 -from datetime import datetime -from termcolor import colored -from lib.cesiumCommon import CesiumCommon, PUBKEY_REGEX - -class ReadLikes(CesiumCommon): - # Configure JSON document to send - def configDoc(self, profile): - if not profile: profile = self.pubkey - - data = {} - data['query'] = {} - data['query']['bool'] = {} - data['query']['bool']['filter'] = [ - {'term': {'index': 'user'}}, - {'term': {'type': 'profile'}}, - {'term': {'id': profile}}, - {'term': {'kind': 'STAR'}} - ] - # data['query']['bool']['should'] = {'term':{'issuer': self.issuer}} - data['size'] = 5000 - data['_source'] = ['issuer','level'] - data['aggs'] = { - 'level_sum': { - 'sum': { - 'field': 'level' - } - } - } - - return json.dumps(data) - - def sendDocument(self, document): - - headers = { - 'Content-type': 'application/json', - } - - # Send JSON document and get JSON result - result = requests.post('{0}/like/record/_search'.format(self.pod), headers=headers, data=document) - - if result.status_code == 200: - # print(result.text) - return result.text - else: - sys.stderr.write("Echec de l'envoi du document de lecture des messages...\n" + result.text + '\n') - - def parseResult(self, result): - result = json.loads(result) - totalLikes = result['hits']['total'] - totalValue = result['aggregations']['level_sum']['value'] - if totalLikes: - score = totalValue/totalLikes - else: - score = 0 - raw = result['hits']['hits'] - finalPrint = {} - finalPrint['likes'] = [] - for i in raw: - issuer = i['_source']['issuer'] - # print(issuer) - gProfile = self.getProfile(issuer) - try: - pseudo = gProfile['title'] - except: - pseudo = '' - try: - payTo = gProfile['pubkey'] - except: - payTo = '' - id = i['_id'] - level = i['_source']['level'] - if issuer == self.pubkey: - finalPrint['yours'] = { 'id' : id, 'pseudo' : pseudo, 'payTo' : payTo, 'level' : level } - else: - finalPrint['likes'].append({ 'issuer' : issuer, 'pseudo' : pseudo, 'payTo' : payTo, 'level' : level }) - finalPrint['score'] = score - - return json.dumps(finalPrint) - - def getProfile(self, profile): - headers = { - 'Content-type': 'application/json', - } - - data = {} - data['query'] = {} - data['query']['bool'] = {} - data['query']['bool']['filter'] = [ - {'term': {'_index': 'user'}}, - {'term': {'_type': 'profile'}}, - {'term': {'_id': profile}} - ] - data['_source'] = ['title','pubkey'] - - data = json.dumps(data) - - result = requests.post('{0}/user/profile/_search'.format(self.pod), headers=headers, data=data) - result = json.loads(result.text)['hits']['hits'] - for i in result: - return i['_source'] - - -#################### Like class #################### - - -class SendLikes(CesiumCommon): - # Configure JSON document to send - def configDoc(self, profile, likes): - if not profile: profile = self.pubkey - if likes not in range(0, 6): - sys.stderr.write(colored('Votre like doit être compris entre 0 et 5.\n', 'red')) - return False - - - timeSent = int(time.time()) - - data = {} - data['version'] = 2 - data['index'] = "user" - data['type'] = "profile" - data['id'] = profile - data['kind'] = "STAR" - data['level'] = likes - data['time'] = timeSent - data['issuer'] = self.pubkey - - document = json.dumps(data) - - # Generate hash of document - hashDoc = sha256(document.encode()).hexdigest().upper() - - # Generate signature of document - signature = fmt["64"](sign(hashDoc.encode(), get_privkey(self.dunikey, "pubsec"))[:-len(hashDoc.encode())]).decode() - - # Build final document - data = {} - data['hash'] = hashDoc - data['signature'] = signature - signJSON = json.dumps(data) - finalJSON = {**json.loads(signJSON), **json.loads(document)} - finalDoc = json.dumps(finalJSON) - - return finalDoc - - def sendDocument(self, document, pubkey): - - headers = { - 'Content-type': 'application/json', - } - - # Send JSON document and get JSON result - result = requests.post('{0}/user/profile/:id/_like'.format(self.pod), headers=headers, data=document) - - if result.status_code == 200: - print(colored("Profile liké avec succès !", 'green')) - return result.text - elif result.status_code == 400: - resultJson = json.loads(result.text) - if 'DuplicatedDocumentException' in resultJson['error']: - rmLike = UnLikes(self.dunikey, self.pod) - idLike = rmLike.checkLike(pubkey) - if idLike: - document = rmLike.configDoc(idLike) - rmLike.sendDocument(document, True) - sleep(0.5) - self.sendDocument(document, pubkey) - return resultJson['error'] - else: - sys.stderr.write("Echec de l'envoi du document de lecture des messages...\n" + resultJson['error'] + '\n') - else: - resultJson = json.loads(result.text) - sys.stderr.write("Echec de l'envoi du document de lecture des messages...\n" + resultJson['error'] + '\n') - - -#################### Unlike class #################### - - -class UnLikes(CesiumCommon): - # Check if you liked this profile - def checkLike(self, pubkey): - readProfileLikes = ReadLikes(self.dunikey, self.pod) - document = readProfileLikes.configDoc(pubkey) - result = readProfileLikes.sendDocument(document) - result = readProfileLikes.parseResult(result) - result = json.loads(result) - - if 'yours' in result: - myLike = result['yours']['id'] - return myLike - else: - sys.stderr.write("Vous n'avez pas liké ce profile\n") - return False - - # Configure JSON document to send - def configDoc(self, idLike): - timeSent = int(time.time()) - - data = {} - data['version'] = 2 - data['index'] = "like" - data['type'] = "record" - data['id'] = idLike - data['issuer'] = self.pubkey - data['time'] = timeSent - - document = json.dumps(data) - - # Generate hash of document - hashDoc = sha256(document.encode()).hexdigest().upper() - - # Generate signature of document - signature = fmt["64"](sign(hashDoc.encode(), get_privkey(self.dunikey, "pubsec"))[:-len(hashDoc.encode())]).decode() - - # Build final document - data = {} - data['hash'] = hashDoc - data['signature'] = signature - signJSON = json.dumps(data) - finalJSON = {**json.loads(signJSON), **json.loads(document)} - finalDoc = json.dumps(finalJSON) - - return finalDoc - - def sendDocument(self, document, silent): - - headers = { - 'Content-type': 'application/json', - } - - # Send JSON document and get JSON result - result = requests.post('{0}/history/delete'.format(self.pod), headers=headers, data=document) - - if result.status_code == 200: - if not silent: - print(colored("Like supprimé avec succès !", 'green')) - return result.text - else: - sys.stderr.write("Echec de l'envoi du document de lecture des messages...\n" + result.text + '\n') diff --git a/zen/jaklis.old/lib/messaging.py b/zen/jaklis.old/lib/messaging.py deleted file mode 100644 index 2165182..0000000 --- a/zen/jaklis.old/lib/messaging.py +++ /dev/null @@ -1,236 +0,0 @@ -import os, sys, ast, requests, json, base58, base64 -from time import time -from datetime import datetime -from termcolor import colored -from lib.natools import fmt, get_privkey, box_decrypt, box_encrypt -from lib.cesiumCommon import CesiumCommon, pp_json, PUBKEY_REGEX - - -#################### Reading class #################### - - -class ReadFromCesium(CesiumCommon): - # Configure JSON document to send - def configDoc(self, nbrMsg, outbox): - boxType = "issuer" if outbox else "recipient" - - data = {} - data['sort'] = { "time": "desc" } - data['from'] = 0 - data['size'] = nbrMsg - data['_source'] = ['issuer','recipient','title','content','time','nonce','read_signature'] - data['query'] = {} - data['query']['bool'] = {} - data['query']['bool']['filter'] = {} - data['query']['bool']['filter']['term'] = {} - data['query']['bool']['filter']['term'][boxType] = self.pubkey - - document = json.dumps(data) - return document - - def sendDocument(self, nbrMsg, outbox): - boxType = "outbox" if outbox else "inbox" - - document = self.configDoc(nbrMsg, outbox) - headers = { - 'Content-type': 'application/json', - } - - # Send JSON document and get JSON result - result = requests.post('{0}/message/{1}/_search'.format(self.pod, boxType), headers=headers, data=document) - if result.status_code == 200: - return result.json()["hits"] - else: - sys.stderr.write("Echec de l'envoi du document de lecture des messages...\n" + result.text) - - # Parse JSON result and display messages - def readMessages(self, msgJSON, nbrMsg, outbox): - def decrypt(msg): - msg64 = base64.b64decode(msg) - return box_decrypt(msg64, get_privkey(self.dunikey, "pubsec"), self.issuer, nonce).decode() - - # Get terminal size - rows = int(os.popen('stty size', 'r').read().split()[1]) - - totalMsg = msgJSON["total"] - if nbrMsg > totalMsg: - nbrMsg = totalMsg - - if totalMsg == 0: - print(colored("Aucun message à afficher.", 'yellow')) - return True - else: - infoTotal = " Nombre de messages: " + str(nbrMsg) + "/" + str(totalMsg) + " " - print(colored(infoTotal.center(rows, '#'), "yellow")) - for hits in msgJSON["hits"]: - self.idMsg = hits["_id"] - msgSrc = hits["_source"] - self.issuer = msgSrc["issuer"] - nonce = msgSrc["nonce"] - nonce = base58.b58decode(nonce) - self.dateS = msgSrc["time"] - date = datetime.fromtimestamp(self.dateS).strftime(", le %d/%m/%Y à %H:%M ") - if outbox: - startHeader = " À " + msgSrc["recipient"] - else: - startHeader = " De " + self.issuer - headerMsg = startHeader + date + "(ID: {})".format(self.idMsg) + " " - - print('-'.center(rows, '-')) - print(colored(headerMsg, "blue").center(rows+9, '-')) - print('-'.center(rows, '-')) - try: - self.title = decrypt(msgSrc["title"]) - self.content = decrypt(msgSrc["content"]) - except Exception as e: - sys.stderr.write(colored(str(e), 'red') + '\n') - pp_json(hits) - continue - print('\033[1m' + self.title + '\033[0m') - print(self.content) - - print(colored(infoTotal.center(rows, '#'), "yellow")) - - # Parse JSON result and display messages - def jsonMessages(self, msgJSON, nbrMsg, outbox): - def decrypt(msg): - msg64 = base64.b64decode(msg) - return box_decrypt(msg64, get_privkey(self.dunikey, "pubsec"), self.issuer, nonce).decode() - - totalMsg = msgJSON["total"] - if nbrMsg > totalMsg: - nbrMsg = totalMsg - - if totalMsg == 0: - print("Aucun message à afficher") - return True - else: - data = [] - # data.append({}) - # data[0]['total'] = totalMsg - for i, hits in enumerate(msgJSON["hits"]): - self.idMsg = hits["_id"] - msgSrc = hits["_source"] - self.issuer = msgSrc["issuer"] - nonce = msgSrc["nonce"] - nonce = base58.b58decode(nonce) - self.date = msgSrc["time"] - - if outbox: - pubkey = msgSrc["recipient"] - else: - pubkey = self.issuer - - try: - self.title = decrypt(msgSrc["title"]) - self.content = decrypt(msgSrc["content"]) - except Exception as e: - sys.stderr.write(colored(str(e), 'red') + '\n') - pp_json(hits) - continue - - data.append(i) - data[i] = {} - data[i]['id'] = self.idMsg - data[i]['date'] = self.date - data[i]['pubkey'] = pubkey - data[i]['title'] = self.title - data[i]['content'] = self.content - - data = json.dumps(data, indent=2) - return data - - -#################### Sending class #################### - - -class SendToCesium(CesiumCommon): - def encryptMsg(self, msg): - return fmt["64"](box_encrypt(msg.encode(), get_privkey(self.dunikey, "pubsec"), self.recipient, self.nonce)).decode() - - def configDoc(self, title, msg): - b58nonce = base58.b58encode(self.nonce).decode() - - # Get current timestamp - timeSent = int(time()) - - # Generate custom JSON - data = {} - data['issuer'] = self.pubkey - data['recipient'] = self.recipient - data['title'] = title - data['content'] = msg - data['time'] = timeSent - data['nonce'] = b58nonce - data['version'] = 2 - document = json.dumps(data) - - return self.signDoc(document) - - - def sendDocument(self, document, outbox): - boxType = "outbox" if outbox else "inbox" - - headers = { - 'Content-type': 'application/json', - } - - # Send JSON document and get result - try: - result = requests.post('{0}/message/{1}?pubkey={2}'.format(self.pod, boxType, self.recipient), headers=headers, data=document) - except Exception as e: - sys.stderr.write("Impossible d'envoyer le message:\n" + str(e)) - sys.exit(1) - else: - if result.status_code == 200: - print(colored("Message envoyé avec succès !", "green")) - print("ID: " + result.text) - return result - else: - sys.stderr.write("Erreur inconnue:" + '\n') - print(str(pp_json(result.text)) + '\n') - - -#################### Deleting class #################### - - -class DeleteFromCesium(CesiumCommon): - def configDoc(self, idMsg, outbox): - # Get current timestamp - timeSent = int(time()) - - boxType = "outbox" if outbox else "inbox" - - # Generate document to customize - data = {} - data['version'] = 2 - data['index'] = "message" - data['type'] = boxType - data['id'] = idMsg - data['issuer'] = self.pubkey - data['time'] = timeSent - document = json.dumps(data) - - return self.signDoc(document) - - def sendDocument(self, document, idMsg): - headers = { - 'Content-type': 'application/json', - } - - # Send JSON document and get result - try: - result = requests.post('{0}/history/delete'.format(self.pod), headers=headers, data=document) - if result.status_code == 404: - raise ValueError("Message introuvable") - elif result.status_code == 403: - raise ValueError("Vous n'êtes pas l'auteur de ce message.") - except Exception as e: - sys.stderr.write(colored("Impossible de supprimer le message {0}:\n".format(idMsg), 'red') + str(e) + "\n") - return False - else: - if result.status_code == 200: - print(colored("Message {0} supprimé avec succès !".format(idMsg), "green")) - return result - else: - sys.stderr.write("Erreur inconnue.") diff --git a/zen/jaklis.old/lib/natools.py b/zen/jaklis.old/lib/natools.py deleted file mode 100755 index 18f06d1..0000000 --- a/zen/jaklis.old/lib/natools.py +++ /dev/null @@ -1,297 +0,0 @@ -#!/usr/bin/env python3 - -""" - CopyLeft 2020 Pascal Engélibert - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . -""" - -__version__ = "1.3.1" - -import os, sys, duniterpy.key, libnacl, base58, base64, getpass - -def getargv(arg:str, default:str="", n:int=1, args:list=sys.argv) -> str: - if arg in args and len(args) > args.index(arg)+n: - return args[args.index(arg)+n] - else: - return default - -def read_data(data_path, b=True): - if data_path == "-": - if b: - return sys.stdin.buffer.read() - else: - return sys.stdin.read() - else: - return open(os.path.expanduser(data_path), "rb" if b else "r").read() - -def write_data(data, result_path): - if result_path == "-": - os.fdopen(sys.stdout.fileno(), 'wb').write(data) - else: - open(os.path.expanduser(result_path), "wb").write(data) - -def encrypt(data, pubkey): - return duniterpy.key.PublicKey(pubkey).encrypt_seal(data) - -def decrypt(data, privkey): - return privkey.decrypt_seal(data) - -def box_encrypt(data, privkey, pubkey, nonce=None, attach_nonce=False): - signer = libnacl.sign.Signer(privkey.seed) - sk = libnacl.public.SecretKey(libnacl.crypto_sign_ed25519_sk_to_curve25519(signer.sk)) - verifier = libnacl.sign.Verifier(base58.b58decode(pubkey).hex()) - pk = libnacl.public.PublicKey(libnacl.crypto_sign_ed25519_pk_to_curve25519(verifier.vk)) - box = libnacl.public.Box(sk.sk, pk.pk) - data = box.encrypt(data, nonce) if nonce else box.encrypt(data) - return data if attach_nonce else data[24:] - -def box_decrypt(data, privkey, pubkey, nonce=None): - signer = libnacl.sign.Signer(privkey.seed) - sk = libnacl.public.SecretKey(libnacl.crypto_sign_ed25519_sk_to_curve25519(signer.sk)) - verifier = libnacl.sign.Verifier(base58.b58decode(pubkey).hex()) - pk = libnacl.public.PublicKey(libnacl.crypto_sign_ed25519_pk_to_curve25519(verifier.vk)) - box = libnacl.public.Box(sk.sk, pk.pk) - return box.decrypt(data, nonce) if nonce else box.decrypt(data) - -def sign(data, privkey): - return privkey.sign(data) - -def verify(data, pubkey): - try: - ret = libnacl.sign.Verifier(duniterpy.key.PublicKey(pubkey).hex_pk()).verify(data) - sys.stderr.write("Signature OK!\n") - return ret - except ValueError: - sys.stderr.write("Bad signature!\n") - exit(1) - -def get_privkey(privkey_path, privkey_format): - if privkey_format == "pubsec": - if privkey_path == "*": - privkey_path = "privkey.pubsec" - return duniterpy.key.SigningKey.from_pubsec_file(privkey_path) - - elif privkey_format == "cred": - if privkey_path == "*": - privkey_path = "-" - if privkey_path == "-": - return duniterpy.key.SigningKey.from_credentials(getpass.getpass("Password: "), getpass.getpass("Salt: ")) - else: - return duniterpy.key.SigningKey.from_credentials_file(privkey_path) - - elif privkey_format == "seedh": - if privkey_path == "*": - privkey_path = "authfile.seedhex" - return duniterpy.key.SigningKey.from_seedhex(read_data(privkey_path, False)) - - elif privkey_format == "wif": - if privkey_path == "*": - privkey_path = "authfile.wif" - return duniterpy.key.SigningKey.from_wif_or_ewif_file(privkey_path) - - elif privkey_format == "wifh": - if privkey_path == "*": - privkey_path = "authfile.wif" - return duniterpy.key.SigningKey.from_wif_or_ewif_hex(privkey_path) - - elif privkey_format == "ssb": - if privkey_path == "*": - privkey_path = "secret" - return duniterpy.key.SigningKey.from_ssb_file(privkey_path) - - elif privkey_format == "key": - if privkey_path == "*": - privkey_path = "authfile.key" - return duniterpy.key.SigningKey.from_private_key(privkey_path) - - print("Error: unknown privkey format") - -def fill_pubkey(pubkey, length=32): - while pubkey[0] == 0: - pubkey = pubkey[1:] - return b"\x00"*(length-len(pubkey)) + pubkey - -def pubkey_checksum(pubkey, length=32, clength=3): - return base58.b58encode(libnacl.crypto_hash_sha256(libnacl.crypto_hash_sha256(fill_pubkey(base58.b58decode(pubkey), length)))).decode()[:clength] - -# returns (pubkey:bytes|None, deprecated_length:bool) -def check_pubkey(pubkey): - if ":" in pubkey: - parts = pubkey.split(":") - if len(parts[1]) < 3 or len(parts[1]) > 32: - return (None, False) - for i in range(32, 0, -1): - if pubkey_checksum(parts[0], i, len(parts[1])) == parts[1]: - return (parts[0], i < 32) - return (None, False) - return (pubkey, False) - -fmt = { - "raw": lambda data: data, - "16": lambda data: data.hex().encode(), - "32": lambda data: base64.b32encode(data), - "58": lambda data: base58.b58encode(data), - "64": lambda data: base64.b64encode(data), - "64u": lambda data: base64.urlsafe_b64encode(data), - "85": lambda data: base64.b85encode(data), -} - -defmt = { - "raw": lambda data: data, - "16": lambda data: bytes.fromhex(data), - "32": lambda data: base64.b32decode(data), - "58": lambda data: base58.b58decode(data), - "64": lambda data: base64.b64decode(data), - "85": lambda data: base64.b85decode(data), -} - -def show_help(): - print("""Usage: -python3 natools.py [options] - -Commands: - encrypt Encrypt data - decrypt Decrypt data - box-encrypt Encrypt data (NaCl box) - box-decrypt Decrypt data (NaCl box) - sign Sign data - verify Verify data - pubkey Display pubkey - pk Display b58 pubkey shorthand - -Options: - -c Display pubkey checksum - -f Private key format (default: cred) - key cred pubsec seedh ssb wif wifh - -i Input file path (default: -) - -I Input format: raw 16 32 58 64 85 (default: raw) - -k Privkey file path (* for auto) (default: *) - -n Nonce (b64, 24 bytes) (for NaCl box) - -N Attach nonce to output (for NaCl box encryption) - --noinc Do not include msg after signature - -o Output file path (default: -) - -O Output format: raw 16 32 58 64 64u 85 (default: raw) - -p Pubkey (base58) - - --help Show help - --version Show version - --debug Debug mode (display full errors) - -Note: "-" means stdin or stdout. -""") - -if __name__ == "__main__": - - if "--help" in sys.argv: - show_help() - exit() - - if "--version" in sys.argv: - print(__version__) - exit() - - privkey_format = getargv("-f", "cred") - data_path = getargv("-i", "-") - privkey_path = getargv("-k", "*") - pubkey = getargv("-p") - result_path = getargv("-o", "-") - output_format = getargv("-O", "raw") - input_format = getargv("-I", "raw") - - if pubkey: - pubkey, len_deprecated = check_pubkey(pubkey) - if not pubkey: - print("Invalid pubkey checksum! Please check spelling.") - exit(1) - if len(base58.b58decode(pubkey)) > 32: - print("Invalid pubkey: too long!") - exit(1) - if len_deprecated: - print("Warning: valid pubkey checksum, but deprecated format (truncating zeros)") - - try: - if sys.argv[1] == "encrypt": - if not pubkey: - print("Please provide pubkey!") - exit(1) - write_data(fmt[output_format](encrypt(defmt[input_format](read_data(data_path)), pubkey)), result_path) - - elif sys.argv[1] == "decrypt": - write_data(fmt[output_format](decrypt(defmt[input_format](read_data(data_path)), get_privkey(privkey_path, privkey_format))), result_path) - - elif sys.argv[1] == "box-encrypt": - if not pubkey: - print("Please provide pubkey!") - exit(1) - nonce = getargv("-n", None) - if nonce: - nonce = base64.b64decode(nonce) - attach_nonce = "-N" in sys.argv - write_data(fmt[output_format](box_encrypt(defmt[input_format](read_data(data_path)), get_privkey(privkey_path, privkey_format), pubkey, nonce, attach_nonce)), result_path) - - elif sys.argv[1] == "box-decrypt": - if not pubkey: - print("Please provide pubkey!") - exit(1) - nonce = getargv("-n", None) - if nonce: - nonce = base64.b64decode(nonce) - write_data(fmt[output_format](box_decrypt(defmt[input_format](read_data(data_path)), get_privkey(privkey_path, privkey_format), pubkey, nonce)), result_path) - - elif sys.argv[1] == "sign": - data = defmt[input_format](read_data(data_path)) - signed = sign(data, get_privkey(privkey_path, privkey_format)) - - if "--noinc" in sys.argv: - signed = signed[:len(signed)-len(data)] - - write_data(fmt[output_format](signed), result_path) - - elif sys.argv[1] == "verify": - if not pubkey: - print("Please provide pubkey!") - exit(1) - write_data(fmt[output_format](verify(defmt[input_format](read_data(data_path)), pubkey)), result_path) - - elif sys.argv[1] == "pubkey": - if pubkey: - if "-c" in sys.argv and output_format == "58": - write_data("{}:{}".format(pubkey, pubkey_checksum(pubkey)).encode(), result_path) - else: - write_data(fmt[output_format](base58.b58decode(pubkey)), result_path) - else: - pubkey = get_privkey(privkey_path, privkey_format).pubkey - if "-c" in sys.argv and output_format == "58": - write_data("{}:{}".format(pubkey, pubkey_checksum(pubkey)).encode(), result_path) - else: - write_data(fmt[output_format](base58.b58decode(pubkey)), result_path) - - elif sys.argv[1] == "pk": - if not pubkey: - pubkey = get_privkey(privkey_path, privkey_format).pubkey - if "-c" in sys.argv: - print("{}:{}".format(pubkey, pubkey_checksum(pubkey))) - else: - print(pubkey) - - else: - show_help() - - except Exception as e: - if "--debug" in sys.argv: - 0/0 # DEBUG MODE (raise error when handling error to display backtrace) - sys.stderr.write("Error: {}\n".format(e)) - show_help() - exit(1) diff --git a/zen/jaklis.old/lib/profiles.py b/zen/jaklis.old/lib/profiles.py deleted file mode 100644 index 5386c89..0000000 --- a/zen/jaklis.old/lib/profiles.py +++ /dev/null @@ -1,125 +0,0 @@ -import sys, re, json, requests, base64 -from time import time -from lib.cesiumCommon import CesiumCommon, PUBKEY_REGEX - - -class Profiles(CesiumCommon): - # Configure JSON document SET to send - def configDocSet(self, name, description, city, address, pos, socials, avatar): - timeSent = int(time()) - - data = {} - if name: data['title'] = name - if description: data['description'] = description - if address: data['address'] = address - if city: data['city'] = city - if pos: - geoPoint = {} - geoPoint['lat'] = pos[0] - geoPoint['lon'] = pos[1] - data['geoPoint'] = geoPoint - if socials: - data['socials'] = [] - data['socials'].append({}) - data['socials'][0]['type'] = "web" - data['socials'][0]['url'] = socials - if avatar: - avatar = open(avatar, 'rb').read() - avatar = base64.b64encode(avatar).decode() - data['avatar'] = {} - data['avatar']['_content'] = avatar - data['avatar']['_content_type'] = "image/png" - data['time'] = timeSent - data['issuer'] = self.pubkey - data['version'] = 2 - data['tags'] = [] - - document = json.dumps(data) - - return self.signDoc(document) - - # Configure JSON document GET to send - def configDocGet(self, profile, scope='title', getAvatar=None): - - if getAvatar: - avatar = "avatar" - else: - avatar = "avatar._content_type" - - data = { - "query": { - "bool": { - "should":[ - { - "match":{ - scope:{ - "query": profile,"boost":2 - } - } - },{ - "prefix": {scope: profile} - } - ] - } - },"highlight": { - "fields": { - "title":{}, - "tags":{} - } - },"from":0, - "size":100, - "_source":["title", avatar,"description","city","address","socials.url","creationTime","membersCount","type"], - "indices_boost":{"user":100,"page":1,"group":0.01 - } - } - - document = json.dumps(data) - - return document - - # Configure JSON document SET to send - def configDocErase(self): - timeSent = int(time()) - - data = {} - data['time'] = timeSent - data['id'] = self.pubkey - data['issuer'] = self.pubkey - data['version'] = 2 - data['index'] = "user" - data['type'] = "profile" - - document = json.dumps(data) - - return self.signDoc(document) - - def sendDocument(self, document, type): - - headers = { - 'Content-type': 'application/json', - } - - # Send JSON document and get JSON result - if type == 'set': - reqQuery = '{0}/user/profile?pubkey={1}/_update?pubkey={1}'.format(self.pod, self.pubkey) - elif type == 'get': - reqQuery = '{0}/user,page,group/profile,record/_search'.format(self.pod) - elif type == 'erase': - reqQuery = '{0}/history/delete'.format(self.pod) - - result = requests.post(reqQuery, headers=headers, data=document) - if result.status_code == 200: - # print(result.text) - return result.text - else: - sys.stderr.write("Echec de l'envoi du document...\n" + result.text + '\n') - - def parseJSON(self, doc): - doc = json.loads(doc)['hits']['hits'] - if doc: - pubkey = { "pubkey": doc[0]['_id'] } - rest = doc[0]['_source'] - final = {**pubkey, **rest} - return json.dumps(final, indent=2) - else: - return 'Profile vide' diff --git a/zen/jaklis.old/paiements.py b/zen/jaklis.old/paiements.py deleted file mode 100755 index dde58da..0000000 --- a/zen/jaklis.old/paiements.py +++ /dev/null @@ -1,94 +0,0 @@ -#!/usr/bin/env python3 - -""" -ZetCode Tkinter tutorial - -In this example, we use the pack -manager to create a review example. - -Author: Jan Bodnar -Website: www.zetcode.com -""" - -import PySimpleGUI as sg -from lib.gva import GvaApi -import sys, os, threading -from shutil import copyfile -from os.path import join, dirname -from dotenv import load_dotenv -from lib.natools import get_privkey -import requests - -class StdoutRedirector(object): - def __init__(self, text_widget): - self.text_widget = text_widget - - def write(self, s): - self.text_widget.insert('end', s) - self.text_widget.see('end') - - def flush(self): - pass - - -MY_PATH = os.path.realpath(os.path.dirname(sys.argv[0])) + '/' - -# Get variables environment -if not os.path.isfile(MY_PATH + '.env'): - copyfile(MY_PATH + ".env.template",MY_PATH + ".env") -dotenv_path = join(dirname(__file__),MY_PATH + '.env') -load_dotenv(dotenv_path) - -dunikey = os.getenv('DUNIKEY') -if not os.path.isfile(dunikey): - HOME = os.getenv("HOME") - dunikey = HOME + dunikey - if not os.path.isfile(dunikey): - sys.stderr.write('Le fichier de trousseau {0} est introuvable.\n'.format(dunikey)) - sys.exit(1) -node = os.getenv('NODE') -issuer = get_privkey(dunikey, "pubsec").pubkey - - -def ProceedPaiement(recipient, amount, comment): - if not recipient: - raise ValueError("Veuillez indiquer un destinataire de paiement") - elif not amount: - raise ValueError("Veuillez indiquer le montant de la transaction") - - amount = int(float(amount.replace(',','.'))*100) - print("Paiement en cours vers", recipient) - gva = GvaApi(dunikey, node, recipient) - gva.pay(amount, comment, False, False) - - recipient = amount = comment = None - - -sg.theme('DarkGrey2') -layout = [ [sg.Text('Noeud utilisé: ' + node)], - [sg.Text('Votre clé publique: ' + issuer)], - [sg.Text('')], - [sg.Text('Destinataire: '), sg.InputText(size=(55, None),default_text=issuer)], - [sg.Text('Montant: '), sg.InputText(size=(7, None)), sg.Text('Ḡ1')], - [sg.Text('Commentaire:'), sg.InputText(size=(55, None))], - [sg.Button('Envoyer')] ] - -# Create the Window -window = sg.Window('Paiement Ḡ1 - GVA', layout) -# availablePubkeys = requests.get('https://g1-stats.axiom-team.fr/data/wallets-g1.txt') -while True: - try: - event, values = window.read() - if event == sg.WIN_CLOSED: - break - if event == 'Envoyer': - ProceedPaiement(values[0], values[1], values[2]) - except Exception as e: - loc = window.CurrentLocation() - sg.popup(e, title="ERREUR", button_color=('black','red'), location=(loc)) - else: - loc = window.CurrentLocation() - sg.popup(f'Transaction effectué avec succès !', title="Envoyé", location=(loc)) - - -window.close() diff --git a/zen/jaklis.old/requirements.txt b/zen/jaklis.old/requirements.txt deleted file mode 100644 index e6b5711..0000000 --- a/zen/jaklis.old/requirements.txt +++ /dev/null @@ -1,7 +0,0 @@ -wheel -base58 -pybase64 -duniterpy -termcolor -python-dotenv -gql diff --git a/zen/jaklis.old/setup.sh b/zen/jaklis.old/setup.sh deleted file mode 100755 index 222e4ba..0000000 --- a/zen/jaklis.old/setup.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash - -for i in gcc python3-pip python3-setuptools libpq-dev python3-dev python3-wheel; do - if [ $(dpkg-query -W -f='${Status}' $i 2>/dev/null | grep -c "ok installed") -eq 0 ]; then - [[ ! $j ]] && sudo apt update - sudo apt install -y $i - j=1 - fi -done - -pip3 install -r requirements.txt -chmod u+x jaklis.py