#!/usr/bin/env python3 import sys, re, os.path, json from shutil import copyfile if not os.path.isfile("userEnv.py"): copyfile("userEnv.py.template", "userEnv.py") from termcolor import colored from userEnv import dunikey, node from natools import fmt, sign, get_privkey from gql import gql, Client from gql.transport.aiohttp import AIOHTTPTransport if not (dunikey): print("Please set the path to your pubsec keychain in userEnv.py file.") sys.exit(1) # Define Duniter GVA node transport = AIOHTTPTransport(url=node) client = Client(transport=transport, fetch_schema_from_transport=True) issuer = get_privkey(dunikey, "pubsec").pubkey try: recipient = sys.argv[1] amount = int(sys.argv[2]) if len(sys.argv) > 3: comment = sys.argv[3] else: comment = "" graphic = False except: graphic = True def sendGenDoc(recipient, amount, comment): # Build TX generation document queryBuild = gql( """ query ($recipient: String!, $issuer: String!, $amount: Int!, $comment: String!){ genTxs( amount: $amount comment: $comment issuer: $issuer recipient: $recipient ) } """ ) paramsBuild = { "recipient": recipient, "issuer": issuer, "amount": amount, "comment": comment } # Send TX document try: txDoc = str(client.execute(queryBuild, variable_values=paramsBuild))[13:-3].replace('\\n','\n') return txDoc except Exception as e: #e = json.dumps(str(e)) sys.stderr.write("Echec de la génération du document:\n" + str(e) + "\n") sys.exit(1) # Check document def checkTXDoc(txDoc, recipient, amount, comment): docList = txDoc.splitlines() for i, line in enumerate(docList): if re.search("Issuers:", line): issuerRaw = docList[(i + 1) % len(docList)] if re.search("Outputs:", line): outputRaw = docList[(i + 1) % len(docList)].split(":") outAmount = outputRaw[0] outPubkey = outputRaw[2].split("SIG(")[1].replace(')','') if re.search("Comment:", line): commentRaw = line.split(': ', 1)[1] if issuerRaw != issuer or int(outAmount) != amount or outPubkey != recipient or commentRaw != comment: sys.stderr.write(colored("Le document généré est corrompu !\nNe fait plus confiance au noeud " + node + "\n", 'red')) sys.stderr.write(colored(issuerRaw + " envoi " + outAmount + " vers " + outPubkey + " with comment: " + commentRaw + "\n", "yellow")) sys.exit(1) else: print("Le document généré est conforme.") return True def signDoc(txDoc): # Sign TX document signature = fmt["64"](sign(txDoc.encode(), get_privkey(dunikey, "pubsec"))[:-len(txDoc.encode())]) signedDoc = txDoc + signature.decode() return signedDoc def sendTXDoc(signedDoc): # Build TX document querySign = gql( """ mutation ($signedDoc: String!){ tx( rawTx: $signedDoc ) { version issuers outputs } } """ ) paramsSign = { "signedDoc": signedDoc } # Send TX Signed document try: client.execute(querySign, variable_values=paramsSign) print(colored("Transaction effectué avec succès !", "green")) except Exception as e: sys.stderr.write("Echec de la transaction:\n" + str(e) + "\n") sys.exit(1) # Execute workflow if not graphic: returnGen = sendGenDoc(recipient, amount, comment) docIsOK = checkTXDoc(returnGen, recipient, amount, comment) if docIsOK: returnSigned = signDoc(returnGen) sendTXDoc(returnSigned) #print(sentTX) #For debug