Compare commits
19 Commits
35d3ccd0c0
...
v1.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
fb9cb50a90
|
|||
|
db5e672d7b
|
|||
|
8ec23e3a32
|
|||
|
f84359a74b
|
|||
|
92f05992ab
|
|||
|
2ae618c68a
|
|||
|
cfb814d006
|
|||
|
8c61a09e5b
|
|||
|
5c61bad9a2
|
|||
|
209c3794fc
|
|||
|
8099320673
|
|||
|
aa92220756
|
|||
|
2595503dc0
|
|||
|
d516e91592
|
|||
|
b24a3147dd
|
|||
|
f8e03aca73
|
|||
|
38f08c069c
|
|||
|
16ac6c7d2b
|
|||
|
b0c7fcf779
|
1
.gitignore
vendored
1
.gitignore
vendored
@@ -12,3 +12,4 @@ plugins/signatures.json
|
|||||||
.venv/
|
.venv/
|
||||||
|
|
||||||
user_data/
|
user_data/
|
||||||
|
customPlugins/
|
||||||
@@ -10,6 +10,7 @@ COPY . /app
|
|||||||
|
|
||||||
# Add mount point for data volume
|
# Add mount point for data volume
|
||||||
# VOLUME /data
|
# VOLUME /data
|
||||||
|
RUN apk add git
|
||||||
|
|
||||||
ENTRYPOINT ["python3"]
|
ENTRYPOINT ["python3"]
|
||||||
CMD ["server.py"]
|
CMD ["server.py"]
|
||||||
|
|||||||
Binary file not shown.
@@ -34,7 +34,6 @@ Then access the wallet at http://localhost:5000
|
|||||||
|
|
||||||
|
|
||||||
Also available as a docker image:
|
Also available as a docker image:
|
||||||
|
|
||||||
To run using a HSD running directly on the host:
|
To run using a HSD running directly on the host:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -47,6 +46,8 @@ If you have HSD running on a different IP/container
|
|||||||
sudo docker run -p 5000:5000 -e hsd_api=yourapikeyhere -e hsd_ip=hsdcontainer git.woodburn.au/nathanwoodburn/firewallet:latest
|
sudo docker run -p 5000:5000 -e hsd_api=yourapikeyhere -e hsd_ip=hsdcontainer git.woodburn.au/nathanwoodburn/firewallet:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
|
For Docker you can mount a volume to persist the user data (/app/user_data)
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
- Basic wallet functionality
|
- Basic wallet functionality
|
||||||
- Create new wallet
|
- Create new wallet
|
||||||
|
|||||||
22
main.py
22
main.py
@@ -1300,8 +1300,8 @@ def plugins_index():
|
|||||||
wallet_status=account_module.getWalletStatus(),
|
wallet_status=account_module.getWalletStatus(),
|
||||||
plugins=plugins)
|
plugins=plugins)
|
||||||
|
|
||||||
@app.route('/plugin/<plugin>')
|
@app.route('/plugin/<ptype>/<path:plugin>')
|
||||||
def plugin(plugin):
|
def plugin(ptype,plugin):
|
||||||
# Check if the user is logged in
|
# Check if the user is logged in
|
||||||
if request.cookies.get("account") is None:
|
if request.cookies.get("account") is None:
|
||||||
return redirect("/login")
|
return redirect("/login")
|
||||||
@@ -1310,7 +1310,10 @@ def plugin(plugin):
|
|||||||
if not account:
|
if not account:
|
||||||
return redirect("/logout")
|
return redirect("/logout")
|
||||||
|
|
||||||
|
plugin = f"{ptype}/{plugin}"
|
||||||
|
|
||||||
if not plugins_module.pluginExists(plugin):
|
if not plugins_module.pluginExists(plugin):
|
||||||
|
print(f"Plugin {plugin} not found")
|
||||||
return redirect("/plugins")
|
return redirect("/plugins")
|
||||||
|
|
||||||
data = plugins_module.getPluginData(plugin)
|
data = plugins_module.getPluginData(plugin)
|
||||||
@@ -1330,10 +1333,10 @@ def plugin(plugin):
|
|||||||
wallet_status=account_module.getWalletStatus(),
|
wallet_status=account_module.getWalletStatus(),
|
||||||
name=data['name'],description=data['description'],
|
name=data['name'],description=data['description'],
|
||||||
author=data['author'],version=data['version'],
|
author=data['author'],version=data['version'],
|
||||||
functions=functions,error=error)
|
source=data['source'],functions=functions,error=error)
|
||||||
|
|
||||||
@app.route('/plugin/<plugin>/verify')
|
@app.route('/plugin/<ptype>/<path:plugin>/verify')
|
||||||
def plugin_verify(plugin):
|
def plugin_verify(ptype,plugin):
|
||||||
# Check if the user is logged in
|
# Check if the user is logged in
|
||||||
if request.cookies.get("account") is None:
|
if request.cookies.get("account") is None:
|
||||||
return redirect("/login")
|
return redirect("/login")
|
||||||
@@ -1342,6 +1345,8 @@ def plugin_verify(plugin):
|
|||||||
if not account:
|
if not account:
|
||||||
return redirect("/logout")
|
return redirect("/logout")
|
||||||
|
|
||||||
|
plugin = f"{ptype}/{plugin}"
|
||||||
|
|
||||||
if not plugins_module.pluginExists(plugin):
|
if not plugins_module.pluginExists(plugin):
|
||||||
return redirect("/plugins")
|
return redirect("/plugins")
|
||||||
|
|
||||||
@@ -1352,8 +1357,8 @@ def plugin_verify(plugin):
|
|||||||
|
|
||||||
return redirect("/plugin/" + plugin)
|
return redirect("/plugin/" + plugin)
|
||||||
|
|
||||||
@app.route('/plugin/<plugin>/<function>', methods=["POST"])
|
@app.route('/plugin/<ptype>/<path:plugin>/<function>', methods=["POST"])
|
||||||
def plugin_function(plugin,function):
|
def plugin_function(ptype,plugin,function):
|
||||||
# Check if the user is logged in
|
# Check if the user is logged in
|
||||||
if request.cookies.get("account") is None:
|
if request.cookies.get("account") is None:
|
||||||
return redirect("/login")
|
return redirect("/login")
|
||||||
@@ -1362,6 +1367,8 @@ def plugin_function(plugin,function):
|
|||||||
if not account:
|
if not account:
|
||||||
return redirect("/logout")
|
return redirect("/logout")
|
||||||
|
|
||||||
|
plugin = f"{ptype}/{plugin}"
|
||||||
|
|
||||||
if not plugins_module.pluginExists(plugin):
|
if not plugins_module.pluginExists(plugin):
|
||||||
return redirect("/plugins")
|
return redirect("/plugins")
|
||||||
|
|
||||||
@@ -1394,7 +1401,6 @@ def plugin_function(plugin,function):
|
|||||||
return redirect("/plugin/" + plugin + "?error=" + response['error'])
|
return redirect("/plugin/" + plugin + "?error=" + response['error'])
|
||||||
|
|
||||||
response = render.plugin_output(response,plugins_module.getPluginFunctionReturns(plugin,function))
|
response = render.plugin_output(response,plugins_module.getPluginFunctionReturns(plugin,function))
|
||||||
|
|
||||||
return render_template("plugin-output.html", account=account, sync=account_module.getNodeSync(),
|
return render_template("plugin-output.html", account=account, sync=account_module.getNodeSync(),
|
||||||
wallet_status=account_module.getWalletStatus(),
|
wallet_status=account_module.getWalletStatus(),
|
||||||
name=data['name'],description=data['description'],output=response)
|
name=data['name'],description=data['description'],output=response)
|
||||||
|
|||||||
84
plugin.py
84
plugin.py
@@ -3,10 +3,12 @@ import json
|
|||||||
import importlib
|
import importlib
|
||||||
import sys
|
import sys
|
||||||
import hashlib
|
import hashlib
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
|
||||||
def listPlugins():
|
def listPlugins():
|
||||||
plugins = []
|
plugins = []
|
||||||
|
customPlugins = []
|
||||||
for file in os.listdir("plugins"):
|
for file in os.listdir("plugins"):
|
||||||
if file.endswith(".py"):
|
if file.endswith(".py"):
|
||||||
if file != "main.py":
|
if file != "main.py":
|
||||||
@@ -14,17 +16,50 @@ def listPlugins():
|
|||||||
if "info" not in dir(plugin):
|
if "info" not in dir(plugin):
|
||||||
continue
|
continue
|
||||||
details = plugin.info
|
details = plugin.info
|
||||||
details["link"] = file[:-3]
|
details["source"] = "built-in"
|
||||||
|
details["link"] = f"plugins/{file[:-3]}"
|
||||||
|
plugins.append(details)
|
||||||
|
|
||||||
|
# Check for imported plugins
|
||||||
|
if not os.path.exists("user_data/plugins.json"):
|
||||||
|
with open("user_data/plugins.json", "w") as f:
|
||||||
|
json.dump([], f)
|
||||||
|
|
||||||
|
with open("user_data/plugins.json", "r") as f:
|
||||||
|
importurls = json.load(f)
|
||||||
|
|
||||||
|
for importurl in importurls:
|
||||||
|
# Get only repo name
|
||||||
|
importPath = importurl.split("/")[-1].removesuffix(".git")
|
||||||
|
|
||||||
|
# Git clone into customPlugins/<importPath>
|
||||||
|
if not os.path.exists(f"customPlugins/{importPath}"):
|
||||||
|
if os.system(f"git clone {importurl} customPlugins/{importPath}") != 0:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
if os.system(f"cd customPlugins/{importPath} && git pull") != 0:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Import plugins from customPlugins/<importPath>
|
||||||
|
for file in os.listdir(f"customPlugins/{importPath}"):
|
||||||
|
if file.endswith(".py"):
|
||||||
|
if file != "main.py":
|
||||||
|
plugin = importlib.import_module(f"customPlugins.{importPath}."+file[:-3])
|
||||||
|
if "info" not in dir(plugin):
|
||||||
|
continue
|
||||||
|
details = plugin.info
|
||||||
|
details["source"] = importPath
|
||||||
|
details["link"] = f"customPlugins/{importPath}/{file[:-3]}"
|
||||||
plugins.append(details)
|
plugins.append(details)
|
||||||
|
|
||||||
# Verify plugin signature
|
# Verify plugin signature
|
||||||
signatures = []
|
signatures = []
|
||||||
try:
|
try:
|
||||||
with open("plugins/signatures.json", "r") as f:
|
with open("user_data/plugin_signatures.json", "r") as f:
|
||||||
signatures = json.load(f)
|
signatures = json.load(f)
|
||||||
except:
|
except:
|
||||||
# Write a new signatures file
|
# Write a new signatures file
|
||||||
with open("plugins/signatures.json", "w") as f:
|
with open("user_data/plugin_signatures.json", "w") as f:
|
||||||
json.dump(signatures, f)
|
json.dump(signatures, f)
|
||||||
|
|
||||||
for plugin in plugins:
|
for plugin in plugins:
|
||||||
@@ -39,34 +74,31 @@ def listPlugins():
|
|||||||
|
|
||||||
|
|
||||||
def pluginExists(plugin: str):
|
def pluginExists(plugin: str):
|
||||||
for file in os.listdir("plugins"):
|
return os.path.exists(plugin+".py")
|
||||||
if file == plugin+".py":
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def verifyPlugin(plugin: str):
|
def verifyPlugin(plugin: str):
|
||||||
signatures = []
|
signatures = []
|
||||||
try:
|
try:
|
||||||
with open("plugins/signatures.json", "r") as f:
|
with open("user_data/plugin_signatures.json", "r") as f:
|
||||||
signatures = json.load(f)
|
signatures = json.load(f)
|
||||||
except:
|
except:
|
||||||
# Write a new signatures file
|
# Write a new signatures file
|
||||||
with open("plugins/signatures.json", "w") as f:
|
with open("user_data/plugin_signatures.json", "w") as f:
|
||||||
json.dump(signatures, f)
|
json.dump(signatures, f)
|
||||||
|
|
||||||
# Hash the plugin file
|
# Hash the plugin file
|
||||||
pluginHash = hashPlugin(plugin)
|
pluginHash = hashPlugin(plugin)
|
||||||
if pluginHash not in signatures:
|
if pluginHash not in signatures:
|
||||||
signatures.append(pluginHash)
|
signatures.append(pluginHash)
|
||||||
with open("plugins/signatures.json", "w") as f:
|
with open("user_data/plugin_signatures.json", "w") as f:
|
||||||
json.dump(signatures, f)
|
json.dump(signatures, f)
|
||||||
|
|
||||||
|
|
||||||
def hashPlugin(plugin: str):
|
def hashPlugin(plugin: str):
|
||||||
BUF_SIZE = 65536
|
BUF_SIZE = 65536
|
||||||
sha256 = hashlib.sha256()
|
sha256 = hashlib.sha256()
|
||||||
with open("plugins/"+plugin+".py", 'rb') as f:
|
with open(plugin+".py", 'rb') as f:
|
||||||
while True:
|
while True:
|
||||||
data = f.read(BUF_SIZE)
|
data = f.read(BUF_SIZE)
|
||||||
if not data:
|
if not data:
|
||||||
@@ -76,19 +108,31 @@ def hashPlugin(plugin: str):
|
|||||||
|
|
||||||
|
|
||||||
def getPluginData(pluginStr: str):
|
def getPluginData(pluginStr: str):
|
||||||
plugin = importlib.import_module("plugins."+pluginStr)
|
plugin = importlib.import_module(pluginStr.replace("/","."))
|
||||||
|
|
||||||
# Check if the plugin is verified
|
# Check if the plugin is verified
|
||||||
signatures = []
|
signatures = []
|
||||||
try:
|
try:
|
||||||
with open("plugins/signatures.json", "r") as f:
|
with open("user_data/plugin_signatures.json", "r") as f:
|
||||||
signatures = json.load(f)
|
signatures = json.load(f)
|
||||||
except:
|
except:
|
||||||
# Write a new signatures file
|
# Write a new signatures file
|
||||||
with open("plugins/signatures.json", "w") as f:
|
with open("user_data/plugin_signatures.json", "w") as f:
|
||||||
json.dump(signatures, f)
|
json.dump(signatures, f)
|
||||||
|
|
||||||
info = plugin.info
|
info = plugin.info
|
||||||
|
info["source"] = "built-in"
|
||||||
|
|
||||||
|
# Check if the plugin is in customPlugins
|
||||||
|
if pluginStr.startswith("customPlugins"):
|
||||||
|
# Get git url for dir
|
||||||
|
print(f"cd customPlugins/{pluginStr.split('/')[-2]} && git remote get-url origin")
|
||||||
|
url = subprocess.check_output(f"cd customPlugins/{pluginStr.split('/')[-2]} && git remote get-url origin", shell=True).decode("utf-8").strip()
|
||||||
|
info["source"] = url
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Hash the plugin file
|
# Hash the plugin file
|
||||||
pluginHash = hashPlugin(pluginStr)
|
pluginHash = hashPlugin(pluginStr)
|
||||||
if pluginHash not in signatures:
|
if pluginHash not in signatures:
|
||||||
@@ -100,12 +144,12 @@ def getPluginData(pluginStr: str):
|
|||||||
|
|
||||||
|
|
||||||
def getPluginFunctions(plugin: str):
|
def getPluginFunctions(plugin: str):
|
||||||
plugin = importlib.import_module("plugins."+plugin)
|
plugin = importlib.import_module(plugin.replace("/","."))
|
||||||
return plugin.functions
|
return plugin.functions
|
||||||
|
|
||||||
|
|
||||||
def runPluginFunction(plugin: str, function: str, params: dict, authentication: str):
|
def runPluginFunction(plugin: str, function: str, params: dict, authentication: str):
|
||||||
plugin_module = importlib.import_module("plugins."+plugin)
|
plugin_module = importlib.import_module(plugin.replace("/","."))
|
||||||
if function not in plugin_module.functions:
|
if function not in plugin_module.functions:
|
||||||
return {"error": "Function not found"}
|
return {"error": "Function not found"}
|
||||||
|
|
||||||
@@ -118,11 +162,11 @@ def runPluginFunction(plugin: str, function: str, params: dict, authentication:
|
|||||||
# Check if the function is in the signature list
|
# Check if the function is in the signature list
|
||||||
signatures = []
|
signatures = []
|
||||||
try:
|
try:
|
||||||
with open("plugins/signatures.json", "r") as f:
|
with open("user_data/plugin_signatures.json", "r") as f:
|
||||||
signatures = json.load(f)
|
signatures = json.load(f)
|
||||||
except:
|
except:
|
||||||
# Write a new signatures file
|
# Write a new signatures file
|
||||||
with open("plugins/signatures.json", "w") as f:
|
with open("user_data/plugin_signatures.json", "w") as f:
|
||||||
json.dump(signatures, f)
|
json.dump(signatures, f)
|
||||||
|
|
||||||
# Hash the plugin file
|
# Hash the plugin file
|
||||||
@@ -141,12 +185,12 @@ def runPluginFunction(plugin: str, function: str, params: dict, authentication:
|
|||||||
|
|
||||||
|
|
||||||
def getPluginFunctionInputs(plugin: str, function: str):
|
def getPluginFunctionInputs(plugin: str, function: str):
|
||||||
plugin = importlib.import_module("plugins."+plugin)
|
plugin = importlib.import_module(plugin.replace("/","."))
|
||||||
return plugin.functions[function]["params"]
|
return plugin.functions[function]["params"]
|
||||||
|
|
||||||
|
|
||||||
def getPluginFunctionReturns(plugin: str, function: str):
|
def getPluginFunctionReturns(plugin: str, function: str):
|
||||||
plugin = importlib.import_module("plugins."+plugin)
|
plugin = importlib.import_module(plugin.replace("/","."))
|
||||||
return plugin.functions[function]["returns"]
|
return plugin.functions[function]["returns"]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -500,10 +500,6 @@ def advancedChangeLookahead(params, authentication):
|
|||||||
lookahead = int(lookahead)
|
lookahead = int(lookahead)
|
||||||
wallet = authentication.split(":")[0]
|
wallet = authentication.split(":")[0]
|
||||||
password = ":".join(authentication.split(":")[1:])
|
password = ":".join(authentication.split(":")[1:])
|
||||||
# curl http://x:api-key@127.0.0.1:14039/wallet/$id/account/$name \
|
|
||||||
# -X PATCH \
|
|
||||||
# --data '{"lookahead": $lookahead}'
|
|
||||||
|
|
||||||
APIKEY = os.getenv("hsd_api")
|
APIKEY = os.getenv("hsd_api")
|
||||||
ip = os.getenv("hsd_ip")
|
ip = os.getenv("hsd_ip")
|
||||||
if ip is None:
|
if ip is None:
|
||||||
|
|||||||
114
plugins/customPlugins.py
Normal file
114
plugins/customPlugins.py
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
import json
|
||||||
|
import account
|
||||||
|
import requests
|
||||||
|
import os
|
||||||
|
|
||||||
|
# Plugin Data
|
||||||
|
info = {
|
||||||
|
"name": "Custom Plugin Manager",
|
||||||
|
"description": "Import custom plugins from git repositories",
|
||||||
|
"version": "1.0",
|
||||||
|
"author": "Nathan.Woodburn/"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Functions
|
||||||
|
functions = {
|
||||||
|
"add":{
|
||||||
|
"name": "Add Plugin repo",
|
||||||
|
"type": "default",
|
||||||
|
"description": "Add a plugin repo",
|
||||||
|
"params": {
|
||||||
|
"url": {
|
||||||
|
"name":"URL",
|
||||||
|
"type":"text"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"returns": {
|
||||||
|
"status":
|
||||||
|
{
|
||||||
|
"name": "Status of the function",
|
||||||
|
"type": "text"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"remove":{
|
||||||
|
"name": "Remove Plugins",
|
||||||
|
"type": "default",
|
||||||
|
"description": "Remove a plugin repo from the list",
|
||||||
|
"params": {
|
||||||
|
"url": {
|
||||||
|
"name":"URL",
|
||||||
|
"type":"text"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"returns": {
|
||||||
|
"status":
|
||||||
|
{
|
||||||
|
"name": "Status of the function",
|
||||||
|
"type": "text"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"list":{
|
||||||
|
"name": "List Plugins",
|
||||||
|
"type": "default",
|
||||||
|
"description": "List all imported plugins",
|
||||||
|
"params": {},
|
||||||
|
"returns": {
|
||||||
|
"plugins":
|
||||||
|
{
|
||||||
|
"name": "List of plugins",
|
||||||
|
"type": "list"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def add(params, authentication):
|
||||||
|
url = params["url"]
|
||||||
|
if not os.path.exists("user_data/plugins.json"):
|
||||||
|
with open("user_data/plugins.json", "w") as f:
|
||||||
|
json.dump([], f)
|
||||||
|
|
||||||
|
with open("user_data/plugins.json", "r") as f:
|
||||||
|
importurls = json.load(f)
|
||||||
|
|
||||||
|
# Check if the plugin is already imported
|
||||||
|
if url in importurls:
|
||||||
|
return {"status": "Plugin already imported"}
|
||||||
|
|
||||||
|
importurls.append(url)
|
||||||
|
with open("user_data/plugins.json", "w") as f:
|
||||||
|
json.dump(importurls, f)
|
||||||
|
|
||||||
|
return {"status": "Imported"}
|
||||||
|
|
||||||
|
|
||||||
|
def remove(params, authentication):
|
||||||
|
url = params["url"]
|
||||||
|
if not os.path.exists("user_data/plugins.json"):
|
||||||
|
with open("user_data/plugins.json", "w") as f:
|
||||||
|
json.dump([], f)
|
||||||
|
|
||||||
|
with open("user_data/plugins.json", "r") as f:
|
||||||
|
importurls = json.load(f)
|
||||||
|
|
||||||
|
# Check if the plugin is already imported
|
||||||
|
if url not in importurls:
|
||||||
|
return {"status": "Plugin not imported"}
|
||||||
|
|
||||||
|
importurls.remove(url)
|
||||||
|
with open("user_data/plugins.json", "w") as f:
|
||||||
|
json.dump(importurls, f)
|
||||||
|
|
||||||
|
return {"status": "Removed"}
|
||||||
|
|
||||||
|
def list(params, authentication):
|
||||||
|
if not os.path.exists("user_data/plugins.json"):
|
||||||
|
with open("user_data/plugins.json", "w") as f:
|
||||||
|
json.dump([], f)
|
||||||
|
|
||||||
|
with open("user_data/plugins.json", "r") as f:
|
||||||
|
importurls = json.load(f)
|
||||||
|
|
||||||
|
return {"plugins": importurls}
|
||||||
@@ -51,10 +51,11 @@ def main(params, authentication):
|
|||||||
|
|
||||||
# Unlock wallet
|
# Unlock wallet
|
||||||
api_key = os.getenv("hsd_api")
|
api_key = os.getenv("hsd_api")
|
||||||
|
ip = os.getenv("hsd_ip")
|
||||||
if api_key is None:
|
if api_key is None:
|
||||||
print("API key not set")
|
print("API key not set")
|
||||||
return {"status": "API key not set", "transaction": "None"}
|
return {"status": "API key not set", "transaction": "None"}
|
||||||
response = requests.post(f'http://x:{api_key}@127.0.0.1:12039/wallet/{wallet}/unlock',
|
response = requests.post(f'http://x:{api_key}@{ip}:12039/wallet/{wallet}/unlock',
|
||||||
json={'passphrase': password, 'timeout': 600})
|
json={'passphrase': password, 'timeout': 600})
|
||||||
if response.status_code != 200:
|
if response.status_code != 200:
|
||||||
print("Failed to unlock wallet")
|
print("Failed to unlock wallet")
|
||||||
@@ -73,11 +74,11 @@ def main(params, authentication):
|
|||||||
|
|
||||||
batchTX = "[" + ", ".join(batch) + "]"
|
batchTX = "[" + ", ".join(batch) + "]"
|
||||||
responseContent = f'{{"method": "sendbatch","params":[ {batchTX} ]}}'
|
responseContent = f'{{"method": "sendbatch","params":[ {batchTX} ]}}'
|
||||||
response = requests.post(f'http://x:{api_key}@127.0.0.1:12039', data=responseContent)
|
response = requests.post(f'http://x:{api_key}@{ip}:12039', data=responseContent)
|
||||||
if response.status_code != 200:
|
if response.status_code != 200:
|
||||||
print("Failed to create batch")
|
print("Failed to create batch",flush=True)
|
||||||
print(f'Status code: {response.status_code}')
|
print(f'Status code: {response.status_code}',flush=True)
|
||||||
print(f'Response: {response.text}')
|
print(f'Response: {response.text}',flush=True)
|
||||||
return {"status": "Failed", "transaction": "None"}
|
return {"status": "Failed", "transaction": "None"}
|
||||||
|
|
||||||
batch = response.json()
|
batch = response.json()
|
||||||
@@ -85,9 +86,9 @@ def main(params, authentication):
|
|||||||
print("Verifying tx...")
|
print("Verifying tx...")
|
||||||
if batch["error"]:
|
if batch["error"]:
|
||||||
if batch["error"] != "":
|
if batch["error"] != "":
|
||||||
print("Failed to verify batch")
|
print("Failed to verify batch",flush=True)
|
||||||
print(batch["error"]["message"])
|
print(batch["error"]["message"],flush=True)
|
||||||
return {"status": "Failed", "transaction": "None"}
|
return {"status": f"Failed: {batch['error']['message']}", "transaction": "None"}
|
||||||
|
|
||||||
if 'result' in batch:
|
if 'result' in batch:
|
||||||
if batch['result'] != None:
|
if batch['result'] != None:
|
||||||
|
|||||||
@@ -35,7 +35,6 @@
|
|||||||
<li class="nav-item"><a class="nav-link" href="/receive"><i class="material-icons">call_received</i><span>Receive</span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/receive"><i class="material-icons">call_received</i><span>Receive</span></a></li>
|
||||||
<li class="nav-item"><a class="nav-link" href="/plugins"><i class="material-icons">code</i><span>Plugins</span></a><a class="nav-link" href="/settings"><i class="material-icons">settings</i><span>Settings</span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/plugins"><i class="material-icons">code</i><span>Plugins</span></a><a class="nav-link" href="/settings"><i class="material-icons">settings</i><span>Settings</span></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="text-center d-none d-md-inline"><button class="btn rounded-circle border-0" id="sidebarToggle" type="button"></button></div>
|
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
||||||
|
|||||||
@@ -35,7 +35,6 @@
|
|||||||
<li class="nav-item"><a class="nav-link" href="/receive"><i class="material-icons">call_received</i><span>Receive</span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/receive"><i class="material-icons">call_received</i><span>Receive</span></a></li>
|
||||||
<li class="nav-item"><a class="nav-link" href="/plugins"><i class="material-icons">code</i><span>Plugins</span></a><a class="nav-link" href="/settings"><i class="material-icons">settings</i><span>Settings</span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/plugins"><i class="material-icons">code</i><span>Plugins</span></a><a class="nav-link" href="/settings"><i class="material-icons">settings</i><span>Settings</span></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="text-center d-none d-md-inline"><button class="btn rounded-circle border-0" id="sidebarToggle" type="button"></button></div>
|
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
||||||
|
|||||||
@@ -35,7 +35,6 @@
|
|||||||
<li class="nav-item"><a class="nav-link" href="/receive"><i class="material-icons">call_received</i><span>Receive</span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/receive"><i class="material-icons">call_received</i><span>Receive</span></a></li>
|
||||||
<li class="nav-item"><a class="nav-link" href="/plugins"><i class="material-icons">code</i><span>Plugins</span></a><a class="nav-link" href="/settings"><i class="material-icons">settings</i><span>Settings</span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/plugins"><i class="material-icons">code</i><span>Plugins</span></a><a class="nav-link" href="/settings"><i class="material-icons">settings</i><span>Settings</span></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="text-center d-none d-md-inline"><button class="btn rounded-circle border-0" id="sidebarToggle" type="button"></button></div>
|
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<div class="card shadow border-start-warning py-2">
|
<div class="card shadow border-start-warning py-2">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="text-uppercase fw-bold text-xs mb-1"><span style="color: var(--bs-dark);">{{name}}</span></div>
|
<div class="text-uppercase fw-bold text-xs mb-1"><span style="color: var(--bs-dark);">{{name}}</span></div>
|
||||||
<div class="text-dark fw-bold h5 mb-0"><span>{{output}}</span></div>
|
<div class="text-dark fw-bold h5 mb-0"><span>{{output | safe}}</span></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -35,7 +35,6 @@
|
|||||||
<li class="nav-item"><a class="nav-link" href="/receive"><i class="material-icons">call_received</i><span>Receive</span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/receive"><i class="material-icons">call_received</i><span>Receive</span></a></li>
|
||||||
<li class="nav-item"><a class="nav-link" href="/plugins"><i class="material-icons">code</i><span>Plugins</span></a><a class="nav-link" href="/settings"><i class="material-icons">settings</i><span>Settings</span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/plugins"><i class="material-icons">code</i><span>Plugins</span></a><a class="nav-link" href="/settings"><i class="material-icons">settings</i><span>Settings</span></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="text-center d-none d-md-inline"><button class="btn rounded-circle border-0" id="sidebarToggle" type="button"></button></div>
|
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
||||||
|
|||||||
@@ -35,7 +35,6 @@
|
|||||||
<li class="nav-item"><a class="nav-link" href="/receive"><i class="material-icons">call_received</i><span>Receive</span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/receive"><i class="material-icons">call_received</i><span>Receive</span></a></li>
|
||||||
<li class="nav-item"><a class="nav-link" href="/plugins"><i class="material-icons">code</i><span>Plugins</span></a><a class="nav-link" href="/settings"><i class="material-icons">settings</i><span>Settings</span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/plugins"><i class="material-icons">code</i><span>Plugins</span></a><a class="nav-link" href="/settings"><i class="material-icons">settings</i><span>Settings</span></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="text-center d-none d-md-inline"><button class="btn rounded-circle border-0" id="sidebarToggle" type="button"></button></div>
|
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
||||||
|
|||||||
@@ -35,7 +35,6 @@
|
|||||||
<li class="nav-item"><a class="nav-link" href="/receive"><i class="material-icons">call_received</i><span>Receive</span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/receive"><i class="material-icons">call_received</i><span>Receive</span></a></li>
|
||||||
<li class="nav-item"><a class="nav-link" href="/plugins"><i class="material-icons">code</i><span>Plugins</span></a><a class="nav-link" href="/settings"><i class="material-icons">settings</i><span>Settings</span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/plugins"><i class="material-icons">code</i><span>Plugins</span></a><a class="nav-link" href="/settings"><i class="material-icons">settings</i><span>Settings</span></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="text-center d-none d-md-inline"><button class="btn rounded-circle border-0" id="sidebarToggle" type="button"></button></div>
|
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
||||||
|
|||||||
@@ -35,7 +35,6 @@
|
|||||||
<li class="nav-item"><a class="nav-link" href="/receive"><i class="material-icons">call_received</i><span>Receive</span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/receive"><i class="material-icons">call_received</i><span>Receive</span></a></li>
|
||||||
<li class="nav-item"><a class="nav-link" href="/plugins"><i class="material-icons">code</i><span>Plugins</span></a><a class="nav-link" href="/settings"><i class="material-icons">settings</i><span>Settings</span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/plugins"><i class="material-icons">code</i><span>Plugins</span></a><a class="nav-link" href="/settings"><i class="material-icons">settings</i><span>Settings</span></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="text-center d-none d-md-inline"><button class="btn rounded-circle border-0" id="sidebarToggle" type="button"></button></div>
|
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
||||||
|
|||||||
@@ -35,7 +35,6 @@
|
|||||||
<li class="nav-item"><a class="nav-link" href="/receive"><i class="material-icons">call_received</i><span>Receive</span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/receive"><i class="material-icons">call_received</i><span>Receive</span></a></li>
|
||||||
<li class="nav-item"><a class="nav-link" href="/plugins"><i class="material-icons">code</i><span>Plugins</span></a><a class="nav-link" href="/settings"><i class="material-icons">settings</i><span>Settings</span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/plugins"><i class="material-icons">code</i><span>Plugins</span></a><a class="nav-link" href="/settings"><i class="material-icons">settings</i><span>Settings</span></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="text-center d-none d-md-inline"><button class="btn rounded-circle border-0" id="sidebarToggle" type="button"></button></div>
|
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
||||||
|
|||||||
@@ -35,7 +35,6 @@
|
|||||||
<li class="nav-item"><a class="nav-link" href="/receive"><i class="material-icons">call_received</i><span>Receive</span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/receive"><i class="material-icons">call_received</i><span>Receive</span></a></li>
|
||||||
<li class="nav-item"><a class="nav-link" href="/plugins"><i class="material-icons">code</i><span>Plugins</span></a><a class="nav-link" href="/settings"><i class="material-icons">settings</i><span>Settings</span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/plugins"><i class="material-icons">code</i><span>Plugins</span></a><a class="nav-link" href="/settings"><i class="material-icons">settings</i><span>Settings</span></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="text-center d-none d-md-inline"><button class="btn rounded-circle border-0" id="sidebarToggle" type="button"></button></div>
|
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
||||||
|
|||||||
@@ -35,7 +35,6 @@
|
|||||||
<li class="nav-item"><a class="nav-link" href="/receive"><i class="material-icons">call_received</i><span>Receive</span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/receive"><i class="material-icons">call_received</i><span>Receive</span></a></li>
|
||||||
<li class="nav-item"><a class="nav-link" href="/plugins"><i class="material-icons">code</i><span>Plugins</span></a><a class="nav-link" href="/settings"><i class="material-icons">settings</i><span>Settings</span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/plugins"><i class="material-icons">code</i><span>Plugins</span></a><a class="nav-link" href="/settings"><i class="material-icons">settings</i><span>Settings</span></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="text-center d-none d-md-inline"><button class="btn rounded-circle border-0" id="sidebarToggle" type="button"></button></div>
|
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
||||||
|
|||||||
@@ -35,7 +35,6 @@
|
|||||||
<li class="nav-item"><a class="nav-link" href="/receive"><i class="material-icons">call_received</i><span>Receive</span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/receive"><i class="material-icons">call_received</i><span>Receive</span></a></li>
|
||||||
<li class="nav-item"><a class="nav-link" href="/plugins"><i class="material-icons">code</i><span>Plugins</span></a><a class="nav-link" href="/settings"><i class="material-icons">settings</i><span>Settings</span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/plugins"><i class="material-icons">code</i><span>Plugins</span></a><a class="nav-link" href="/settings"><i class="material-icons">settings</i><span>Settings</span></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="text-center d-none d-md-inline"><button class="btn rounded-circle border-0" id="sidebarToggle" type="button"></button></div>
|
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
||||||
@@ -67,7 +66,7 @@
|
|||||||
<div class="container-fluid" style="margin-bottom: 20px;">
|
<div class="container-fluid" style="margin-bottom: 20px;">
|
||||||
<h3 class="text-dark mb-1">{{name}}</h3>
|
<h3 class="text-dark mb-1">{{name}}</h3>
|
||||||
<h4 class="text-dark mb-1">{{description}}</h4>
|
<h4 class="text-dark mb-1">{{description}}</h4>
|
||||||
<h6 class="text-dark mb-1">Author: {{author}}<br>Version: {{version}}</h6>{{functions|safe}}
|
<h6 class="text-dark mb-1">Author: {{author}}<br>Version: {{version}}<br>Source: {{source}}</h6>{{functions|safe}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<footer class="sticky-footer" style="background: var(--bs-primary-text-emphasis);">
|
<footer class="sticky-footer" style="background: var(--bs-primary-text-emphasis);">
|
||||||
|
|||||||
@@ -35,7 +35,6 @@
|
|||||||
<li class="nav-item"><a class="nav-link" href="/receive"><i class="material-icons">call_received</i><span>Receive</span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/receive"><i class="material-icons">call_received</i><span>Receive</span></a></li>
|
||||||
<li class="nav-item"><a class="nav-link" href="/plugins"><i class="material-icons">code</i><span>Plugins</span></a><a class="nav-link" href="/settings"><i class="material-icons">settings</i><span>Settings</span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/plugins"><i class="material-icons">code</i><span>Plugins</span></a><a class="nav-link" href="/settings"><i class="material-icons">settings</i><span>Settings</span></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="text-center d-none d-md-inline"><button class="btn rounded-circle border-0" id="sidebarToggle" type="button"></button></div>
|
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
||||||
|
|||||||
@@ -35,7 +35,6 @@
|
|||||||
<li class="nav-item"><a class="nav-link" href="/receive"><i class="material-icons">call_received</i><span>Receive</span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/receive"><i class="material-icons">call_received</i><span>Receive</span></a></li>
|
||||||
<li class="nav-item"><a class="nav-link" href="/plugins"><i class="material-icons">code</i><span>Plugins</span></a><a class="nav-link" href="/settings"><i class="material-icons">settings</i><span>Settings</span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/plugins"><i class="material-icons">code</i><span>Plugins</span></a><a class="nav-link" href="/settings"><i class="material-icons">settings</i><span>Settings</span></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="text-center d-none d-md-inline"><button class="btn rounded-circle border-0" id="sidebarToggle" type="button"></button></div>
|
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
||||||
|
|||||||
@@ -35,7 +35,6 @@
|
|||||||
<li class="nav-item"><a class="nav-link" href="/receive"><i class="material-icons">call_received</i><span>Receive</span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/receive"><i class="material-icons">call_received</i><span>Receive</span></a></li>
|
||||||
<li class="nav-item"><a class="nav-link" href="/plugins"><i class="material-icons">code</i><span>Plugins</span></a><a class="nav-link" href="/settings"><i class="material-icons">settings</i><span>Settings</span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/plugins"><i class="material-icons">code</i><span>Plugins</span></a><a class="nav-link" href="/settings"><i class="material-icons">settings</i><span>Settings</span></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="text-center d-none d-md-inline"><button class="btn rounded-circle border-0" id="sidebarToggle" type="button"></button></div>
|
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
||||||
|
|||||||
@@ -35,7 +35,6 @@
|
|||||||
<li class="nav-item"><a class="nav-link" href="/receive"><i class="material-icons">call_received</i><span>Receive</span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/receive"><i class="material-icons">call_received</i><span>Receive</span></a></li>
|
||||||
<li class="nav-item"><a class="nav-link" href="/plugins"><i class="material-icons">code</i><span>Plugins</span></a><a class="nav-link" href="/settings"><i class="material-icons">settings</i><span>Settings</span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/plugins"><i class="material-icons">code</i><span>Plugins</span></a><a class="nav-link" href="/settings"><i class="material-icons">settings</i><span>Settings</span></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="text-center d-none d-md-inline"><button class="btn rounded-circle border-0" id="sidebarToggle" type="button"></button></div>
|
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
||||||
|
|||||||
@@ -36,7 +36,6 @@
|
|||||||
<li class="nav-item"><a class="nav-link" href="/receive"><i class="material-icons">call_received</i><span>Receive</span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/receive"><i class="material-icons">call_received</i><span>Receive</span></a></li>
|
||||||
<li class="nav-item"><a class="nav-link" href="/plugins"><i class="material-icons">code</i><span>Plugins</span></a><a class="nav-link" href="/settings"><i class="material-icons">settings</i><span>Settings</span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/plugins"><i class="material-icons">code</i><span>Plugins</span></a><a class="nav-link" href="/settings"><i class="material-icons">settings</i><span>Settings</span></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="text-center d-none d-md-inline"><button class="btn rounded-circle border-0" id="sidebarToggle" type="button"></button></div>
|
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
||||||
|
|||||||
@@ -35,7 +35,6 @@
|
|||||||
<li class="nav-item"><a class="nav-link" href="/receive"><i class="material-icons">call_received</i><span>Receive</span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/receive"><i class="material-icons">call_received</i><span>Receive</span></a></li>
|
||||||
<li class="nav-item"><a class="nav-link" href="/plugins"><i class="material-icons">code</i><span>Plugins</span></a><a class="nav-link" href="/settings"><i class="material-icons">settings</i><span>Settings</span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/plugins"><i class="material-icons">code</i><span>Plugins</span></a><a class="nav-link" href="/settings"><i class="material-icons">settings</i><span>Settings</span></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="text-center d-none d-md-inline"><button class="btn rounded-circle border-0" id="sidebarToggle" type="button"></button></div>
|
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
||||||
|
|||||||
@@ -35,7 +35,6 @@
|
|||||||
<li class="nav-item"><a class="nav-link" href="/receive"><i class="material-icons">call_received</i><span>Receive</span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/receive"><i class="material-icons">call_received</i><span>Receive</span></a></li>
|
||||||
<li class="nav-item"><a class="nav-link" href="/plugins"><i class="material-icons">code</i><span>Plugins</span></a><a class="nav-link" href="/settings"><i class="material-icons">settings</i><span>Settings</span></a></li>
|
<li class="nav-item"><a class="nav-link" href="/plugins"><i class="material-icons">code</i><span>Plugins</span></a><a class="nav-link" href="/settings"><i class="material-icons">settings</i><span>Settings</span></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="text-center d-none d-md-inline"><button class="btn rounded-circle border-0" id="sidebarToggle" type="button"></button></div>
|
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
<div class="d-flex flex-column" id="content-wrapper" style="background: var(--bs-primary);">
|
||||||
|
|||||||
Reference in New Issue
Block a user