112 lines
2.9 KiB
Python
Executable File
112 lines
2.9 KiB
Python
Executable File
#!/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 issuer, dunikey, node
|
|
from natools import fmt, sign, get_privkey
|
|
from gql import gql, Client
|
|
from gql.transport.aiohttp import AIOHTTPTransport
|
|
|
|
if not (issuer) or not (dunikey):
|
|
print("Please set your pubkey and path to you 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)
|
|
|
|
recipient = sys.argv[1]
|
|
amount = int(sys.argv[2])
|
|
if len(sys.argv) > 3:
|
|
comment = sys.argv[3]
|
|
else:
|
|
comment = ""
|
|
|
|
## GraphQL queries
|
|
# Build the TX 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')
|
|
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
|
|
|
|
# print(txDoc) # For debug
|
|
|
|
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)
|
|
|
|
print("Le document généré est conforme.")
|
|
# sys.exit(0)
|
|
|
|
# Sign TX document
|
|
signature = fmt["64"](sign(txDoc.encode(), get_privkey(dunikey, "pubsec"))[:-len(txDoc.encode())])
|
|
signedDoc = txDoc + signature.decode()
|
|
|
|
#print(signedDoc) # For debug
|
|
|
|
querySign = gql(
|
|
"""
|
|
mutation ($signedDoc: String!){ tx(
|
|
rawTx: $signedDoc
|
|
) {
|
|
version
|
|
issuers
|
|
outputs
|
|
}
|
|
}
|
|
"""
|
|
)
|
|
paramsSign = {
|
|
"signedDoc": signedDoc
|
|
}
|
|
|
|
# Send TX Signed document
|
|
try:
|
|
sentTX = 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)
|
|
|
|
#print(sentTX) #For debug
|
|
|
|
|