diff --git a/account.py b/account.py index 0844c8c..37a85c5 100644 --- a/account.py +++ b/account.py @@ -659,6 +659,56 @@ def revoke(account,domain): } } +def sendBatch(account, batch): + account_name = check_account(account) + password = ":".join(account.split(":")[1:]) + + if account_name == False: + return { + "error": { + "message": "Invalid account" + } + } + + try: + response = hsw.rpc_selectWallet(account_name) + if response['error'] is not None: + return { + "error": { + "message": response['error']['message'] + } + } + response = hsw.rpc_walletPassphrase(password,10) + if response['error'] is not None: + return { + "error": { + "message": response['error']['message'] + } + } + response = requests.post(f"http://x:{APIKEY}@{ip}:12039",json={ + "method": "sendbatch", + "params": [batch] + }).json() + if response['error'] is not None: + return { + "error": { + "message": response['error']['message'] + } + } + if 'result' not in response: + return { + "error": { + "message": "No result" + } + } + + return response['result'] + except Exception as e: + return { + "error": { + "message": str(e) + } + } #region settingsAPIs diff --git a/plugins/batching.py b/plugins/batching.py new file mode 100644 index 0000000..c2379f8 --- /dev/null +++ b/plugins/batching.py @@ -0,0 +1,435 @@ +import json +import account +import requests + + +# Plugin Data +info = { + "name": "Batching Functions", + "description": "This is a plugin that provides multiple functions to batch transactions", + "version": "1.0", + "author": "Nathan.Woodburn/" +} +# https://hsd-dev.org/api-docs/?shell--cli#sendbatch + + +# Functions +functions = { + "transfer":{ + "name": "Batch transfer", + "type": "default", + "description": "Transfer a ton of domains", + "params": { + "domains": { + "name":"List of domains to transfer (one per line)", + "type":"longText" + }, + "address": { + "name":"Address to transfer to", + "type":"address" + } + }, + "returns": { + "status": + { + "name": "Status", + "type": "text" + }, + "transaction": + { + "name": "Hash of the transaction", + "type": "tx" + } + } + }, + "finalize":{ + "name": "Batch finalize a transfer", + "type": "default", + "description": "Finalize transferring a ton of domains", + "params": { + "domains": { + "name":"List of domains to finalize (one per line)", + "type":"longText" + } + }, + "returns": { + "status": + { + "name": "Status", + "type": "text" + }, + "transaction": + { + "name": "Hash of the transaction", + "type": "tx" + } + } + }, + "cancel":{ + "name": "Batch cancel a transfer", + "type": "default", + "description": "Cancel transferring a ton of domains", + "params": { + "domains": { + "name":"List of domains to cancel (one per line)", + "type":"longText" + } + }, + "returns": { + "status": + { + "name": "Status", + "type": "text" + }, + "transaction": + { + "name": "Hash of the transaction", + "type": "tx" + } + } + }, + "open":{ + "name": "Batch open auctions", + "type": "default", + "description": "Open auctions for a ton of domains", + "params": { + "domains": { + "name":"List of domains to open (one per line)", + "type":"longText" + } + }, + "returns": { + "status": + { + "name": "Status", + "type": "text" + }, + "transaction": + { + "name": "Hash of the transaction", + "type": "tx" + } + } + }, + "bid":{ + "name": "Batch bid on auctions", + "type": "default", + "description": "Bid on auctions for a ton of domains", + "params": { + "domains": { + "name":"List of domains to bid on (one per line)", + "type":"longText" + }, + "bid": { + "name":"Bid amount", + "type":"text" + }, + "blind": { + "name":"Blind amount", + "type":"text" + } + }, + "returns": { + "status": + { + "name": "Status", + "type": "text" + }, + "transaction": + { + "name": "Hash of the transaction", + "type": "tx" + } + } + }, + "reveal":{ + "name": "Batch reveal bids", + "type": "default", + "description": "Reveal bids for tons of auctions", + "params": { + "domains": { + "name":"List of domains to reveal (one per line)", + "type":"longText" + } + }, + "returns": { + "status": + { + "name": "Status", + "type": "text" + }, + "transaction": + { + "name": "Hash of the transaction", + "type": "tx" + } + } + }, + "redeem":{ + "name": "Batch redeem bids", + "type": "default", + "description": "Redeem lost bids to get funds back", + "params": { + "domains": { + "name":"List of domains to redeem (one per line)", + "type":"longText" + } + }, + "returns": { + "status": + { + "name": "Status", + "type": "text" + }, + "transaction": + { + "name": "Hash of the transaction", + "type": "tx" + } + } + }, + "register":{ + "name": "Batch register domains", + "type": "default", + "description": "Register domains won in auction", + "params": { + "domains": { + "name":"List of domains to redeem (one per line)", + "type":"longText" + } + }, + "returns": { + "status": + { + "name": "Status", + "type": "text" + }, + "transaction": + { + "name": "Hash of the transaction", + "type": "tx" + } + } + }, + "advancedBid":{ + "name": "Bid on domains with csv", + "type": "default", + "description": "Bid on domains using a csv format", + "params": { + "bids": { + "name":"List of bids in format `domain,bid,blind` (one per line)", + "type":"longText" + } + }, + "returns": { + "status": + { + "name": "Status", + "type": "text" + }, + "transaction": + { + "name": "Hash of the transaction", + "type": "tx" + } + } + }, + "advancedBatch":{ + "name": "Batch transactions with csv", + "type": "default", + "description": "Batch transactions using a csv format", + "params": { + "transactions": { + "name":"List of transactions in format `type,domain,param1,param2` (one per line) Eg.
TRANSFER,woodburn1,hs1q4rkfe5df7ss6wzhnw388hv27we0hp7ha2np0hk
OPEN,woodburn2", + "type":"longText" + } + }, + "returns": { + "status": + { + "name": "Status", + "type": "text" + }, + "transaction": + { + "name": "Hash of the transaction", + "type": "tx" + } + } + } +} + +def sendBatch(batch, authentication): + response = account.sendBatch(authentication, batch) + return response + + +def transfer(params, authentication): + domains = params["domains"] + address = params["address"] + domains = domains.splitlines() + + wallet = authentication.split(":")[0] + owned = account.getDomains(wallet) + # Only keep owned domains ["name"] + ownedNames = [domain["name"] for domain in owned] + + for domain in domains: + if domain not in ownedNames: + return { + "status":f"Domain {domain} not owned", + "transaction":None + } + + batch = [] + for domain in domains: + batch.append(['TRANSFER', domain, address]) + + response = sendBatch(batch, authentication) + if 'error' in response: + return { + "status":response['error']['message'], + "transaction":None + } + + return { + "status":"Sent batch successfully", + "transaction":response['hash'] + } + +def simple(batchType,params, authentication): + domains = params["domains"] + domains = domains.splitlines() + + batch = [] + for domain in domains: + batch.append([batchType, domain]) + + response = sendBatch(batch, authentication) + if 'error' in response: + return { + "status":response['error']['message'], + "transaction":None + } + + return { + "status":"Sent batch successfully", + "transaction":response['hash'] + } + +def finalize(params, authentication): + return simple("FINALIZE",params,authentication) + +def cancel(params, authentication): + return simple("CANCEL",params,authentication) + +def open(params, authentication): + return simple("OPEN",params,authentication) + +def bid(params, authentication): + domains = params["domains"] + domains = domains.splitlines() + try: + bid = float(params["bid"]) + blind = float(params["blind"]) + blind+=bid + except: + return { + "status":"Invalid bid amount", + "transaction":None + } + + batch = [] + for domain in domains: + batch.append(['BID', domain, bid, blind]) + + print(batch) + response = sendBatch(batch, authentication) + if 'error' in response: + return { + "status":response['error']['message'], + "transaction":None + } + + return { + "status":"Sent batch successfully", + "transaction":response['hash'] + } + +def reveal(params, authentication): + return simple("REVEAL",params,authentication) + +def redeem(params, authentication): + return simple("REDEEM",params,authentication) + +def register(params, authentication): + domains = params["domains"] + domains = domains.splitlines() + batch = [] + for domain in domains: + batch.append(['UPDATE', domain,{"records": []}]) + + print(batch) + response = sendBatch(batch, authentication) + if 'error' in response: + return { + "status":response['error']['message'], + "transaction":None + } + + return { + "status":"Sent batch successfully", + "transaction":response['hash'] + } + + +def advancedBid(params, authentication): + bids = params["bids"] + bids = bids.splitlines() + + batch = [] + for bid in bids: + # Split the bid + line = bid.split(",") + domain = line[0] + bid = float(line[1]) + blind = float(line[2]) + blind+=bid + batch.append(['BID', domain, bid, blind]) + + print(batch) + response = sendBatch(batch, authentication) + if 'error' in response: + return { + "status":response['error']['message'], + "transaction":None + } + + return { + "status":"Sent batch successfully", + "transaction":response['hash'] + } + +def advancedBatch(params, authentication): + transactions = params["transactions"] + transactions = transactions.splitlines() + + batch = [] + for transaction in transactions: + # Split the bid + line = transaction.split(",") + line[0] = line[0].upper() + batch.append(line) + + print(batch) + response = sendBatch(batch, authentication) + if 'error' in response: + return { + "status":response['error']['message'], + "transaction":None + } + + return { + "status":"Sent batch successfully", + "transaction":response['hash'] + } diff --git a/templates/components/tx.html b/templates/components/tx.html index c1e0c1e..88f3575 100644 --- a/templates/components/tx.html +++ b/templates/components/tx.html @@ -1,4 +1,5 @@ TX: {{tx}} Check your transaction on a block explorer Niami -3xpl \ No newline at end of file +3xpl +Cymon.de \ No newline at end of file