From eec66b13ca335c6738b19a45697ea1b3039f2f44 Mon Sep 17 00:00:00 2001 From: Nathan Woodburn Date: Thu, 18 Jul 2024 14:30:12 +1000 Subject: [PATCH] feat: Add crypto address verifications --- .well-known/wallets/.BTC.proof | 6 ++++++ .well-known/wallets/.ETH.proof | 6 ++++++ .well-known/wallets/.SOL.proof | 13 +++++++++++++ .well-known/wallets/BTC | 2 +- server.py | 18 +++++++++++++++--- templates/assets/img/proof.png | Bin 0 -> 19470 bytes 6 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 .well-known/wallets/.BTC.proof create mode 100644 .well-known/wallets/.ETH.proof create mode 100644 .well-known/wallets/.SOL.proof create mode 100644 templates/assets/img/proof.png diff --git a/.well-known/wallets/.BTC.proof b/.well-known/wallets/.BTC.proof new file mode 100644 index 0000000..a29568c --- /dev/null +++ b/.well-known/wallets/.BTC.proof @@ -0,0 +1,6 @@ +I hereby confirm that I am the owner of the Bitcoin address bc1q60qy4s6gd7se8z6nc4wu49g4u5y8k2epd3djzc. +Nathan.Woodburn/ +-------------------- +H3oLoxLyax3gW6KkGfJiarseaktWWydyfS2TZ1zGoDlkIoMG/nIlNWNC5xc/uHCdPs+CIJgxNRq0GQI91qkalpg= +-------------------- +You can verify this signature by pasting it into a signature verification tool such as https://www.verifybitcoinmessage.com/. \ No newline at end of file diff --git a/.well-known/wallets/.ETH.proof b/.well-known/wallets/.ETH.proof new file mode 100644 index 0000000..400745f --- /dev/null +++ b/.well-known/wallets/.ETH.proof @@ -0,0 +1,6 @@ +I hereby confirm that I am the owner of the EVM address 0x6cB4B39bEc23a921C9a20D061Bf17d4640B0d39e. +Nathan.Woodburn/ +-------------------- +0x254919e1f2035a4f04614da9e1fbc1f45dab31b03b0baf1bb3325a9f9e437f1f787b99ebc6716b822fc190284c2c678054c91835492ff0df239ec60f6166587f1c +-------------------- +You can verify this signature by pasting it into a signature verification tool such as https://etherscan.io/verifiedSignatures \ No newline at end of file diff --git a/.well-known/wallets/.SOL.proof b/.well-known/wallets/.SOL.proof new file mode 100644 index 0000000..051c106 --- /dev/null +++ b/.well-known/wallets/.SOL.proof @@ -0,0 +1,13 @@ +I hereby confirm that I am the owner of the SOL address AJsPEEe6S7XSiVcdZKbeV8GRp1QuhFUsG8mLrqL4XgiU. +Nathan.Woodburn/ +-------------------- +[71,63,207,190,90,17,145,39,4,98,110,176,86,140,143,107,237,96,24,43,2,116,21,70,47,98,192,24,193,210,89,220,30,128,219,105,9,35,146,188,216,143,164,32,255,44,146,249,153,33,54,214,203,159,80,26,107,165,217,240,153,61,39,0] +-------------------- +0x473fcfbe5a11912704626eb0568c8f6bed60182b027415462f62c018c1d259dc1e80db69092392bcd88fa420ff2c92f9992136d6cb9f501a6ba5d9f0993d2700 +-------------------- +2Rd2EkAUwC8u4DtCZ5BXTkJEvWxozrxmcEzn7VbJFFbL81YLQngH9V1bTu3vivaQz7ZGqs5YtpPWxomsYeE7Ws6F +-------------------- +Rz/PvloRkScEYm6wVoyPa+1gGCsCdBVGL2LAGMHSWdwegNtpCSOSvNiPpCD/LJL5mSE21sufUBprpdnwmT0nAA== +-------------------- +You can verify this signature by pasting it into a signature verification tool such as https://amacar.github.io/solana-tools/#verify-message +Please note I have included various formats for the signature to make it easier to verify. \ No newline at end of file diff --git a/.well-known/wallets/BTC b/.well-known/wallets/BTC index 327a2aa..55a762b 100644 --- a/.well-known/wallets/BTC +++ b/.well-known/wallets/BTC @@ -1 +1 @@ -bc1qhs94zzcw64qnwq4hvk056rwxwvgrkd7tq7d4xw \ No newline at end of file +bc1q60qy4s6gd7se8z6nc4wu49g4u5y8k2epd3djzc \ No newline at end of file diff --git a/server.py b/server.py index 9962898..14fec7f 100644 --- a/server.py +++ b/server.py @@ -523,6 +523,11 @@ def donate(): address = '' domain = '' cryptoHTML = '' + + proof = '' + if os.path.isfile(f'.well-known/wallets/.{crypto}.proof'): + proof = f'Proof of ownership' + if os.path.isfile(f'.well-known/wallets/{crypto}'): with open(f'.well-known/wallets/{crypto}') as file: address = file.read() @@ -530,12 +535,17 @@ def donate(): cryptoHTML += f'
Donate with {coinNames[crypto] if crypto in coinNames else crypto}:' else: cryptoHTML += f'
Donate with {token["name"]} {"("+token["symbol"]+") " if token["symbol"] != token["name"] else ""}on {crypto}:' - cryptoHTML += f'{address}' + cryptoHTML += f'
{address}' + + if proof: + cryptoHTML += proof elif token: if 'address' in token: address = token['address'] cryptoHTML += f'
Donate with {token["name"]} {"("+token["symbol"]+")" if token["symbol"] != token["name"] else ""}{" on "+crypto if crypto != "NULL" else ""}:' - cryptoHTML += f'{address}' + cryptoHTML += f'
{address}' + if proof: + cryptoHTML += proof else: cryptoHTML += f'
Invalid coin: {crypto}
' else: @@ -554,12 +564,14 @@ def donate(): cryptoHTML += '
Or send to this domain on compatible wallets:
' cryptoHTML += f'{domain}' if address: - cryptoHTML += 'QR Code' + cryptoHTML += '
QR Code' copyScript = '' cryptoHTML += copyScript + + return render_template('donate.html', handshake_scripts=handshake_scripts, crypto=cryptoHTML, coins=coins,default_coins=default_coins) @app.route('/qrcode/') diff --git a/templates/assets/img/proof.png b/templates/assets/img/proof.png new file mode 100644 index 0000000000000000000000000000000000000000..1dabd389b08c4b3206c3cd8a83377c234399449f GIT binary patch literal 19470 zcmeIZc|6o#`#=7gv1VMO|&QZA=Ys>DUdkN=8 z?1}ylLd}@W$corEq_m36!G4%i4DWdD#LPQSf};4(=?m1b-(fuyN#WKEqWh0NeswFG z;0+y{**EP|5gRC)J2#QEdR{D6w)ebERnUnujd9=3X;-&Q2>$+cq}FyR>b*&I-E3>o zsc2UZ<813w>b*&UOkO&QCT~c+>1y<*lLFEg?!}lhf2>f`W+5jkx~9k{Jn-w2zOZ>( zYapq~aO%v*xxUss&f@Cwr@gpmLUCzZyG

QbN{!1wDM<+D8%LwwKS94UB(ozN>ug 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 literal 0 HcmV?d00001