{"id":15489460,"url":"https://github.com/karhal/web3-connect","last_synced_at":"2025-04-15T01:07:50.126Z","repository":{"id":43722953,"uuid":"455585671","full_name":"Karhal/web3-connect","owner":"Karhal","description":"Give your Symfony users an way to sign In with an Ethereum wallet","archived":false,"fork":false,"pushed_at":"2025-04-08T10:51:59.000Z","size":76,"stargazers_count":6,"open_issues_count":7,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-15T01:07:42.208Z","etag":null,"topics":["authentication-backend","eip-4361","ethereum","php","symfony-bundle","token"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Karhal.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-02-04T14:52:33.000Z","updated_at":"2024-07-29T23:07:48.000Z","dependencies_parsed_at":"2023-01-30T20:46:07.340Z","dependency_job_id":"d68a6276-7237-49aa-be0c-ce84f3c976e2","html_url":"https://github.com/Karhal/web3-connect","commit_stats":{"total_commits":46,"total_committers":2,"mean_commits":23.0,"dds":"0.32608695652173914","last_synced_commit":"769eefe8da8e9c3b46a92fe4d6004c269891f956"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Karhal%2Fweb3-connect","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Karhal%2Fweb3-connect/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Karhal%2Fweb3-connect/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Karhal%2Fweb3-connect/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Karhal","download_url":"https://codeload.github.com/Karhal/web3-connect/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248986312,"owners_count":21194025,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["authentication-backend","eip-4361","ethereum","php","symfony-bundle","token"],"created_at":"2024-10-02T07:05:58.629Z","updated_at":"2025-04-15T01:07:50.107Z","avatar_url":"https://github.com/Karhal.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Depfu](https://badges.depfu.com/badges/39be77dd94720ddf864ac11ef638d293/overview.svg)](https://badges.depfu.com/github/Karhal/web3-connect?project_id=34082)\n[![codecov](https://codecov.io/gh/Karhal/web3-connect/branch/main/graph/badge.svg?token=4UL8g1hRfe)](https://codecov.io/gh/Karhal/web3-connect)\n\n# Web3 Wallet Connect Bundle\n\n## Description\n\nThis Symfony bundle lets your users authenticate with their ethereum wallet.\nTo do this you only need them to sign a message with their wallet.\n\nThis bundle uses the EIP-4361, it is meant to work with the [spruceid/siwe](https://github.com/spruceid/siwe) library\n### Why ?\n\nYour wallet lets you connect to any decentralized application using your Ethereum account. It's like a login you can use across many dapps.\nThis bundle is here to bring this feature to every Symfony website.\n\n## Getting started\n\n### Installation\n\n```bash\ncomposer require karhal/web3-connect\n```\n\n```php\n\u003c?php\n\n//config/bundles.php\n\nreturn [\n    //... ,\n    Karhal\\Web3ConnectBundle\\Web3ConnectBundle::class =\u003e ['all' =\u003e true],\n];\n```\n\n### Configuration\n\nconfig/packages/web3_connect.yaml\n\n```yaml\nwallet_connect:\n  user_class: App\\Entity\\User\n  jwt_secret: MySecretPhrase\n```\nconfig/packages/security.yaml\n\n```yaml\nsecurity:\n    #...\n    providers:\n        #...\n        web3_user_provider:\n            entity:\n                class: App\\Entity\\User\n                property: walletAddress\n    firewalls:\n        #...\n        web3:\n            custom_authenticators:\n                - Karhal\\Web3ConnectBundle\\Security\\Web3Authenticator\n            provider: web3_user_provider\n\n        main: #...\n```\n\nconfig/routes.yaml\n\n```yaml\nweb3_link:\n  resource: \"@Web3ConnectBundle/config/routes.yaml\"\n```\nUpdate the model of the class representing the user by implementing the Web3UserInterface\n```php\n\n//...\nuse use Karhal\\Web3ConnectBundle\\Model\\Web3UserInterface;\n//...\n\nclass User implements Web3UserInterface\n{\n    //...\n    \n    #[ORM\\Column(type: 'string', nullable: true)]\n    private ?string $walletAddress;\n\n    public function getWalletAddress(): string\n    {\n        return $this-\u003ewalletAddress;\n    }\n\n    public function setWalletAddress(string $wallet)\n    {\n        $this-\u003ewalletAddress = $wallet;\n    }\n}\n```\n\nThen update your storage\n\n```bash\nphp bin/console doctrine:mig:diff\nphp bin/console doctrine:mig:mig\n````\n\nNow you're good to go\n\n# Usage\n\nThe bundle provides a signature route to generate the message to sign.\nOnce the message signed, send it back with the address which signed it.\n\n## Step 1: Get the nonce\n\nBefore each signature, get the nonce from the backend\n\n```javascript\n    const res = await fetch(`${BACKEND_ADDR}/web3_nonce`, {\n    credentials: 'include',\n    mode: 'cors',\n    headers: {\n        'Accept': 'application/json',\n    },\n});\n```\n\n## Step 2: Generate the message \n\n```javascript\n    const message = await createSiweMessage(\n        await signer.getAddress(),\n        'Sign in with Ethereum to the app.'\n    );\n```\n\n## Step 3: Send the message with his signature\n\n```javascript\n    const res = await fetch(`${BACKEND_ADDR}/web3_verify`, {\n    headers: {\n        'Accept': 'application/json',\n        'Content-Type': 'application/json',\n    },\n    body: JSON.stringify({ message, signature }),\n    credentials: 'include',\n    method: \"POST\",\n    mode: 'cors',\n});\n```\n\nFull example with the [spruceid/siwe-quickstart example](https://github.com/spruceid/siwe-quickstart/tree/main/03_complete_app/frontend) \n\n```javascript\nimport { ethers } from 'ethers';\nimport { SiweMessage } from 'siwe';\n\nconst domain = window.location.host;\nconst origin = window.location.origin;\nconst provider = new ethers.providers.Web3Provider(window.ethereum);\nconst signer = provider.getSigner();\n\nconst BACKEND_ADDR = \"http://127.0.0.1:8000\";\nasync function createSiweMessage(address, statement) {\n    const res = await fetch(`${BACKEND_ADDR}/web3_nonce`, {\n        credentials: 'include',\n        mode: 'cors',\n        headers: {\n            'Accept': 'application/json',\n        },\n    });\n    const message = new SiweMessage({\n        domain,\n        address,\n        statement,\n        uri: origin,\n        version: '1',\n        chainId: '1',\n        nonce: (await res.json()).nonce\n    });\n    return message.prepareMessage();\n}\n\nfunction connectWallet() {\n    provider.send('eth_requestAccounts', [])\n        .catch(() =\u003e console.log('user rejected request'));\n}\n\nasync function signInWithEthereum() {\n    const message = await createSiweMessage(\n        await signer.getAddress(),\n        'Sign in with Ethereum to the app.'\n    );\n    const signature = await signer.signMessage(message);\n\n    const res = await fetch(`${BACKEND_ADDR}/web3_verify`, {\n        headers: {\n            'Accept': 'application/json',\n            'Content-Type': 'application/json',\n        },\n        body: JSON.stringify({ message, signature }),\n        credentials: 'include',\n        method: \"POST\",\n        mode: 'cors',\n    });\n    document.getElementById('infoUser').innerText = 'Welcome '+  (await res.json()).identifier;\n}\n\n\nconst connectWalletBtn = document.getElementById('connectWalletBtn');\nconst siweBtn = document.getElementById('siweBtn');\nconnectWalletBtn.onclick = connectWallet;\nsiweBtn.onclick = signInWithEthereum;\n```\n\nThe 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.\n\nResponse:\n\n````json\n{\n    \"identifier\": \"foo@bar.com\",\n    \"token\": \"eyJ0eXs[...]\",\n    \"data\": {}\n}\n````\n\n## Step 4: Access authorized routes\n\nYou 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.\n\n```javascript\n    const res = await fetch(`${BACKEND_ADDR}/private_url`, {\n    headers: {\n        'Accept': 'application/json',\n        'X-AUTH-WEB3TOKEN': 'eyJ0eXs[...]'\n    },\n});\n```\n\n## Step 5: Customize the bundle Response\n\nJust 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.\n\nYou can add any data you want by listening to this event and call his `setData` method.\n\n```php\n\u003c?php\n\nnamespace App\\EventListener;\n\nuse Karhal\\Web3ConnectBundle\\Event\\DataInitializedEvent;\n\nclass Web3LoginEventListener\n{\n    public function onWeb3userDataInitialized(DataInitializedEvent $event)\n    {\n        $event-\u003esetData(['foo' =\u003e 'bar']);\n    }\n}\n```\n\nResponse:\n\n```json\n{\n    \"identifier\": \"foo@bar.com\",\n    \"token\": \"eyJ0eXs[...]\",\n    \"data\": {\n        \"foo\": \"bar\"\n    }\n}\n```\n\n# Resources\n\n- [Fast Elliptic Curve Cryptography in PHP](https://github.com/simplito/elliptic-php)\n- [Ethereum-PHP](https://github.com/digitaldonkey/ethereum-php)\n- https://medium.com/fabric-ventures/what-is-web-3-0-why-it-matters-934eb07f3d2b\n- https://medium.com/mycrypto/the-magic-of-digital-signatures-on-ethereum-98fe184dc9c7\n- https://eips.ethereum.org/EIPS/eip-4361#message-field-descriptions\n\n### What's an Ethereum wallet?\n\nEthereum 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.\n\n\u003cem\u003e“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.”\u003c/em\u003e\n\n# Tests\n\n```bash\nvendor/bin/phpunit \n```\n\n# License\n\nThe MIT License (MIT). Please see [License File](LICENSE.md) for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkarhal%2Fweb3-connect","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkarhal%2Fweb3-connect","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkarhal%2Fweb3-connect/lists"}