polisplexity.tech/app/Http/Controllers/AuthController.php

48 lines
1.6 KiB
PHP

<?php
namespace App\Http\Controllers;
use Elliptic\EC;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use kornrunner\Keccak;
class AuthController extends Controller
{
public function message(): string
{
$nonce = Str::random();
$message = "Sign this message to confirm you own this wallet address. This action will not cost any gas fees.\n\nNonce: " . $nonce;
session()->put('sign_message', $message);
return $message;
}
public function verify(Request $request): string
{
$result = $this->verifySignature(session()->pull('sign_message'), $request->input('signature'), $request->input('address'));
// If $result is true, perform additional logic like logging the user in, or by creating an account if one doesn't exist based on the Ethereum address
return ($result ? 'OK' : 'ERROR');
}
protected function verifySignature(string $message, string $signature, string $address): bool
{
$hash = Keccak::hash(sprintf("\x19Ethereum Signed Message:\n%s%s", strlen($message), $message), 256);
$sign = [
'r' => substr($signature, 2, 64),
's' => substr($signature, 66, 64),
];
$recid = ord(hex2bin(substr($signature, 130, 2))) - 27;
if ($recid != ($recid & 1)) {
return false;
}
$pubkey = (new EC('secp256k1'))->recoverPubKey($hash, $sign, $recid);
$derived_address = '0x' . substr(Keccak::hash(substr(hex2bin($pubkey->encode('hex')), 1), 256), 24);
return (Str::lower($address) === $derived_address);
}
}