Skip to content

Commit

Permalink
Add Privy Provider (#313)
Browse files Browse the repository at this point in the history
* feat: add dapp-kit-react-privy package

* fix: continue the privy provider

* fix: fix build issue

* fix: add sample privy next app

* fix: fix issue

* feat: add ConnectModal

* fix: fix linter issue

* fix: improve modal

* fix: refactor

* fix: refactor

* fix: improve example UI

* fix: improve modal

* feat: add new hooks

* fix: add readme files and a small explanation

* fix: update package

* fi: update readme

* feat: move config in separate object + solve compilation issues

* fix: typos

* feat: refactor return types

* feat: fixed issues

* feat: update twitter logo

* feat: handle cross accounts

* feat: use chakra

* feat: cross app login

* fix: transactions

* feat: connect button

* fix: dependency

* feat: display connected account

* feat: fetch app info

* feat: go back to main modal

* fix: apps info loop

* feat: update params structure

* feat: copy address

* feat: transaction modal

* feat: add chakra theme

* feat: color mode

* feat: add settings

* feat: refactor ConnectModal

* feat: refactored app icons

* fix: on mobile show modal fixed bottom

* feat: transaction toast

* style: connect modal

* fix: show spinner on demo

* feat: refactor address cards

* feat: added smart account content

* style: login buttons

* style: show bigger address

* Add AbstractAccountSigner (#325)

* feat: add AbstractAccountSigner

* fix: add example

* fix: fix sdk version

* fix: fix typo and package version

* fix: refactor code

* fix: refactor code

* fix: rename to Smart AccountSigner

* fix: move logic in a separate component

* fix: fix import

* fix: fix issue

* fix: add console.log

* fix: fix security issue

* fix: fix coverage

* fix: fix sonar issue

* fix: fix sonar issue

* fix: fix sonar issues

* feat: remove sdk signer

---------

Co-authored-by: Dan Rusnac <[email protected]>

* fix: modal scroll, disable cross app btns

* fix: wallet addresses

* fix: selected address and connected accoount

---------

Co-authored-by: Dan Rusnac <[email protected]>
  • Loading branch information
fabiorigam and Agilulfo1820 authored Dec 19, 2024
1 parent 48a95d2 commit 7b20e81
Show file tree
Hide file tree
Showing 88 changed files with 8,435 additions and 72 deletions.
6 changes: 6 additions & 0 deletions examples/sample-next-privy-app/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Privy Configuration
NEXT_PUBLIC_PRIVY_APP_ID=
NEXT_PUBLIC_PRIVY_CLIENT_ID=
# Wallet Connect Project ID
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID=
NEXT_PUBLIC_DELEGATOR_URL=
6 changes: 6 additions & 0 deletions examples/sample-next-privy-app/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
extends: ['next'],
rules: {
'@typescript-eslint/unbound-method': 'off',
},
};
37 changes: 37 additions & 0 deletions examples/sample-next-privy-app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env
.env*.local

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
55 changes: 55 additions & 0 deletions examples/sample-next-privy-app/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# `sample-privy-next-app`

This example demonstrates how to integrate the `@vechain/dapp-kit-react-privy` package into a Next.js application. It showcases how to leverage the library for seamless social login and VeChain ecosystem integration, providing a foundation for building robust and user-friendly decentralized applications (dApps).

## How it works

### Step 1: Dynamically Import the SocialLoginWrapper

To ensure compatibility with server-side rendering, dynamically import the SocialLoginWrapper component in layout.tsx:

```typescript
const SocialLoginWrapper = dynamic(
async () =>
(await import('./components/SocialLoginWrapper')).SocialLoginWrapper,
{
ssr: false,
},
);

export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<head>
<title>Privy Next JS</title>
</head>
<body>
<SocialLoginWrapper>{children}</SocialLoginWrapper>
</body>
</html>
);
}
```

### Step 2: Use Hooks and Components

Import the necessary hooks and components from @vechain/dapp-kit-react-privy and use them to interact with the VeChain ecosystem in your application:

```typescript
import { useVOT3Balance, useB3TRBalance } from '@vechain/dapp-kit-react-privy';

const b3trBalanceQuery = isConnected
? useB3TRBalance({ address: connectedAccount ?? '' })
: useB3TRBalance({
address: abstractedAccount.embeddedWallet?.address ?? '',
});
const vot3BalanceQuery = isConnected
? useVOT3Balance({ address: connectedAccount ?? '' })
: useVOT3Balance({
address: abstractedAccount.embeddedWallet?.address ?? '',
});
```
18 changes: 18 additions & 0 deletions examples/sample-next-privy-app/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const basePath = process.env.BASE_PATH ?? '';

/** @type {import('next').NextConfig} */
const nextConfig = {
basePath,
output: 'export',
distDir: 'dist',
env: {
basePath,
},
eslint: {
// Warning: This allows production builds to successfully complete even if
// your project has ESLint errors.
ignoreDuringBuilds: true,
},
};

module.exports = nextConfig;
30 changes: 30 additions & 0 deletions examples/sample-next-privy-app/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "sample-next-privy-app",
"version": "0.1.0",
"private": true,
"scripts": {
"build": "next build",
"clean": "rm -rf .next dist .turbo",
"dev": "next dev"
},
"dependencies": {
"@chakra-ui/react": "2.8.2",
"@emotion/react": "^11.13.5",
"@emotion/styled": "^11.13.5",
"@vechain/dapp-kit": "*",
"@vechain/dapp-kit-react": "*",
"@vechain/dapp-kit-react-privy": "*",
"next": "14.2.10",
"react": "^18",
"react-dom": "^18"
},
"devDependencies": {
"@next/eslint-plugin-next": "^14.1.4",
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"eslint": "^9.12.0",
"eslint-config-next": "14.1.4",
"typescript": "5.3.3"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
'use client';

import { useColorMode } from '@chakra-ui/react';
import dynamic from 'next/dynamic';

const DAppKitPrivyProvider = dynamic(
async () =>
(await import('@vechain/dapp-kit-react-privy')).DAppKitPrivyProvider,
{
ssr: false,
},
);

interface Props {
children: React.ReactNode;
}

export function SocialLoginWrapper({ children }: Props) {
const { colorMode } = useColorMode();
return (
<DAppKitPrivyProvider
privyConfig={{
appId: process.env.NEXT_PUBLIC_PRIVY_APP_ID!,
clientId: process.env.NEXT_PUBLIC_PRIVY_CLIENT_ID!,
loginMethods: ['google', 'twitter', 'github', 'sms', 'email'],
appearance: {
theme: colorMode,
accentColor: '#696FFD',
loginMessage: 'Select a social media profile',
logo: 'https://i.ibb.co/ZHGmq3y/image-21.png',
},
embeddedWallets: {
createOnLogin: 'all-users',
},
ecosystemAppsID: [
'clz41gcg00e4ay75dmq3uzzgr', //cleanify
'clxdoatq601h35inz6qykgmai',
'clpgf04wn04hnkw0fv1m11mnb',
'clrtmg1n104ypl60p9w5c3v4c',
],
allowPasskeyLinking: true,
}}
feeDelegationConfig={{
delegatorUrl: process.env.NEXT_PUBLIC_DELEGATOR_URL!,
delegateAllTransactions: true,
}}
dappKitConfig={{
nodeUrl: 'https://node.vechain.energy',
genesis: {
number: 0,
id: '0x00000000851caf3cfdb6e899cf5958bfb1ac3413d346d43539627e6be7ec1b4a',
size: 170,
parentID:
'0xffffffff53616c757465202620526573706563742c20457468657265756d2100',
timestamp: 1530316800,
gasLimit: 10000000,
beneficiary: '0x0000000000000000000000000000000000000000',
gasUsed: 0,
totalScore: 0,
txsRoot:
'0x45b0cfc220ceec5b7c1c62c4d4193d38e4eba48e8815729ce75f9c0ab0e4c1c0',
txsFeatures: 0,
stateRoot:
'0x09bfdf9e24dd5cd5b63f3c1b5d58b97ff02ca0490214a021ed7d99b93867839c',
receiptsRoot:
'0x45b0cfc220ceec5b7c1c62c4d4193d38e4eba48e8815729ce75f9c0ab0e4c1c0',
signer: '0x0000000000000000000000000000000000000000',
isTrunk: true,
transactions: [],
},
themeMode: colorMode === 'dark' ? 'DARK' : 'LIGHT',
walletConnectOptions: {
projectId:
process.env.NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID!,
metadata: {
name: 'Your App',
description: 'Your app description',
url:
typeof window !== 'undefined'
? window.location.origin
: '',
icons: [
typeof window !== 'undefined'
? `${window.location.origin}/images/logo/my-dapp.png`
: '',
],
},
},
}}
>
{children}
</DAppKitPrivyProvider>
);
}
26 changes: 26 additions & 0 deletions examples/sample-next-privy-app/src/app/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
export const b3trMainnetAddress = '0x5ef79995FE8a89e0812330E4378eB2660ceDe699';
export const b3trTestnetAddress = '0xbf64cf86894Ee0877C4e7d03936e35Ee8D8b864F';
export const b3trAbi = [
// Replace this with your actual transfer function ABI
{
inputs: [
{
name: 'recipient',
type: 'address',
},
{
name: 'amount',
type: 'uint256',
},
],
name: 'transfer',
outputs: [
{
name: '',
type: 'bool',
},
],
stateMutability: 'nonpayable',
type: 'function',
},
] as const;
Binary file not shown.
Binary file not shown.
23 changes: 23 additions & 0 deletions examples/sample-next-privy-app/src/app/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
body {
margin: 0;
display: flex;
height: 100vh;
align-items: center;
justify-content: center;
}
h2 {
margin: 0;
}
.container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
border: 1px solid #000;
border-radius: 20px;
padding: 20px;
}
.label {
margin-top: 20px;
margin-bottom: 10px;
}
36 changes: 36 additions & 0 deletions examples/sample-next-privy-app/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
'use client';

import { ChakraProvider } from '@chakra-ui/react';
import './globals.css';
import dynamic from 'next/dynamic';

const SocialLoginWrapper = dynamic(
async () =>
(await import('./components/SocialLoginWrapper')).SocialLoginWrapper,
{
ssr: false,
},
);

export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en" suppressHydrationWarning={true}>
<head>
<meta
name="viewport"
content="width=device-width, initial-scale=1"
/>
<title>Privy Next JS</title>
</head>
<body>
<ChakraProvider>
<SocialLoginWrapper>{children}</SocialLoginWrapper>
</ChakraProvider>
</body>
</html>
);
}
17 changes: 17 additions & 0 deletions examples/sample-next-privy-app/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'use client';

import { Container } from '@chakra-ui/react';
import dynamic from 'next/dynamic';
import React from 'react';

const Homepage = dynamic(() => import('./pages/homepage'), {
ssr: false,
});

export default function Page() {
return (
<Container maxW="container.xl">
<Homepage />
</Container>
);
}
Loading

0 comments on commit 7b20e81

Please sign in to comment.