定制 karhal/web3-connect 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

karhal/web3-connect

Composer 安装命令:

composer require karhal/web3-connect

包简介

Allows login on symfony application via ethereum wallet

README 文档

README

Depfu codecov

Web3 Wallet Connect Bundle

Description

This Symfony bundle lets your users authenticate with their ethereum wallet. To do this you only need them to sign a message with their wallet.

This bundle uses the EIP-4361, it is meant to work with the spruceid/siwe library

Why ?

Your wallet lets you connect to any decentralized application using your Ethereum account. It's like a login you can use across many dapps. This bundle is here to bring this feature to every Symfony website.

Getting started

Installation

composer require karhal/web3-connect
<?php

//config/bundles.php

return [
    //... ,
    Karhal\Web3ConnectBundle\Web3ConnectBundle::class => ['all' => true],
];

Configuration

config/packages/web3_connect.yaml

wallet_connect:
  user_class: App\Entity\User
  jwt_secret: MySecretPhrase

config/packages/security.yaml

security:
    #...
    providers:
        #...
        web3_user_provider:
            entity:
                class: App\Entity\User
                property: walletAddress
    firewalls:
        #...
        web3:
            custom_authenticators:
                - Karhal\Web3ConnectBundle\Security\Web3Authenticator
            provider: web3_user_provider

        main: #...

config/routes.yaml

web3_link:
  resource: "@Web3ConnectBundle/config/routes.yaml"

Update the model of the class representing the user by implementing the Web3UserInterface

//...
use use Karhal\Web3ConnectBundle\Model\Web3UserInterface;
//...

class User implements Web3UserInterface
{
    //...
    
    #[ORM\Column(type: 'string', nullable: true)]
    private ?string $walletAddress;

    public function getWalletAddress(): string
    {
        return $this->walletAddress;
    }

    public function setWalletAddress(string $wallet)
    {
        $this->walletAddress = $wallet;
    }
}

Then update your storage

php bin/console doctrine:mig:diff
php bin/console doctrine:mig:mig

Now you're good to go

Usage

The bundle provides a signature route to generate the message to sign. Once the message signed, send it back with the address which signed it.

Step 1: Get the nonce

Before each signature, get the nonce from the backend

    const res = await fetch(`${BACKEND_ADDR}/web3_nonce`, {
    credentials: 'include',
    mode: 'cors',
    headers: {
        'Accept': 'application/json',
    },
});

Step 2: Generate the message

    const message = await createSiweMessage(
        await signer.getAddress(),
        'Sign in with Ethereum to the app.'
    );

Step 3: Send the message with his signature

    const res = await fetch(`${BACKEND_ADDR}/web3_verify`, {
    headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({ message, signature }),
    credentials: 'include',
    method: "POST",
    mode: 'cors',
});

Full example with the spruceid/siwe-quickstart example

import { ethers } from 'ethers';
import { SiweMessage } from 'siwe';

const domain = window.location.host;
const origin = window.location.origin;
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();

const BACKEND_ADDR = "http://127.0.0.1:8000";
async function createSiweMessage(address, statement) {
    const res = await fetch(`${BACKEND_ADDR}/web3_nonce`, {
        credentials: 'include',
        mode: 'cors',
        headers: {
            'Accept': 'application/json',
        },
    });
    const message = new SiweMessage({
        domain,
        address,
        statement,
        uri: origin,
        version: '1',
        chainId: '1',
        nonce: (await res.json()).nonce
    });
    return message.prepareMessage();
}

function connectWallet() {
    provider.send('eth_requestAccounts', [])
        .catch(() => console.log('user rejected request'));
}

async function signInWithEthereum() {
    const message = await createSiweMessage(
        await signer.getAddress(),
        'Sign in with Ethereum to the app.'
    );
    const signature = await signer.signMessage(message);

    const res = await fetch(`${BACKEND_ADDR}/web3_verify`, {
        headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({ message, signature }),
        credentials: 'include',
        method: "POST",
        mode: 'cors',
    });
    document.getElementById('infoUser').innerText = 'Welcome '+  (await res.json()).identifier;
}


const connectWalletBtn = document.getElementById('connectWalletBtn');
const siweBtn = document.getElementById('siweBtn');
connectWalletBtn.onclick = connectWallet;
siweBtn.onclick = signInWithEthereum;

The bundle will verify the signed message is owned by the address. If true, the owner of the address from your storage will be loaded as a JWT token.

Response:

{
    "identifier": "foo@bar.com",
    "token": "eyJ0eXs[...]",
    "data": {}
}

Step 4: Access authorized routes

You can now make requests to authorized routes by adding the http_header to the headers of your requests with the value of the just generated token.

    const res = await fetch(`${BACKEND_ADDR}/private_url`, {
    headers: {
        'Accept': 'application/json',
        'X-AUTH-WEB3TOKEN': 'eyJ0eXs[...]'
    },
});

Step 5: Customize the bundle Response

Just before returning the Response the bundle dispatch a DataInitializedEvent event providing a data array you can fill to provide some extra information to your front.

You can add any data you want by listening to this event and call his setData method.

<?php

namespace App\EventListener;

use Karhal\Web3ConnectBundle\Event\DataInitializedEvent;

class Web3LoginEventListener
{
    public function onWeb3userDataInitialized(DataInitializedEvent $event)
    {
        $event->setData(['foo' => 'bar']);
    }
}

Response:

{
    "identifier": "foo@bar.com",
    "token": "eyJ0eXs[...]",
    "data": {
        "foo": "bar"
    }
}

Resources

What's an Ethereum wallet?

Ethereum wallets are applications that let you interact with your Ethereum account. Think of it like an internet banking app – without the bank. Your wallet lets you read your balance, send transactions and connect to applications.

“No more remembering unique passwords for separate sites. No more creating unique email addresses for different services. No more having to worry about the site you are interacting with having your data stolen from them. Pure, self-sovereign control of your accounts across the Internet. No usernames, passwords, or identifying information other than the public key that is derived upon sign up.”

Tests

vendor/bin/phpunit 

License

The MIT License (MIT). Please see License File for more information.

karhal/web3-connect 适用场景与选型建议

karhal/web3-connect 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 6.04k 次下载、GitHub Stars 达 7, 最近一次更新时间为 2022 年 02 月 04 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 karhal/web3-connect 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 karhal/web3-connect 我们能提供哪些服务?
定制开发 / 二次开发

基于 karhal/web3-connect 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 6.04k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 7
  • 点击次数: 10
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 7
  • Watchers: 1
  • Forks: 1
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2022-02-04