Compare commits
3 Commits
adfaa5913f
...
1dd680e7ae
Author | SHA1 | Date |
---|---|---|
poka | 1dd680e7ae | |
poka | b0333ab908 | |
poka | 6126dad72b |
|
@ -0,0 +1,29 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys, argparse, os
|
||||
from os.path import join, dirname
|
||||
from shutil import copyfile
|
||||
from dotenv import load_dotenv
|
||||
from libs.balancelib import Balance
|
||||
|
||||
# Get variables environment
|
||||
if not os.path.isfile('.env'):
|
||||
copyfile(".env.template", ".env")
|
||||
dotenv_path = join(dirname(__file__), '.env')
|
||||
load_dotenv(dotenv_path)
|
||||
|
||||
dunikey = os.getenv('DUNIKEY')
|
||||
node = os.getenv('NODE')
|
||||
if not node:
|
||||
sys.stderr.write("Please fill a Duniter node in .env file\n")
|
||||
sys.exit(1)
|
||||
|
||||
# Parse arguments
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('-p', '--pubkey', help="Clé publique du compte visé")
|
||||
parser.add_argument('--mempool', action='store_true', help="Utilise les sources en Mempool")
|
||||
args = parser.parse_args()
|
||||
|
||||
# Create transaction and send it
|
||||
balance = Balance(dunikey, node, args.pubkey, args.mempool)
|
||||
result = balance.balance()
|
|
@ -0,0 +1,29 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys, argparse, os
|
||||
from os.path import join, dirname
|
||||
from shutil import copyfile
|
||||
from dotenv import load_dotenv
|
||||
from libs.historylib import History
|
||||
|
||||
# Get variables environment
|
||||
if not os.path.isfile('.env'):
|
||||
copyfile(".env.template", ".env")
|
||||
dotenv_path = join(dirname(__file__), '.env')
|
||||
load_dotenv(dotenv_path)
|
||||
|
||||
dunikey = os.getenv('DUNIKEY')
|
||||
node = os.getenv('NODE')
|
||||
if not node:
|
||||
sys.stderr.write("Please fill a Duniter node in .env file\n")
|
||||
sys.exit(1)
|
||||
|
||||
# Parse arguments
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('-p', '--pubkey', help="Clé publique du compte visé")
|
||||
parser.add_argument('--mempool', action='store_true', help="Utilise les sources en Mempool")
|
||||
args = parser.parse_args()
|
||||
|
||||
# Create transaction and send it
|
||||
hist = History(dunikey, node, args.pubkey, args.mempool)
|
||||
result = hist.history()
|
|
@ -0,0 +1,78 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys, re, os.path, json, ast
|
||||
from termcolor import colored
|
||||
from 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 TX generation document
|
||||
queryBuild = gql(
|
||||
"""
|
||||
query ($pubkey: String!){
|
||||
transactionsHistory(pubkey: $pubkey) {
|
||||
received {
|
||||
outputs
|
||||
}
|
||||
sent {
|
||||
outputs
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
)
|
||||
paramsBuild = {
|
||||
"pubkey": self.pubkey
|
||||
}
|
||||
|
||||
# Send TX 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)
|
||||
|
||||
res = self.historyDoc['transactionsHistory']['received']
|
||||
amount=[]
|
||||
for i in res:
|
||||
for output in i['outputs']:
|
||||
if re.search(self.pubkey, output):
|
||||
amount.append(int(output.split(':')[0]))
|
||||
receivedTotal = sum(amount)
|
||||
|
||||
res = self.historyDoc['transactionsHistory']['sent']
|
||||
amount=[]
|
||||
for i in res:
|
||||
for output in i['outputs']:
|
||||
if not re.search(self.pubkey, output):
|
||||
amount.append(int(output.split(':')[0]))
|
||||
sentTotal = sum(amount)
|
||||
|
||||
|
||||
# TODO: Get all UD from pubkey
|
||||
|
||||
|
||||
total = (receivedTotal-sentTotal)/100
|
||||
print(total)
|
||||
|
||||
def balance(self):
|
||||
self.sendDoc()
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys, re, os.path, json, ast
|
||||
from datetime import datetime
|
||||
from termcolor import colored
|
||||
from 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, 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 TX generation document
|
||||
queryBuild = gql(
|
||||
"""
|
||||
query ($pubkey: String!){
|
||||
transactionsHistory(pubkey: $pubkey) {
|
||||
received {
|
||||
writtenTime
|
||||
issuers
|
||||
outputs
|
||||
comment
|
||||
}
|
||||
sent {
|
||||
writtenTime
|
||||
issuers
|
||||
outputs
|
||||
comment
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
)
|
||||
paramsBuild = {
|
||||
"pubkey": self.pubkey
|
||||
}
|
||||
|
||||
# Send TX 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):
|
||||
|
||||
res = self.historyDoc['transactionsHistory']['received']
|
||||
transIn=[[0 for x in range(0)] for y in range(len(res))]
|
||||
for i, bloc in enumerate(res):
|
||||
for output in bloc['outputs']:
|
||||
if re.search(self.pubkey, output):
|
||||
transIn[i].append("IN")
|
||||
transIn[i].append(bloc['writtenTime'])
|
||||
transIn[i].append(bloc['issuers'][0])
|
||||
transIn[i].append(int(output.split(':')[0])/100)
|
||||
transIn[i].append(bloc['comment'])
|
||||
|
||||
|
||||
res = self.historyDoc['transactionsHistory']['sent']
|
||||
transOut=[[0 for x in range(0)] for y in range(len(res))]
|
||||
i = 0
|
||||
for bloc in res:
|
||||
for output in bloc['outputs']:
|
||||
if not re.search(self.pubkey, output):
|
||||
transOut[i].append("OUT")
|
||||
transOut[i].append(bloc['writtenTime'])
|
||||
transOut[i].append(output.split("SIG(")[1].replace(')',''))
|
||||
transOut[i].append(int(output.split(':')[0])/100)
|
||||
transOut[i].append(bloc['comment'])
|
||||
i += 1
|
||||
|
||||
trans = transIn + transOut
|
||||
trans = list(filter(None, trans))
|
||||
trans.sort(key=lambda x: x[1])
|
||||
|
||||
# Get terminal size
|
||||
rows = int(os.popen('stty size', 'r').read().split()[1])
|
||||
|
||||
print('-'.center(rows, '-'))
|
||||
print("{: <20} | {: <45} | {: <7} | {: <30}".format(" Date"," De la part de (clé publique)","Montant","Commentaire"))
|
||||
for i in trans:
|
||||
color = "green" if i[0] == "IN" else "blue"
|
||||
date = datetime.fromtimestamp(i[1]).strftime("%d/%m/%Y à %H:%M")
|
||||
print('-'.center(rows, '-'))
|
||||
print(colored("{: <20} | {: <45} | {: <7} | {: <30}".format(date, *i[2:]), color))
|
||||
# print(*i)
|
||||
|
||||
|
||||
def history(self):
|
||||
self.sendDoc()
|
||||
self.parseHistory()
|
||||
|
|
@ -6,19 +6,19 @@ from natools import fmt, sign, get_privkey
|
|||
from gql import gql, Client
|
||||
from gql.transport.aiohttp import AIOHTTPTransport
|
||||
|
||||
VERSION = "0.1.0"
|
||||
PUBKEY_REGEX = "(?![OIl])[1-9A-Za-z]{42,45}"
|
||||
|
||||
class Transaction:
|
||||
|
||||
def __init__(self, dunikey, node, recipient, amount, comment='', verbose=False):
|
||||
def __init__(self, dunikey, node, recipient, amount, comment='', useMempool=False, verbose=False):
|
||||
self.dunikey = dunikey
|
||||
self.recipient = recipient
|
||||
self.amount = amount
|
||||
self.comment = comment
|
||||
self.issuer = get_privkey(dunikey, "pubsec").pubkey
|
||||
self.useMempool = useMempool
|
||||
self.verbose = verbose
|
||||
self.isChange = False
|
||||
self._isChange = False
|
||||
|
||||
if not re.match(PUBKEY_REGEX, recipient) or len(recipient) > 45:
|
||||
sys.stderr.write("La clé publique n'est pas au bon format.\n")
|
||||
|
@ -34,14 +34,15 @@ class Transaction:
|
|||
|
||||
def genDoc(self):
|
||||
# Build TX generation document
|
||||
print(self.useMempool)
|
||||
queryBuild = gql(
|
||||
"""
|
||||
query ($recipient: String!, $issuer: String!, $amount: Int!, $comment: String!, $isChange: Boolean!){ genTxs(
|
||||
query ($recipient: String!, $issuer: String!, $amount: Int!, $comment: String!, $useMempool: Boolean!){ genTxs(
|
||||
amount: $amount
|
||||
comment: $comment
|
||||
issuer: $issuer
|
||||
recipient: $recipient
|
||||
useMempoolSources: $isChange
|
||||
useMempoolSources: $useMempool
|
||||
)
|
||||
}
|
||||
"""
|
||||
|
@ -51,7 +52,7 @@ class Transaction:
|
|||
"issuer": self.issuer,
|
||||
"amount": self.amount,
|
||||
"comment": self.comment,
|
||||
"isChange": self.isChange
|
||||
"useMempool": self.useMempool
|
||||
}
|
||||
|
||||
# Send TX document
|
||||
|
@ -144,6 +145,13 @@ class Transaction:
|
|||
|
||||
return txResult
|
||||
|
||||
def _getIsChange(self):
|
||||
return self._isChange
|
||||
def _setIsChange(self, newChange):
|
||||
self._isChange = newChange
|
||||
if newChange: self.useMempool == True
|
||||
isChange = property(_getIsChange, _setIsChange)
|
||||
|
||||
def send(self):
|
||||
result = self.genDoc()
|
||||
result = self.checkTXDoc()
|
||||
|
|
7
pay.py
7
pay.py
|
@ -4,7 +4,9 @@ import sys, argparse, os
|
|||
from os.path import join, dirname
|
||||
from shutil import copyfile
|
||||
from dotenv import load_dotenv
|
||||
from libs.paylib import Transaction, VERSION
|
||||
from libs.paylib import Transaction
|
||||
|
||||
VERSION = "0.1.1"
|
||||
|
||||
# Get variables environment
|
||||
if not os.path.isfile('.env'):
|
||||
|
@ -23,6 +25,7 @@ parser = argparse.ArgumentParser()
|
|||
parser.add_argument('-d', '--destinataire', help="Destinataire du paiement")
|
||||
parser.add_argument('-m', '--montant', type=int, help="Montant de la transaction")
|
||||
parser.add_argument('-c', '--commentaire', default="", help="Commentaire de la transaction")
|
||||
parser.add_argument('--mempool', action='store_true', help="Utilise les sources en Mempool")
|
||||
parser.add_argument('-v', '--verbose', action='store_true', help="Affiche le résultat JSON de la transaction")
|
||||
parser.add_argument('--version', action='store_true', help="Affiche la version actuelle du programme")
|
||||
args = parser.parse_args()
|
||||
|
@ -37,7 +40,7 @@ if not args.destinataire or not args.montant:
|
|||
sys.exit(1)
|
||||
|
||||
# Create transaction and send it
|
||||
trans = Transaction(dunikey, node, args.destinataire, args.montant, args.commentaire, args.verbose)
|
||||
trans = Transaction(dunikey, node, args.destinataire, args.montant, args.commentaire, args.mempool, args.verbose)
|
||||
result = trans.send()
|
||||
|
||||
if args.verbose:
|
||||
|
|
Reference in New Issue