Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 11 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/** @type {import('eslint').ESLint.ConfigData} */
module.exports = {
root: true,
extends: ["prettier"],
rules: {
"no-unexpected-multiline": "warn",
"react/display-name": "off",
semi: 0,
"react/no-unescaped-entities": 0,
},
};
2 changes: 2 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
.next
19 changes: 19 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"arrowParens": "always",
"endOfLine": "lf",
"importOrderSortSpecifiers": true,
"printWidth": 90,
"semi": false,
"singleQuote": true,
"trailingComma": "es5",
"importOrderSeparation": true,
"importOrder": [
"^[components]",
"^[constants]",
"^[hooks]",
"^[styles]",
"^[types]",
"^@(.*)$",
"^[./]"
]
}
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
# Tokenbound SDK

This repo houses the tokenbound SDK, a front end library for interacting with [ERC-6551 accounts](https://eips.ethereum.org/EIPS/eip-6551).
This repo houses the Tokenbound SDK, a front-end library for interacting with [ERC-6551 accounts](https://eips.ethereum.org/EIPS/eip-6551).

### Packages

- **[@tokenbound/sdk](https://github.com/tokenbound/sdk/tree/main/packages/sdk)** - SDK client for projects using viem
- **[@tokenbound/sdk-ethers](https://github.com/tokenbound/sdk/tree/main/packages/sdk-ethers)** - SDK client for projects using ethers
- **[@tokenbound/sdk](https://github.com/tokenbound/sdk/tree/main/packages/sdk)** - SDK client for all projects, signing enabled via either Ethers Signer or viem WalletClient.
- **[@tokenbound/react](https://github.com/tokenbound/sdk/tree/main/packages/react)** - Low-level react hooks for interacting with token bound accounts

### Examples

- **[examples/vite-wagmi](https://github.com/tokenbound/sdk/tree/main/examples/vite-wagmi)** - An example app using the tokenbound SDK in a vite project with wagmi
- **[examples/vite-wagmi](https://github.com/tokenbound/sdk/tree/main/examples/vite-wagmi-ethers)** - An example app using the tokenbound SDK in a vite project with ethers v5
- **[examples/vite-wagmi](https://github.com/tokenbound/sdk/tree/main/examples/vite-wagmi-ethers6)** - An example app using the tokenbound SDK in a vite project with ethers v6

### Development

Expand Down
1 change: 1 addition & 0 deletions examples/vite-wagmi-ethers/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
VITE_ALCHEMY_API_KEY=
47 changes: 47 additions & 0 deletions examples/vite-wagmi-ethers/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies

/node_modules
/.pnp
.pnp.js

# testing

/coverage

# vite

dist
dist-ssr

# production

/build

# misc

.DS_Store
\*.pem
*.local

# debug

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

# local env files

.env
.env\*.local

# vercel

.vercel

# typescript

\*.tsbuildinfo
next-env.d.ts
1 change: 1 addition & 0 deletions examples/vite-wagmi-ethers/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
strict-peer-dependencies = false
16 changes: 16 additions & 0 deletions examples/vite-wagmi-ethers/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
This is a [wagmi](https://wagmi.sh) + [ConnectKit](https://docs.family.co/connectkit) + [Vite](https://vitejs.dev/) project bootstrapped with [`create-wagmi`](https://github.com/wagmi-dev/wagmi/tree/main/packages/create-wagmi)

# Getting Started

Run `npm run dev` in your terminal, and then open [localhost:5173](http://localhost:5173) in your browser.

Once the webpage has loaded, changes made to files inside the `src/` directory (e.g. `src/App.tsx`) will automatically update the webpage.

# Learn more

To learn more about [Vite](https://vitejs.dev/), [ConnectKit](https://docs.family.co/connectkit) or [wagmi](https://wagmi.sh), check out the following resources:

- [wagmi Documentation](https://wagmi.sh) – learn about wagmi Hooks and API.
- [wagmi Examples](https://wagmi.sh/examples/connect-wallet) – a suite of simple examples using wagmi.
- [ConnectKit Documentation](https://docs.family.co/connectkit) – learn more about ConnectKit (configuration, theming, advanced usage, etc).
- [Vite Documentation](https://vitejs.dev/) – learn about Vite features and API.
13 changes: 13 additions & 0 deletions examples/vite-wagmi-ethers/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Tokenbound Demo - Ethers 5 Signer</title>
<script type="module" src="./polyfills.ts"></script>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
30 changes: 30 additions & 0 deletions examples/vite-wagmi-ethers/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "vite-wagmi-ethers",
"version": "0.0.0",
"private": true,
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview",
"clean": "rm -rf node_modules"
},
"dependencies": {
"@tokenbound/sdk": "workspace:^",
"buffer": "^6.0.3",
"connectkit": "1.4.0",
"ethers": "^5.7.2",
"process": "^0.11.10",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"util": "^0.12.5",
"viem": "^1.0.7",
"wagmi": "^1.2.0"
},
"devDependencies": {
"@types/react": "^18.2.12",
"@types/react-dom": "^18.2.5",
"@vitejs/plugin-react": "^4.0.1",
"typescript": "^5.1.3",
"vite": "^4.3.9"
}
}
6 changes: 6 additions & 0 deletions examples/vite-wagmi-ethers/polyfills.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { Buffer } from 'buffer'
import process from 'process'

window.global = window
window.process = process
window.Buffer = Buffer
88 changes: 88 additions & 0 deletions examples/vite-wagmi-ethers/src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { ConnectKitButton } from 'connectkit'
import { useAccount } from 'wagmi'
import { TokenboundClient } from '@tokenbound/sdk'

import { Account } from './components'

import { useCallback, useEffect } from 'react'
import { useEthersSigner } from './hooks'

export function App() {
const { isConnected, address } = useAccount()
const signer = useEthersSigner({ chainId: 5 })
// or useSigner() from legacy wagmi versions: const { data: signer } = useSigner()

const tokenboundClient = new TokenboundClient({ signer, chainId: 5 })

useEffect(() => {
async function testTokenboundClass() {
const account = await tokenboundClient.getAccount({
tokenContract: '0xe7134a029cd2fd55f678d6809e64d0b6a0caddcb',
tokenId: '9',
})

const preparedExecuteCall = await tokenboundClient.prepareExecuteCall({
account: account,
to: account,
value: 0n,
data: '',
})

const preparedAccount = await tokenboundClient.prepareCreateAccount({
tokenContract: '0xe7134a029cd2fd55f678d6809e64d0b6a0caddcb',
tokenId: '1',
})

console.log('getAccount', account)
console.log('prepareExecuteCall', preparedExecuteCall)
console.log('preparedAccount', preparedAccount)

// if (signer) {
// signer?.sendTransaction(preparedAccount)
// signer?.sendTransaction(preparedExecuteCall)
// }
}

testTokenboundClass()
}, [tokenboundClient])

const createAccount = useCallback(async () => {
if (!tokenboundClient || !address) return
const createAccount = await tokenboundClient.createAccount({
tokenContract: '0xe7134a029cd2fd55f678d6809e64d0b6a0caddcb',
tokenId: '1',
})
}, [tokenboundClient])

const executeCall = useCallback(async () => {
if (!tokenboundClient || !address) return
const executedCall = await tokenboundClient.executeCall({
account: address,
to: address,
value: 0n,
data: '0x',
})
}, [tokenboundClient])

return (
<>
<h1>Ethers 5 Signer + ConnectKit + Vite</h1>
<ConnectKitButton />
{isConnected && <Account />}
{address && (
<div
style={{
display: 'flex',
flexDirection: 'column',
gap: '8px',
margin: '32px 0 0',
maxWidth: '320px',
}}
>
<button onClick={() => executeCall()}>EXECUTE CALL</button>
<button onClick={() => createAccount()}>CREATE ACCOUNT</button>
</div>
)}
</>
)
}
13 changes: 13 additions & 0 deletions examples/vite-wagmi-ethers/src/components/Account.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { useAccount, useEnsName } from 'wagmi'

export function Account() {
const { address } = useAccount()
const { data: ensName } = useEnsName({ address })

return (
<div>
{ensName ?? address}
{ensName ? ` (${address})` : null}
</div>
)
}
1 change: 1 addition & 0 deletions examples/vite-wagmi-ethers/src/components/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { Account } from './Account'
1 change: 1 addition & 0 deletions examples/vite-wagmi-ethers/src/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './useEthersSigner'
27 changes: 27 additions & 0 deletions examples/vite-wagmi-ethers/src/hooks/useEthersSigner.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import * as React from 'react'
import { type WalletClient, useWalletClient } from 'wagmi'
import { providers } from 'ethers'

// Ethers.js Adapters for Wagmi Wallet Client
// https://wagmi.sh/react/ethers-adapters

export function walletClientToSigner(walletClient: WalletClient) {
const { account, chain, transport } = walletClient
const network = {
chainId: chain.id,
name: chain.name,
ensAddress: chain.contracts?.ensRegistry?.address,
}
const provider = new providers.Web3Provider(transport, network)
const signer = provider.getSigner(account.address)
return signer
}

/** Hook to convert a viem Wallet Client to an ethers.js Signer. */
export function useEthersSigner({ chainId }: { chainId?: number } = {}) {
const { data: walletClient } = useWalletClient({ chainId })
return React.useMemo(
() => (walletClient ? walletClientToSigner(walletClient) : undefined),
[walletClient],
)
}
35 changes: 35 additions & 0 deletions examples/vite-wagmi-ethers/src/main.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// import { ConnectKitProvider } from 'connectkit'
// import * as React from 'react'
// import * as ReactDOM from 'react-dom/client'
// import { WagmiConfig } from 'wagmi'

// import { App } from './App'
// import { wagmiClient } from './wagmi'

// ReactDOM.createRoot(document.getElementById('root')!).render(
// <React.StrictMode>
// <WagmiConfig client={wagmiClient}>
// <ConnectKitProvider>
// <App />
// </ConnectKitProvider>
// </WagmiConfig>
// </React.StrictMode>
// )

import { ConnectKitProvider } from 'connectkit'
import * as React from 'react'
import * as ReactDOM from 'react-dom/client'
import { WagmiConfig } from 'wagmi'

import { App } from './App'
import { wagmiConfig } from './wagmi'

ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<WagmiConfig config={wagmiConfig}>
<ConnectKitProvider>
<App />
</ConnectKitProvider>
</WagmiConfig>
</React.StrictMode>
)
28 changes: 28 additions & 0 deletions examples/vite-wagmi-ethers/src/wagmi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// import { getDefaultClient } from "connectkit";
// import { createClient } from "wagmi";
// import { goerli } from "wagmi";

// export const wagmiClient = createClient(
// getDefaultClient({
// autoConnect: true,
// appName: "My wagmi + ConnectKit App",
// chains: [goerli],
// })
// )

import { getDefaultConfig } from "connectkit";
import { createConfig } from "wagmi";
import { goerli } from 'wagmi/chains'

const chains = [goerli]

export const wagmiConfig = createConfig(
getDefaultConfig({
walletConnectProjectId: process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID!,
// alchemyId: process.env.NEXT_PUBLIC_ALCHEMY_API_KEY,
chains,
appName: 'Vite Tokenbound SDK Example',
appDescription: 'Tokenbound SDK Example',
appUrl: 'https://tokenbound.org',
})
)
Loading