Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

:feat add passport react context and hooks #2068

Open
wants to merge 51 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
bc72f13
add passport react context and hooks
shineli1984 Aug 5, 2024
736aabf
fix typing
shineli1984 Aug 5, 2024
d72ecd3
Merge branch 'main' into add-passport-react-context-and-hooks
shineli1984 Aug 5, 2024
8245bf6
exclude react in types
shineli1984 Aug 5, 2024
0b7fc6d
change hooks
shineli1984 Aug 6, 2024
df56bbf
use context
shineli1984 Aug 6, 2024
a9b60d0
change hook interfaces
shineli1984 Aug 7, 2024
a418e26
add code snippets in example
shineli1984 Aug 7, 2024
2d97c60
add typeAssertions back
shineli1984 Aug 7, 2024
ea500f3
lint example
shineli1984 Aug 7, 2024
84cfbc1
lint
shineli1984 Aug 7, 2024
6442f79
Merge branch 'main' into add-passport-react-context-and-hooks
shineli1984 Aug 8, 2024
7239164
remove doc mk for now
shineli1984 Aug 8, 2024
81010a6
add error to context
shineli1984 Aug 8, 2024
57e3c50
example lint
shineli1984 Aug 8, 2024
de02f09
return provider when login with web3 provider
shineli1984 Aug 8, 2024
5cc9dc6
add accounts context
shineli1984 Aug 8, 2024
2e8cf9b
export useAccount
shineli1984 Aug 8, 2024
f1274ba
address comments
shineli1984 Aug 8, 2024
bcd17fb
merge main
shineli1984 Aug 8, 2024
b5f63bc
add to the consolidated example
shineli1984 Aug 8, 2024
c42f2dd
yarn lock
shineli1984 Aug 8, 2024
49b8f9a
rename PassportProvider
shineli1984 Aug 9, 2024
08634f2
change provider name
shineli1984 Aug 9, 2024
b5980b6
set error when idtoken is null
shineli1984 Aug 9, 2024
05bf6a5
change provider interface
shineli1984 Aug 12, 2024
85ed2fe
add metrics
shineli1984 Aug 12, 2024
55afc6b
typing
shineli1984 Aug 12, 2024
a1542bd
fix types
shineli1984 Aug 12, 2024
aaefc91
fix example
shineli1984 Aug 12, 2024
aa47ad0
add tests
shineli1984 Aug 13, 2024
8ae1029
yarn
shineli1984 Aug 13, 2024
4bf86e1
add missing types
shineli1984 Aug 13, 2024
2fc813e
improve interface
shineli1984 Aug 13, 2024
7a3f0bf
yarn
shineli1984 Aug 14, 2024
b7d419b
fix example
shineli1984 Aug 14, 2024
dbac851
separate to different context
shineli1984 Aug 14, 2024
efd65ed
yarn
shineli1984 Aug 14, 2024
cc0450f
yarn lock
shineli1984 Aug 14, 2024
0525454
change interface
shineli1984 Aug 15, 2024
973c147
yarn lock
shineli1984 Aug 15, 2024
c779ca9
fix snippet
shineli1984 Aug 15, 2024
b9b94e1
fix snippets
shineli1984 Aug 15, 2024
36f7c96
fix import
shineli1984 Aug 15, 2024
02cbcea
move tokens out of hooks
shineli1984 Aug 16, 2024
4383ba8
use events from passport
shineli1984 Aug 16, 2024
d2e9e3e
Revert "use events from passport"
shineli1984 Aug 19, 2024
74bb0f5
revert the event emitter
shineli1984 Aug 19, 2024
8a55532
resolve conflicts
shineli1984 Aug 19, 2024
c708c61
add mapper
shineli1984 Aug 19, 2024
c984dfb
revert back to using passport methods
shineli1984 Aug 19, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@ export default function Logout() {
>
Return to examples
</a>
<b> OR </b>
<a
className="underline"
href="/use-context"
>
Return to examples using
{' '}
<pre>passport.ZkEvmReactProvider</pre>
</a>
</div>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
'use client';

import { PassportProvider } from '@/context/passport2';
import { ReactNode } from 'react';

export default function Layout({
children,
}: Readonly<{
children: ReactNode;
}>) {
return (
<PassportProvider>{children}</PassportProvider>
);
}
113 changes: 113 additions & 0 deletions examples/passport/identity-with-nextjs/src/app/use-context/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
'use client';

import { passport, reactPassport } from '@imtbl/sdk';
import { useState } from 'react';

export default function Page() {
const {
login, logout, isLoading, isLoggedIn, getAccessToken, getIdToken, getAccounts, getLinkedAddresses, getProfile,
} = reactPassport.usePassport();

const [accessToken, setAccessToken] = useState<string | undefined>();
const [idToken, setIdToken] = useState<string | undefined>();
const [linkedAddresses, setLinkedAddresses] = useState<string[]>();
const [profile, setProfile] = useState<passport.UserProfile | undefined>();
const [accounts, setAccounts] = useState<string[]>();


return (
<div className="flex flex-col items-center justify-center min-h-screen p-8">
<h1 className="text-3xl font-bold mb-8">Passport react context example</h1>
<div className="grid grid-cols-1 gap-4 text-center">
<div>
<p className="mb-2">
<b>Loading:</b>
{' '}
{isLoading ? 'true' : 'false'}
</p>
<p className="mb-2">
<b>Is Logged In:</b>
{' '}
{isLoggedIn ? 'true' : 'false'}
</p>
<p className="mb-2">
<b>Linked Addresses:</b>
{' '}
{linkedAddresses}
</p>
<p className="mb-2">
<b>Profile:</b>
{' '}
{JSON.stringify(profile, null, 2)}
</p>
<p className="mb-2">
<b>Accounts:</b>
{' '}
{JSON.stringify(accounts, null, 2)}
</p>
<p className="mb-2">
<b>Access Token:</b>
{' '}
{accessToken}
</p>
<p className="mb-2">
<b>ID Token:</b>
{' '}
{idToken}
</p>
</div>
<button
className="bg-black text-white py-2 px-4 rounded hover:bg-gray-800"
onClick={() => login()}
type="button"
>
Login
</button>
<button
className="bg-black text-white py-2 px-4 rounded hover:bg-gray-800"
onClick={() => login({
withoutWallet: true,
})}
type="button"
>
Login without wallet
</button>
<button className="bg-black text-white py-2 px-4 rounded hover:bg-gray-800"
onClick={() => {
getAccessToken().then(setAccessToken);
getIdToken().then(setIdToken);
}}
type='button'
>Get Tokens</button>
<button
className="bg-black text-white py-2 px-4 rounded hover:bg-gray-800"
onClick={() => getLinkedAddresses().then(setLinkedAddresses)}
type="button"
>
Get Linked Addresses
</button>
<button
className="bg-black text-white py-2 px-4 rounded hover:bg-gray-800"
onClick={() => getProfile().then(setProfile)}
type="button"
>
Get Profile
</button>
<button
className="bg-black text-white py-2 px-4 rounded hover:bg-gray-800"
onClick={() => getAccounts().then(setAccounts)}
type="button"
>
Get Accounts
</button>
<button
className="bg-black text-white py-2 px-4 rounded hover:bg-gray-800"
onClick={logout}
type="button"
>
Logout
</button>
</div>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// #doc passport-react-jwt-tokens
import { reactPassport } from '@imtbl/sdk';
import { useState } from 'react';

export default function Page() {
const { login, getAccessToken, getIdToken } = reactPassport.usePassport();
const [accessToken, setAccessToken] = useState<string | undefined>();
const [idToken, setIdToken] = useState<string | undefined>();

return (
<>
Access Token:
{' '}
{accessToken}
ID Token:
{' '}
{idToken}
<button onClick={() => login()}>Login</button>
<button onClick={() => {
getAccessToken().then(setAccessToken);
getIdToken().then(setIdToken);
}}>Get Tokens</button>
</>
);
}
// #enddoc passport-react-jwt-tokens
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// #doc passport-react-login-without-wallet
import { reactPassport, passport } from '@imtbl/sdk';
import { useState } from 'react';

export default function Page() {
const { login, getProfile } = reactPassport.usePassport();
const [profile, setProfile] = useState<passport.UserProfile | undefined>(undefined);

return (
<>
user profile:
{' '}
{profile}
<button onClick={() => login({ withoutWallet: true })}>Login Without Wallet</button>
<button onClick={() => getProfile().then(setProfile)}>Get User Profile</button>
</>
);
}
// #enddoc passport-react-login-without-wallet
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// #doc passport-react-login
import { reactPassport } from '@imtbl/sdk';
import { useState } from 'react';

export default function MyComponent() {
const { login, getAccounts } = reactPassport.usePassport();

return (
<>
<button onClick={() => login()}>Login</button>
<button onClick={() => getAccounts().then((accounts) => console.log(accounts))}>Get Accounts</button>
</>
);
}
// #enddoc passport-react-login
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// #doc passport-react-logout
import { reactPassport } from '@imtbl/sdk';

export default function Page() {
const { logout } = reactPassport.usePassport();

return (
<button onClick={logout}>Logout</button>
);
}
// #enddoc passport-react-logout
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// #doc passport-setup-react
import { config, reactPassport } from '@imtbl/sdk';
import { ReactNode } from 'react';

export function PassportProvider({ children }: { children: ReactNode }) {
return (
<reactPassport.ZkEvmReactProvider
config={{
baseConfig: {
environment: config.Environment.SANDBOX, // or config.Environment.SANDBOX
publishableKey: process.env.NEXT_PUBLIC_PUBLISHABLE_KEY || '<YOUR_PUBLISHABLE_KEY>', // replace with your publishable API key from Hub
},
clientId: process.env.NEXT_PUBLIC_CLIENT_ID || '<YOUR_CLIENT_ID>', // replace with your client ID from Hub
redirectUri: 'http://localhost:3000/redirect', // replace with one of your redirect URIs from Hub
logoutRedirectUri: 'http://localhost:3000/logout', // replace with one of your logout URIs from Hub
audience: 'platform_api',
scope: 'openid offline_access email transact',
}}
>
{children}
</reactPassport.ZkEvmReactProvider>
);
}
// #enddoc passport-setup-react
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@
"packages/checkout/widgets-lib",
"packages/blockchain-data/sdk",
"packages/game-bridge",
"packages/react/passport",
"packages/webhook/sdk",
"packages/minting-backend/sdk",
"tests/**",
Expand Down
1 change: 1 addition & 0 deletions packages/passport/sdk/.eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module.exports = {
"tsconfigRootDir": __dirname
},
"rules": {
"react/react-in-jsx-scope": ["off"],
"@typescript-eslint/naming-convention": [
"error",
{
Expand Down
2 changes: 0 additions & 2 deletions packages/passport/sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@
"@types/axios": "^0.14.0",
"@types/jest": "^29.4.3",
"@types/jwt-encode": "^1.0.1",
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
"@types/uuid": "^8.3.4",
"@typescript-eslint/eslint-plugin": "^5.57.1",
"@typescript-eslint/parser": "^5.57.1",
Expand Down
1 change: 1 addition & 0 deletions packages/passport/sdk/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"extends": "../../../tsconfig.base.json",
"compilerOptions": {
"jsx": "react-jsx",
"outDir": "./dist",
"rootDirs": ["src"],
"customConditions": ["development"]
Expand Down
27 changes: 27 additions & 0 deletions packages/react/passport/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module.exports = {
"extends": ["../../../.eslintrc"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "./tsconfig.json",
"tsconfigRootDir": __dirname
},
"rules": {
"react/react-in-jsx-scope": ["off"],
"@typescript-eslint/naming-convention": [
"error",
{
"selector": "variable",
"format": ["camelCase", "UPPER_CASE", "snake_case"]
}
],
"max-len": [
"error",
{
"code": 120,
"ignoreComments": true,
"ignoreTrailingComments": true,
"ignoreStrings": true
}
]
}
}
15 changes: 15 additions & 0 deletions packages/react/passport/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { Config } from 'jest';

const config: Config = {
clearMocks: true,
coverageProvider: 'v8',
moduleDirectories: ['node_modules', 'src'],
moduleNameMapper: { '^@imtbl/(.*)$': '<rootDir>/../../../node_modules/@imtbl/$1/src' },
testEnvironment: 'jsdom',
transform: {
'^.+\\.(t|j)sx?$': '@swc/jest',
},
transformIgnorePatterns: [],
};

export default config;
62 changes: 62 additions & 0 deletions packages/react/passport/package.json
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding the package.json:

  • Could the "d" command be updated to be a rollup config build without the NODE_ENV=production, and have the rollup.config.js to conditionally use typescript or swc when rebuilding to match the change that was merged in yesterday?
  • The unplugin-swc dependency will then need to be added to this package
  • The exports object needs to be set up for the conditional types for live types locally, matching the other package.jsons that were updated
  • I'll drop the tsconfig change needed here; the customConditions value also needs to be added to support the live types.

You can use the passport sdk package.json/rollup.config/tsconfig.json as a point of reference

Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{
"name": "@imtbl/react-passport",
"description": "Passport React SDK",
"version": "0.0.0",
"author": "Immutable",
"bugs": "https://github.com/immutable/ts-immutable-sdk/issues",
"dependencies": {
"@imtbl/config": "0.0.0",
"@imtbl/metrics": "0.0.0",
"@imtbl/passport": "0.0.0"
},
"devDependencies": {
"@rollup/plugin-typescript": "^11.1.6",
"@swc/core": "^1.3.36",
"@swc/jest": "^0.2.24",
"@testing-library/react-hooks": "^8.0.1",
"@types/axios": "^0.14.0",
"@types/jest": "^29.4.3",
"@types/jwt-encode": "^1.0.1",
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
"@types/react-test-renderer": "^18.3.0",
"@types/uuid": "^8.3.4",
"@typescript-eslint/eslint-plugin": "^5.57.1",
"@typescript-eslint/parser": "^5.57.1",
"cross-fetch": "^3.1.6",
"eslint": "^8.40.0",
"jest": "^29.4.3",
"jest-environment-jsdom": "^29.4.3",
"jwt-encode": "^1.0.1",
"msw": "^1.2.2",
"prettier": "^2.8.7",
"react-test-renderer": "^18.3.1",
"rollup": "^4.19.1",
"ts-node": "^10.9.1",
"typescript": "^5.5.4"
},
"engines": {
"node": ">=20.11.0"
},
"files": [
"dist"
],
"homepage": "https://github.com/immutable/ts-immutable-sdk#readme",
"license": "Apache-2.0",
"main": "dist/index.js",
"optionalDependencies": {
"react": ">=17.0.0"
},
"private": true,
"repository": "immutable/ts-immutable-sdk.git",
"scripts": {
"build": "NODE_ENV=production rollup --config rollup.config.js",
"d": "swc src -d dist --strip-leading-paths --ignore '**/*.test.*'",
"lint": "eslint ./src --ext .ts,.jsx,.tsx --max-warnings=0",
"test": "jest",
"test:watch": "jest --watch",
"typecheck": "tsc --noEmit --jsx preserve"
},
"type": "module",
"types": "dist/index.d.ts"
}
10 changes: 10 additions & 0 deletions packages/react/passport/rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import typescript from '@rollup/plugin-typescript';

export default {
input: 'src/index.ts',
output: {
dir: 'dist',
format: 'es',
},
plugins: [typescript()],
};
Loading
Loading