diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b9a723e --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ + +.env + +__pycache__/ + +used.json + +payments.json diff --git a/Dockerfile b/Dockerfile index 703a041..25c32e3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,7 +9,7 @@ RUN --mount=type=cache,target=/root/.cache/pip \ COPY . /app # Add mount point for data volume -# VOLUME /data +VOLUME /mnt ENTRYPOINT ["python3"] CMD ["main.py"] diff --git a/payments.py b/payments.py new file mode 100644 index 0000000..0689d85 --- /dev/null +++ b/payments.py @@ -0,0 +1,148 @@ +import json +import random +import os +import dotenv +import requests + +dotenv.load_dotenv() + +payments = { +} + +path = "/mnt/" +if os.getenv('LOCAL') == "true": + path = "./" + + +if os.path.exists(path+'payments.json'): + with open('payments.json', 'r') as f: + payments = json.load(f) +else: + with open(path+'payments.json', 'w') as f: + json.dump(payments, f, indent=4) + +used = [] +if os.path.exists('used.json'): + with open('used.json', 'r') as f: + used = json.load(f) +else: + with open('used.json', 'w') as f: + json.dump(used, f, indent=4) + +HNSaddress = os.getenv('ADDRESS') + +names = { + "pack1": "Pack of 5 Pins: Includes 2x Gold w Silver highlights", + "pack2": "Pack of 5 Pins: Includes 2x Silver w Gold highlights", +} + + +def generate_payment(name,email,mobile,address,country,cart,hns): + # Generate a payment object + payment_id = generate_payment_id() + if payment_id == "ERROR": + return False + + finalPrice = str(hns) + '.' + str(payment_id) + + # Fix the cart names + for item in cart: + if item['name'] in names: + item['name'] = names[item['name']] + + payment = { + "name": name, + "email": email, + "mobile": mobile, + "address": address, + "country": country, + "hns": hns, + "ID": finalPrice, + "cart": cart, + "status": "Pending" + } + finalPriceDolarydoo = float(finalPrice) * 1000000 + payments[finalPriceDolarydoo] = payment + # Save payments to file + with open('payments.json', 'w') as f: + json.dump(payments, f, indent=4) + + + payment['HNSaddress'] = HNSaddress + + return payment + + +def check_payments(): + # Get all txs + data = requests.get(f"https://api.niami.io/address/{HNSaddress}") + if data.status_code != 200: + return False + data = data.json() + if data['success'] == False: + return False + + data = data['data'] + + for tx in data: + for output in tx['outputs']: + if output['address'] == HNSaddress: + # Convert to HNS + outputValue = int(output['value']) + outputValue = str(float(outputValue)) + + if outputValue in payments: + # Payment found + payment = payments[outputValue] + if payment['status'] == "Pending": + if not finalise_payment(payment): + return False + payment['status'] = "Paid" + with open('payments.json', 'w') as f: + json.dump(payments, f, indent=4) + print("Payment finalised") + + + +def finalise_payment(payment): + # Send webhook + url = "https://n8n.woodburn.au/webhook/ea025b12-d002-4f0b-80bb-b39e6452fa66" + data = payment + resp = requests.post(url, json=data) + if resp.status_code != 200: + print(resp.text) + return False + return True + + + + +def generate_payment_id(): + id = 1 + while True: + if id not in used: + used.append(id) + with open('used.json', 'w') as f: + json.dump(used, f, indent=4) + + # Return the id padded to 2 digits + return str(id).zfill(2) + id +=1 + if id > 75: + # Send a warning + requests.post("https://n8n.woodburn.au/webhook/15477afd-60d7-469e-a213-d3bd57234f75", json={"message": "Payment ID is over 75"}) + + if id > 99: + return "ERROR" + +if __name__ == '__main__': + for i in range(10): + generate_payment('Test', 'test@email.com', '123 Test St', [ + { + 'name': 'Test', + 'quantity': 1 + } + ], 10) + + print(json.dumps(payments, indent=4)) + print(check_payments()) \ No newline at end of file diff --git a/render.py b/render.py new file mode 100644 index 0000000..cd43830 --- /dev/null +++ b/render.py @@ -0,0 +1,147 @@ +import json +import datetime +import requests + +names = { + "pack1": "Pack of 5 Pins
Includes 2x Silver highlights", + "pack2": "Pack of 5 Pins
Includes 2x Gold highlights", +} + +images = { + "pack1": "pins/pack1.jpg", + "pack2": "pins/pack2.jpg", +} + +prices = { + "pack1": 45, + "pack2": 45, +} + +exchange = { + 'rate': 0, + 'timestamp': 0 +} + + +def cart(cert): + html = "" + for item in cert: + quantity = item['quantity'] + path = item['name'] + if path in names: + name = names[path] + image = images[path] + price = prices[path] + else: + name = path + image = "pins/pack1.jpg" + price = 45 + + hns = usdToHNS(price) + + html += "
" + html += "
" + html += "
" + html += f"
" + html += "
" + html += f"" + html += "
" + html += f"
" + html += f"
US${price}
{hns} HNS
" + html += "
" + html += script(path) + html += "
" + + return html + +def cart_total(cert): + html = "" + for item in cert: + quantity = item['quantity'] + if int(quantity) <= 0: + continue + + path = item['name'] + if path in names: + name = names[path] + image = images[path] + price = prices[path] + else: + name = path + image = "tech/image2.jpg" + price = 45 + + hns = usdToHNS(price, True) + hns = hns * int(quantity) + hns = "{:,}".format(hns) + + + html += f"
{hns} HNS" + html += f"

{name}

" + html += f"

{quantity} Packs

" + html += "
" + + return html + +def script(path): + html = f""" + + """ + return html + +def usdToHNS(usd, returnInt=False): + global exchange + if exchange['timestamp'] < datetime.datetime.now().timestamp() - 3600: + response = requests.get('https://api.coingecko.com/api/v3/simple/price?ids=handshake&vs_currencies=usd') + exchange['rate'] = response.json()['handshake']['usd'] + exchange['timestamp'] = datetime.datetime.now().timestamp() + + hns = usd / exchange['rate'] + + hns = int(hns / 5) * 5 + if returnInt: + return int(hns) + hns = "{:,}".format(hns) + return hns + + +def total_usd(cert): + total = 0 + for item in cert: + path = item['name'] + if path in prices: + total += prices[path] * int(item['quantity']) + else: + total += 45 * int(item['quantity']) + return total + +def total_hns(cert, returnInt=False): + total = 0 + for item in cert: + path = item['name'] + if path in prices: + total += usdToHNS(prices[path],True) * int(item['quantity']) + else: + total += usdToHNS(45,True) * int(item['quantity']) + + if returnInt: + return int(total) + total ="{:,}".format(total) + return total \ No newline at end of file diff --git a/server.py b/server.py index 35a90f4..6a0ab67 100644 --- a/server.py +++ b/server.py @@ -3,10 +3,20 @@ import os import dotenv import requests import datetime +import json +import render +import payments +import threading app = Flask(__name__) dotenv.load_dotenv() +# Exchange cache +exchange = { + 'timestamp': 0, + 'rate': 0 +} + #Assets routes @app.route('/assets/') @@ -45,7 +55,218 @@ def wallet(path): def email(): return redirect('mailto:hns@hns.au') +@app.route('/pins') +def pins(): + global exchange + year = datetime.datetime.now().year + # Get current exchange rate if not in cache + if exchange['timestamp'] < datetime.datetime.now().timestamp() - 3600: + response = requests.get('https://api.coingecko.com/api/v3/simple/price?ids=handshake&vs_currencies=usd') + exchange['rate'] = response.json()['handshake']['usd'] + exchange['timestamp'] = datetime.datetime.now().timestamp() + + hns_45 = 45 / exchange['rate'] + hns_30 = 30 / exchange['rate'] + + # Round to the nearest 5 HNS and add commas + hns_45 = int(hns_45 / 5) * 5 + hns_30 = int(hns_30 / 5) * 5 + + hns_45 = "{:,}".format(hns_45) + hns_30 = "{:,}".format(hns_30) + + + return render_template('pins.html', year=year, hns_45=hns_45, hns_30=hns_30) + +@app.route('/pins/') +def pins_redirect(path): + global exchange + + if not os.path.isfile('templates/pins/'+path + ".html"): + return render_template('404.html'), 404 + + year = datetime.datetime.now().year + # Get current exchange rate if not in cache + if exchange['timestamp'] < datetime.datetime.now().timestamp() - 3600: + response = requests.get('https://api.coingecko.com/api/v3/simple/price?ids=handshake&vs_currencies=usd') + exchange['rate'] = response.json()['handshake']['usd'] + exchange['timestamp'] = datetime.datetime.now().timestamp() + + hns_45 = 45 / exchange['rate'] + hns_30 = 30 / exchange['rate'] + + # Round to the nearest 5 HNS and add commas + hns_45 = int(hns_45 / 5) * 5 + hns_30 = int(hns_30 / 5) * 5 + + hns_45 = "{:,}".format(hns_45) + hns_30 = "{:,}".format(hns_30) + return render_template('pins/'+path + ".html", year=year, hns_45=hns_45, hns_30=hns_30) + +@app.route('/pins/order/') +def pins_order(path): + if not os.path.isfile('templates/pins/'+path + ".html"): + return render_template('404.html'), 404 + + # Get cookies + cookies = request.cookies + if 'cart' in cookies: + cart = cookies['cart'] + else: + cart = '[]' + + cart = json.loads(cart) + item = { + 'name': path, + 'quantity': 1 + } + for i in range(len(cart)): + if cart[i]['name'] == path: + cart[i]['quantity'] += 1 + item = None + break + + if item: + cart.append(item) + cart = json.dumps(cart) + + response = make_response(redirect('/cart')) + response.set_cookie('cart', cart) + return response + +@app.route('/pins/update/', methods=['POST']) +def pins_update(path): + # Get cookies + cookies = request.cookies + if 'cart' in cookies: + cart = cookies['cart'] + else: + cart = '[]' + + cart = json.loads(cart) + data = request.json + for i in range(len(cart)): + if cart[i]['name'] == path: + cart[i]['quantity'] = data['quantity'] + break + + + # Remove any item with less than 1 quantity + cart = [item for item in cart if int(item['quantity']) > 0] + cart = json.dumps(cart) + + response = make_response(jsonify({'status': 'ok'})) + response.set_cookie('cart', cart) + return response + +@app.route('/cart') +def cart(): + year = datetime.datetime.now().year + # Get cookies + cookies = request.cookies + if 'cart' in cookies: + cart = cookies['cart'] + else: + cart = '[]' + + cart = json.loads(cart) + cartHtml = render.cart(cart) + + total_usd = render.total_usd(cart) + total_hns = render.total_hns(cart) + + return render_template('cart.html', year=year, cart=cartHtml, total_usd=total_usd, total_hns=total_hns) + +@app.route('/payment') +def payment(): + year = datetime.datetime.now().year + # Get cookies + cookies = request.cookies + if 'cart' in cookies: + cart = cookies['cart'] + else: + cart = '[]' + + if cart == '[]': + return redirect('/cart') + + cart = json.loads(cart) + cartHtml = render.cart_total(cart) + + total_usd = render.total_usd(cart) + total_hns = render.total_hns(cart) + + return render_template('payment.html', year=year, cart=cartHtml, total_usd=total_usd, total_hns=total_hns) + +@app.route('/payment', methods=['POST']) +def payment_post(): + # Get cookies + cookies = request.cookies + if 'cart' in cookies: + cart = cookies['cart'] + else: + cart = '[]' + + if cart == '[]': + return redirect('/cart') + + cart = json.loads(cart) + total_usd = render.total_usd(cart) + total_hns = render.total_hns(cart) + + data = request.form + if 'email' in data: + email = data['email'] + else: + email = '' + if 'mobile' in data: + mobile = data['mobile'] + else: + mobile = '' + + if 'address' in data: + address = data['address'] + else: + address = '' + + if 'country' in data: + country = data['country'] + else: + country = '' + + if 'name' in data: + name = data['name'] + else: + name = '' + + cartHtml = render.cart_total(cart) + + + if email == '' or address == '' or name == '' or country == '' or mobile == '': + return render_template('payment.html', error='Please fill all fields', + email=email, address=address, name=name, mobile=mobile, country=country, + cart=cartHtml, total_usd=total_usd, total_hns=total_hns) + + + # All good, check out + payment = payments.generate_payment(name, email, mobile,address,country, cart, render.total_hns(cart, True)) + + if payment == False: + return render_template('payment.html', error='There was an error processing your payment', email=email, address=address, name=name, + cart=cartHtml, total_usd=total_usd, total_hns=total_hns) + + finalPrice = payment['ID'] + HNSaddress = payment['HNSaddress'] + qr = f"QR Code" + + # Center the QR code + qr = f"
{qr}
" + + responce = make_response(render_template('payment_info.html',cart=cartHtml, total_hns=finalPrice,address=HNSaddress, year=datetime.datetime.now().year, qr=qr)) + responce.set_cookie('cart', '[]') + + return responce # Main routes @app.route('/') @@ -71,5 +292,17 @@ def catch_all(path): def not_found(e): return render_template('404.html'), 404 + +def repeat_check_payments(): + # Run check_payments function + payments.check_payments() + # Schedule the function to run again after 10 seconds + threading.Timer(10, repeat_check_payments).start() + + + if __name__ == '__main__': + # Set timer for payments + + repeat_check_payments() app.run(debug=True, port=5000, host='0.0.0.0') \ No newline at end of file diff --git a/templates/about.html b/templates/about.html index ceee86f..812b8f7 100644 --- a/templates/about.html +++ b/templates/about.html @@ -58,6 +58,7 @@ + diff --git a/templates/assets/css/vanilla-zoom.min.css b/templates/assets/css/vanilla-zoom.min.css index 7110105..6607dfe 100644 --- a/templates/assets/css/vanilla-zoom.min.css +++ b/templates/assets/css/vanilla-zoom.min.css @@ -35,3 +35,7 @@ margin-bottom: 5px; } +.no-display { + text-decoration: none; +} + diff --git a/templates/assets/fonts/Simple-Line-Icons.eot b/templates/assets/fonts/Simple-Line-Icons.eot new file mode 100644 index 0000000..f0ca6e8 Binary files /dev/null and b/templates/assets/fonts/Simple-Line-Icons.eot differ diff --git a/templates/assets/fonts/Simple-Line-Icons.svg b/templates/assets/fonts/Simple-Line-Icons.svg new file mode 100644 index 0000000..e24c746 --- /dev/null +++ b/templates/assets/fonts/Simple-Line-Icons.svg @@ -0,0 +1,200 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/templates/assets/fonts/Simple-Line-Icons.ttf b/templates/assets/fonts/Simple-Line-Icons.ttf new file mode 100644 index 0000000..6ecb686 Binary files /dev/null and b/templates/assets/fonts/Simple-Line-Icons.ttf differ diff --git a/templates/assets/fonts/Simple-Line-Icons.woff b/templates/assets/fonts/Simple-Line-Icons.woff new file mode 100644 index 0000000..b17d694 Binary files /dev/null and b/templates/assets/fonts/Simple-Line-Icons.woff differ diff --git a/templates/assets/fonts/Simple-Line-Icons.woff2 b/templates/assets/fonts/Simple-Line-Icons.woff2 new file mode 100644 index 0000000..c49fccf Binary files /dev/null and b/templates/assets/fonts/Simple-Line-Icons.woff2 differ diff --git a/templates/assets/fonts/simple-line-icons.min.css b/templates/assets/fonts/simple-line-icons.min.css new file mode 100644 index 0000000..9044952 --- /dev/null +++ b/templates/assets/fonts/simple-line-icons.min.css @@ -0,0 +1 @@ +@font-face{font-family:simple-line-icons;src:url('../fonts/Simple-Line-Icons.eot?v=2.4.0');src:url('../fonts/Simple-Line-Icons.eot?v=2.4.0#iefix') format('embedded-opentype'),url('../fonts/Simple-Line-Icons.woff2?v=2.4.0') format('woff2'),url('../fonts/Simple-Line-Icons.ttf?v=2.4.0') format('truetype'),url('../fonts/Simple-Line-Icons.woff?v=2.4.0') format('woff'),url('../fonts/Simple-Line-Icons.svg?v=2.4.0#simple-line-icons') format('svg');font-weight:400;font-style:normal}.icon-action-redo,.icon-action-undo,.icon-anchor,.icon-arrow-down,.icon-arrow-down-circle,.icon-arrow-left,.icon-arrow-left-circle,.icon-arrow-right,.icon-arrow-right-circle,.icon-arrow-up,.icon-arrow-up-circle,.icon-badge,.icon-bag,.icon-ban,.icon-basket,.icon-basket-loaded,.icon-bell,.icon-book-open,.icon-briefcase,.icon-bubble,.icon-bubbles,.icon-bulb,.icon-calculator,.icon-calendar,.icon-call-end,.icon-call-in,.icon-call-out,.icon-camera,.icon-camrecorder,.icon-chart,.icon-check,.icon-chemistry,.icon-clock,.icon-close,.icon-cloud-download,.icon-cloud-upload,.icon-compass,.icon-control-end,.icon-control-forward,.icon-control-pause,.icon-control-play,.icon-control-rewind,.icon-control-start,.icon-credit-card,.icon-crop,.icon-cup,.icon-cursor,.icon-cursor-move,.icon-diamond,.icon-direction,.icon-directions,.icon-disc,.icon-dislike,.icon-doc,.icon-docs,.icon-drawer,.icon-drop,.icon-earphones,.icon-earphones-alt,.icon-emotsmile,.icon-energy,.icon-envelope,.icon-envelope-letter,.icon-envelope-open,.icon-equalizer,.icon-event,.icon-exclamation,.icon-eye,.icon-eyeglass,.icon-feed,.icon-film,.icon-fire,.icon-flag,.icon-folder,.icon-folder-alt,.icon-frame,.icon-game-controller,.icon-ghost,.icon-globe,.icon-globe-alt,.icon-graduation,.icon-graph,.icon-grid,.icon-handbag,.icon-heart,.icon-home,.icon-hourglass,.icon-info,.icon-key,.icon-layers,.icon-like,.icon-link,.icon-list,.icon-location-pin,.icon-lock,.icon-lock-open,.icon-login,.icon-logout,.icon-loop,.icon-magic-wand,.icon-magnet,.icon-magnifier,.icon-magnifier-add,.icon-magnifier-remove,.icon-map,.icon-menu,.icon-microphone,.icon-minus,.icon-mouse,.icon-music-tone,.icon-music-tone-alt,.icon-mustache,.icon-note,.icon-notebook,.icon-options,.icon-options-vertical,.icon-organization,.icon-paper-clip,.icon-paper-plane,.icon-paypal,.icon-pencil,.icon-people,.icon-phone,.icon-picture,.icon-pie-chart,.icon-pin,.icon-plane,.icon-playlist,.icon-plus,.icon-power,.icon-present,.icon-printer,.icon-puzzle,.icon-question,.icon-refresh,.icon-reload,.icon-rocket,.icon-screen-desktop,.icon-screen-smartphone,.icon-screen-tablet,.icon-settings,.icon-share,.icon-share-alt,.icon-shield,.icon-shuffle,.icon-size-actual,.icon-size-fullscreen,.icon-social-behance,.icon-social-dribbble,.icon-social-dropbox,.icon-social-facebook,.icon-social-foursqare,.icon-social-github,.icon-social-google,.icon-social-instagram,.icon-social-linkedin,.icon-social-pinterest,.icon-social-reddit,.icon-social-skype,.icon-social-soundcloud,.icon-social-spotify,.icon-social-steam,.icon-social-stumbleupon,.icon-social-tumblr,.icon-social-twitter,.icon-social-vkontakte,.icon-social-youtube,.icon-speech,.icon-speedometer,.icon-star,.icon-support,.icon-symbol-female,.icon-symbol-male,.icon-tag,.icon-target,.icon-trash,.icon-trophy,.icon-umbrella,.icon-user,.icon-user-female,.icon-user-follow,.icon-user-following,.icon-user-unfollow,.icon-vector,.icon-volume-1,.icon-volume-2,.icon-volume-off,.icon-wallet,.icon-wrench{font-family:simple-line-icons;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.icon-user:before{content:"\e005"}.icon-people:before{content:"\e001"}.icon-user-female:before{content:"\e000"}.icon-user-follow:before{content:"\e002"}.icon-user-following:before{content:"\e003"}.icon-user-unfollow:before{content:"\e004"}.icon-login:before{content:"\e066"}.icon-logout:before{content:"\e065"}.icon-emotsmile:before{content:"\e021"}.icon-phone:before{content:"\e600"}.icon-call-end:before{content:"\e048"}.icon-call-in:before{content:"\e047"}.icon-call-out:before{content:"\e046"}.icon-map:before{content:"\e033"}.icon-location-pin:before{content:"\e096"}.icon-direction:before{content:"\e042"}.icon-directions:before{content:"\e041"}.icon-compass:before{content:"\e045"}.icon-layers:before{content:"\e034"}.icon-menu:before{content:"\e601"}.icon-list:before{content:"\e067"}.icon-options-vertical:before{content:"\e602"}.icon-options:before{content:"\e603"}.icon-arrow-down:before{content:"\e604"}.icon-arrow-left:before{content:"\e605"}.icon-arrow-right:before{content:"\e606"}.icon-arrow-up:before{content:"\e607"}.icon-arrow-up-circle:before{content:"\e078"}.icon-arrow-left-circle:before{content:"\e07a"}.icon-arrow-right-circle:before{content:"\e079"}.icon-arrow-down-circle:before{content:"\e07b"}.icon-check:before{content:"\e080"}.icon-clock:before{content:"\e081"}.icon-plus:before{content:"\e095"}.icon-minus:before{content:"\e615"}.icon-close:before{content:"\e082"}.icon-event:before{content:"\e619"}.icon-exclamation:before{content:"\e617"}.icon-organization:before{content:"\e616"}.icon-trophy:before{content:"\e006"}.icon-screen-smartphone:before{content:"\e010"}.icon-screen-desktop:before{content:"\e011"}.icon-plane:before{content:"\e012"}.icon-notebook:before{content:"\e013"}.icon-mustache:before{content:"\e014"}.icon-mouse:before{content:"\e015"}.icon-magnet:before{content:"\e016"}.icon-energy:before{content:"\e020"}.icon-disc:before{content:"\e022"}.icon-cursor:before{content:"\e06e"}.icon-cursor-move:before{content:"\e023"}.icon-crop:before{content:"\e024"}.icon-chemistry:before{content:"\e026"}.icon-speedometer:before{content:"\e007"}.icon-shield:before{content:"\e00e"}.icon-screen-tablet:before{content:"\e00f"}.icon-magic-wand:before{content:"\e017"}.icon-hourglass:before{content:"\e018"}.icon-graduation:before{content:"\e019"}.icon-ghost:before{content:"\e01a"}.icon-game-controller:before{content:"\e01b"}.icon-fire:before{content:"\e01c"}.icon-eyeglass:before{content:"\e01d"}.icon-envelope-open:before{content:"\e01e"}.icon-envelope-letter:before{content:"\e01f"}.icon-bell:before{content:"\e027"}.icon-badge:before{content:"\e028"}.icon-anchor:before{content:"\e029"}.icon-wallet:before{content:"\e02a"}.icon-vector:before{content:"\e02b"}.icon-speech:before{content:"\e02c"}.icon-puzzle:before{content:"\e02d"}.icon-printer:before{content:"\e02e"}.icon-present:before{content:"\e02f"}.icon-playlist:before{content:"\e030"}.icon-pin:before{content:"\e031"}.icon-picture:before{content:"\e032"}.icon-handbag:before{content:"\e035"}.icon-globe-alt:before{content:"\e036"}.icon-globe:before{content:"\e037"}.icon-folder-alt:before{content:"\e039"}.icon-folder:before{content:"\e089"}.icon-film:before{content:"\e03a"}.icon-feed:before{content:"\e03b"}.icon-drop:before{content:"\e03e"}.icon-drawer:before{content:"\e03f"}.icon-docs:before{content:"\e040"}.icon-doc:before{content:"\e085"}.icon-diamond:before{content:"\e043"}.icon-cup:before{content:"\e044"}.icon-calculator:before{content:"\e049"}.icon-bubbles:before{content:"\e04a"}.icon-briefcase:before{content:"\e04b"}.icon-book-open:before{content:"\e04c"}.icon-basket-loaded:before{content:"\e04d"}.icon-basket:before{content:"\e04e"}.icon-bag:before{content:"\e04f"}.icon-action-undo:before{content:"\e050"}.icon-action-redo:before{content:"\e051"}.icon-wrench:before{content:"\e052"}.icon-umbrella:before{content:"\e053"}.icon-trash:before{content:"\e054"}.icon-tag:before{content:"\e055"}.icon-support:before{content:"\e056"}.icon-frame:before{content:"\e038"}.icon-size-fullscreen:before{content:"\e057"}.icon-size-actual:before{content:"\e058"}.icon-shuffle:before{content:"\e059"}.icon-share-alt:before{content:"\e05a"}.icon-share:before{content:"\e05b"}.icon-rocket:before{content:"\e05c"}.icon-question:before{content:"\e05d"}.icon-pie-chart:before{content:"\e05e"}.icon-pencil:before{content:"\e05f"}.icon-note:before{content:"\e060"}.icon-loop:before{content:"\e064"}.icon-home:before{content:"\e069"}.icon-grid:before{content:"\e06a"}.icon-graph:before{content:"\e06b"}.icon-microphone:before{content:"\e063"}.icon-music-tone-alt:before{content:"\e061"}.icon-music-tone:before{content:"\e062"}.icon-earphones-alt:before{content:"\e03c"}.icon-earphones:before{content:"\e03d"}.icon-equalizer:before{content:"\e06c"}.icon-like:before{content:"\e068"}.icon-dislike:before{content:"\e06d"}.icon-control-start:before{content:"\e06f"}.icon-control-rewind:before{content:"\e070"}.icon-control-play:before{content:"\e071"}.icon-control-pause:before{content:"\e072"}.icon-control-forward:before{content:"\e073"}.icon-control-end:before{content:"\e074"}.icon-volume-1:before{content:"\e09f"}.icon-volume-2:before{content:"\e0a0"}.icon-volume-off:before{content:"\e0a1"}.icon-calendar:before{content:"\e075"}.icon-bulb:before{content:"\e076"}.icon-chart:before{content:"\e077"}.icon-ban:before{content:"\e07c"}.icon-bubble:before{content:"\e07d"}.icon-camrecorder:before{content:"\e07e"}.icon-camera:before{content:"\e07f"}.icon-cloud-download:before{content:"\e083"}.icon-cloud-upload:before{content:"\e084"}.icon-envelope:before{content:"\e086"}.icon-eye:before{content:"\e087"}.icon-flag:before{content:"\e088"}.icon-heart:before{content:"\e08a"}.icon-info:before{content:"\e08b"}.icon-key:before{content:"\e08c"}.icon-link:before{content:"\e08d"}.icon-lock:before{content:"\e08e"}.icon-lock-open:before{content:"\e08f"}.icon-magnifier:before{content:"\e090"}.icon-magnifier-add:before{content:"\e091"}.icon-magnifier-remove:before{content:"\e092"}.icon-paper-clip:before{content:"\e093"}.icon-paper-plane:before{content:"\e094"}.icon-power:before{content:"\e097"}.icon-refresh:before{content:"\e098"}.icon-reload:before{content:"\e099"}.icon-settings:before{content:"\e09a"}.icon-star:before{content:"\e09b"}.icon-symbol-female:before{content:"\e09c"}.icon-symbol-male:before{content:"\e09d"}.icon-target:before{content:"\e09e"}.icon-credit-card:before{content:"\e025"}.icon-paypal:before{content:"\e608"}.icon-social-tumblr:before{content:"\e00a"}.icon-social-twitter:before{content:"\e009"}.icon-social-facebook:before{content:"\e00b"}.icon-social-instagram:before{content:"\e609"}.icon-social-linkedin:before{content:"\e60a"}.icon-social-pinterest:before{content:"\e60b"}.icon-social-github:before{content:"\e60c"}.icon-social-google:before{content:"\e60d"}.icon-social-reddit:before{content:"\e60e"}.icon-social-skype:before{content:"\e60f"}.icon-social-dribbble:before{content:"\e00d"}.icon-social-behance:before{content:"\e610"}.icon-social-foursqare:before{content:"\e611"}.icon-social-soundcloud:before{content:"\e612"}.icon-social-spotify:before{content:"\e613"}.icon-social-stumbleupon:before{content:"\e614"}.icon-social-youtube:before{content:"\e008"}.icon-social-dropbox:before{content:"\e00c"}.icon-social-vkontakte:before{content:"\e618"}.icon-social-steam:before{content:"\e620"} \ No newline at end of file diff --git a/templates/assets/img/pins/pack1.jpg b/templates/assets/img/pins/pack1.jpg new file mode 100644 index 0000000..7e1d1ee Binary files /dev/null and b/templates/assets/img/pins/pack1.jpg differ diff --git a/templates/assets/img/pins/pack2.jpg b/templates/assets/img/pins/pack2.jpg new file mode 100644 index 0000000..7e1d1ee Binary files /dev/null and b/templates/assets/img/pins/pack2.jpg differ diff --git a/templates/assets/img/pins/pins_bulk.jpg b/templates/assets/img/pins/pins_bulk.jpg new file mode 100644 index 0000000..7e1d1ee Binary files /dev/null and b/templates/assets/img/pins/pins_bulk.jpg differ diff --git a/templates/assets/img/pins/pins_single.jpg b/templates/assets/img/pins/pins_single.jpg new file mode 100644 index 0000000..aed6ecf Binary files /dev/null and b/templates/assets/img/pins/pins_single.jpg differ diff --git a/templates/assets/img/scenery/image3.jpg b/templates/assets/img/scenery/image3.jpg new file mode 100644 index 0000000..28b9e04 Binary files /dev/null and b/templates/assets/img/scenery/image3.jpg differ diff --git a/templates/assets/img/star-empty.svg b/templates/assets/img/star-empty.svg new file mode 100644 index 0000000..3f7e74f --- /dev/null +++ b/templates/assets/img/star-empty.svg @@ -0,0 +1,5 @@ + + +star-o + + diff --git a/templates/assets/img/star-half-empty.svg b/templates/assets/img/star-half-empty.svg new file mode 100644 index 0000000..b3af5fb --- /dev/null +++ b/templates/assets/img/star-half-empty.svg @@ -0,0 +1,5 @@ + + +star-half-empty + + diff --git a/templates/assets/img/star.svg b/templates/assets/img/star.svg new file mode 100644 index 0000000..2ca58a1 --- /dev/null +++ b/templates/assets/img/star.svg @@ -0,0 +1,5 @@ + + +star + + diff --git a/templates/assets/img/tech/image1.jpg b/templates/assets/img/tech/image1.jpg new file mode 100644 index 0000000..ce35c8b Binary files /dev/null and b/templates/assets/img/tech/image1.jpg differ diff --git a/templates/assets/img/tech/image2.jpg b/templates/assets/img/tech/image2.jpg new file mode 100644 index 0000000..273eaa6 Binary files /dev/null and b/templates/assets/img/tech/image2.jpg differ diff --git a/templates/assets/img/tech/image3.png b/templates/assets/img/tech/image3.png new file mode 100644 index 0000000..3926937 Binary files /dev/null and b/templates/assets/img/tech/image3.png differ diff --git a/templates/blog.html b/templates/blog.html index 2f64256..dd9c17d 100644 --- a/templates/blog.html +++ b/templates/blog.html @@ -56,6 +56,7 @@ + @@ -69,6 +70,16 @@

Latest Blog posts from HNSAU

+
+
+
+
+

Pins is now on HNSAU

+
Feb 12, 2024 by Erwin.Groen/
+

HNS lapel pins are now available to buy directly from HNSAU using HNS. Available in 2 different pack options.

Read More +
+
+
diff --git a/templates/blog/happening.html b/templates/blog/happening.html index 66e0b61..17a99e9 100644 --- a/templates/blog/happening.html +++ b/templates/blog/happening.html @@ -56,6 +56,7 @@ +
diff --git a/templates/blog/pins.html b/templates/blog/pins.html new file mode 100644 index 0000000..4bd8949 --- /dev/null +++ b/templates/blog/pins.html @@ -0,0 +1,121 @@ + + + + + + + Blog Post - HNSAU + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+

Pins is now on HNSAU

+ +

We are thrilled to announce that HNS Lapel Pins are now available for purchase directly from HNSAU using HNS! These high-quality pins are designed to showcase the iconic HNS logo, making them the perfect accessory for anyone passionate about the future of the decentralized web.

Don't miss your chance to own a piece of internet history and support the decentralized web movement. Click the Pins link on the HNSAU website to order your HNS Lapel Pins today, and join us in building a more secure and decentralized internet for generations to come.

+
+
+
+

There are 2 options for pins. Both comes with 1 of each of the original colours (gold, silver and bronze).

The first option adds 2 gold with silver highlight pins.

The second option adds 2 silver with gold highlight pins.

Each pack has 5 pins and includes shipping worldwide for only US$45

+
+
+
A generic square placeholder image with rounded corners in a figure. +
Dual Plated Pins
+
+
+
+
+
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/templates/cart.html b/templates/cart.html new file mode 100644 index 0000000..783c167 --- /dev/null +++ b/templates/cart.html @@ -0,0 +1,120 @@ + + + + + + + Cart - HNSAU + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Shopping Cart

+

Please note that all payments are to be paid in HNS

+
+
+
+
+
{{cart|safe}}
+
+
+
+

Summary

+

Total USDUS${{total_usd}}

+

Total{{total_hns}} HNS

Checkout +
+
+
+
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/templates/contact.html b/templates/contact.html index 12162cb..c79d3fe 100644 --- a/templates/contact.html +++ b/templates/contact.html @@ -57,6 +57,7 @@ +
diff --git a/templates/domains.html b/templates/domains.html index 5f8ea87..e802fcc 100644 --- a/templates/domains.html +++ b/templates/domains.html @@ -56,6 +56,7 @@ +
diff --git a/templates/faq.html b/templates/faq.html index 7416b63..42399da 100644 --- a/templates/faq.html +++ b/templates/faq.html @@ -56,6 +56,7 @@ + diff --git a/templates/index.html b/templates/index.html index 98f72a8..c9f66a4 100644 --- a/templates/index.html +++ b/templates/index.html @@ -65,6 +65,7 @@ + diff --git a/templates/links.html b/templates/links.html index 01d9f21..53f2370 100644 --- a/templates/links.html +++ b/templates/links.html @@ -56,6 +56,7 @@ + @@ -132,15 +133,6 @@ -
-
-
-

Lapel Pins

-

Represent Handshake with a lapel pin.
Custom made in Australia.

- -
-
-
diff --git a/templates/payment.html b/templates/payment.html new file mode 100644 index 0000000..77eec91 --- /dev/null +++ b/templates/payment.html @@ -0,0 +1,136 @@ + + + + + + + Payment - HNSAU + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Payment

+

All payments are to be made in HNS

+
+
+
+

Checkout

{{cart|safe}} +
Total{{total_hns}} HNS
+
+
+

Postage Details

+

{{error}}

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/templates/payment_info.html b/templates/payment_info.html new file mode 100644 index 0000000..c8e76d5 --- /dev/null +++ b/templates/payment_info.html @@ -0,0 +1,120 @@ + + + + + + + Payment - HNSAU + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Payment

+

All payments are to be made in HNS

+
+
+
+

Checkout

{{cart|safe}} +
Total{{total_hns}} HNS
Total includes up to 1 HNS fee to identify your payment when it arrives +
If you are withdrawing from NB you should add 1 HNS extra in addition for NB processing fees
+
+
+

Payment info

+
Send {{total_hns}} HNS to {{address}} to finalize sale.
{{qr|safe}} +
+
+
You can leave this page once you have recorded the information or sent the payment
+
+
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/templates/pins.html b/templates/pins.html new file mode 100644 index 0000000..a8cada2 --- /dev/null +++ b/templates/pins.html @@ -0,0 +1,134 @@ + + + + + + + Pins - HNSAU + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Pins

+

Show that you support Handshake with a HNS lapel pin. Created to our high stands with multiple colours to choose from.
Free shipping worldwide

+
+
+
+
+
+
+ +
+
+

US$45

+

{{hns_45}} HNS

+
+
+
+
+
+
+
+ +
+
+

US$45

+

{{hns_45}} HNS

+
+
+
+
+
+
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/templates/pins/pack1.html b/templates/pins/pack1.html new file mode 100644 index 0000000..258274b --- /dev/null +++ b/templates/pins/pack1.html @@ -0,0 +1,191 @@ + + + + + + + Pins - HNSAU + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Pins

+

Show that you support Handshake with a HNS lapel pin. Created to our high stands with multiple colours to choose from.
Free shipping worldwide

+
+
+
+
+
+ +
+
+
+

Pack of 5 Pins
Includes 2x Silver highlights

+
+

US$45
{{hns_45}} HNS

+
Add to Cart +
+

Grab your Handshake pins with this pack of 5 pins. This pack includes:
1x Gold, Silver & Bronze Pins
2x Gold Pins with Silver Highlights

+
+
+
+
+
+
+
+ +
+
+

Cast with custom molds in high purity metal to ensure a premium pin.

+
+
+
+
+
+

Gold with Silver Highlights

+

This pack includes 2 dual plated pins. They are gold pins with silver highlights.

+
+
+
+
+

Includes the original colours

+

This pack includes each of the original 3 colours.
1 of each of the Gold, Silver and Bronze pins.

+
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + +
Gold Pins with Silver Highlights2x
Silver Pins with Gold Highlights0x
Gold Pins1x
Silver Pins1x
Bronze Pins1x
+
+
+
+
+
+
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/templates/pins/pack2.html b/templates/pins/pack2.html new file mode 100644 index 0000000..7690b38 --- /dev/null +++ b/templates/pins/pack2.html @@ -0,0 +1,191 @@ + + + + + + + Pins - HNSAU + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Pins

+

Show that you support Handshake with a HNS lapel pin. Created to our high stands with multiple colours to choose from.
Free shipping worldwide

+
+
+
+
+
+ +
+
+
+

Pack of 5 Pins
Includes 2x Gold highlights

+
+

US$45
{{hns_45}} HNS

+
Add to Cart +
+

Grab your Handshake pins with this pack of 5 pins. This pack includes:
1x Gold, Silver & Bronze Pins
2x Silver Pins with Gold Highlights

+
+
+
+
+
+
+
+ +
+
+

Cast with custom molds in high purity metal to ensure a premium pin.

+
+
+
+
+
+

Silver with Gold Highlights

+

This pack includes 2 dual plated pins. They are silver pins with gold highlights.

+
+
+
+
+

Includes the original colours

+

This pack includes each of the original 3 colours.
1 of each of the Gold, Silver and Bronze pins.

+
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + +
Gold Pins with Silver Highlights0x
Silver Pins with Gold Highlights2x
Gold Pins1x
Silver Pins1x
Bronze Pins1x
+
+
+
+
+
+
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/templates/pins/pack3.html b/templates/pins/pack3.html new file mode 100644 index 0000000..acd8846 --- /dev/null +++ b/templates/pins/pack3.html @@ -0,0 +1,191 @@ + + + + + + + Pins - HNSAU + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Pins

+

Show that you support Handshake with a HNS lapel pin. Created to our high stands with multiple colours to choose from.
Free shipping worldwide

+
+
+
+
+
+ +
+
+
+

Pack of 5 Pins
Includes 2x Silver highlights

+
+

US$45
{{hns_45}} HNS

+
Add to Cart +
+

Grab your Handshake pins with this pack of 5 pins. This pack includes:
1x Gold, Silver & Bronze Pins
2x Gold Pins with Silver Highlights

+
+
+
+
+
+
+
+ +
+
+

Cast with custom molds in high purity metal to ensure a premium pin.

+
+
+
+
+
+

Lorem Ipsum

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc quam urna, dignissim nec auctor in, mattis vitae leo. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

+
+
+
+
+

Lorem Ipsum

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc quam urna, dignissim nec auctor in, mattis vitae leo. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

+
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + +
Gold Pins with Silver Highlights1x
Silver Pins with Gold Highlights0x
Gold Pins1x
Silver Pins1x
Bronze Pins1x
+
+
+
+
+
+
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/templates/sitemap.xml b/templates/sitemap.xml index 8901669..8c43408 100644 --- a/templates/sitemap.xml +++ b/templates/sitemap.xml @@ -3,6 +3,15 @@ https://hns.au/blog/happening + + https://hns.au/blog/pins + + + https://hns.au/pins/pack1 + + + https://hns.au/pins/pack2 + https://hns.au/404 @@ -12,6 +21,9 @@ https://hns.au/blog + + https://hns.au/cart + https://hns.au/contact @@ -27,6 +39,15 @@ https://hns.au/links + + https://hns.au/payment + + + https://hns.au/payment_info + + + https://hns.au/pins + https://hns.au/uv diff --git a/templates/uv.html b/templates/uv.html index a1e0e2d..60aed77 100644 --- a/templates/uv.html +++ b/templates/uv.html @@ -56,6 +56,7 @@ +