Ethers
Note that @joyid/ethers
only supports Ethers.js v5.
Integrate your dapp with the JoyID wallet using the JoyID provider API, which enables your dapp to interact with its users' EVM accounts. Axon is a Proof-of-Stake (PoS) and 100% EVM compatible framework that enables developers to build app-chains as Layer 2 of CKB network. We recommend using @joyid/ethers
SDK to easily enable your users to connect to their JoyID wallet with Axon app-chains.
To connect, sign and send the transaction with the user's JoyID, we need to do the following steps:
Step 1: Connect JoyID
import * as React from 'react'
import { JoyIDProvider } from '@joyid/ethers'
import './style.css'
const JOY_ID_URL = 'https://app.joyid.dev'
const AXON_RPC_URL = 'https://axon-rpc.internal.joyid.dev'
export default function App() {
const provider = new JoyIDProvider({
name: 'JoyID EVM Demo',
logo: 'https://fav.farm/๐',
joyidAppURL: JOY_ID_URL,
rpcURL: AXON_RPC_URL,
})
const onConnect = async () => {
try {
const authData = await provider.connect()
console.log(`JoyID user info:`, authData)
} catch (error) {
console.log(error)
}
}
return (
<div>
<h1>Hello JoyID!</h1>
<button onClick={onConnect}>Connect JoyID</button>
</div>
)
}
connect
function, please check the API Reference.Step 2: Sign a challenge
After the connection is complete, we need to add a button
element and listen to the click
event. When the user clicks the button, we will call the signChallenge
function to sign a challenge
with the user's JoyID.
Verify the credential before signing a challenge
import * as React from 'react'
import { JoyIDProvider } from '@joyid/ethers'
import { verifyCredential } from '@joyid/core'
import './style.css'
const JOY_ID_URL = 'https://app.joyid.dev'
const AXON_RPC_URL = 'https://axon-rpc.internal.joyid.dev'
export default function App() {
const [joyidInfo, setJoyidInfo] = React.useState(null)
const [challenge, setChallenge] = React.useState('Sign this for me')
const provider = new JoyIDProvider({
name: 'JoyID EVM Demo',
logo: 'https://fav.farm/๐',
joyidAppURL: JOY_ID_URL,
rpcURL: AXON_RPC_URL,
})
const onConnect = async () => {
try {
const authData = await provider.connect()
setJoyidInfo(authData)
} catch (error) {
console.log(error)
}
}
const onSign = async () => {
const { keyType, address, pubkey, alg } = joyidInfo
if (keyType === 'main_session_key' || keyType === 'sub_session_key') {
const isValid = await verifyCredential(pubkey, address, keyType, alg)
if (!isValid) {
alert('Your key is expired, please re-authenticate with JoyID')
return
}
}
const signer = provider.getSigner(authData.ethAddress)
const res = await signer.signChallenge(challenge())
if (res) {
console.log(`Sign message result: ${res}`)
}
}
return (
<div>
<h1>Hello JoyID!</h1>
{joyidInfo ? null : <button onClick={onConnect}>Connect JoyID</button>}
{joyidInfo ? (
<div>
<textarea value={challenge} onChange={e => setChallenge(e.target.value)} />
<button onClick={onSign}>Sign With JoyID</button>
</div>
) : null}
</div>
)
}
signChallenge
function, please check the API Reference.challenge
vs. message
Step 3: Sign and Send a Transaction
After the connection is complete, we need to add a button
element and listen to the click
event. When the user clicks the button, we will call the signTransaction
and eth_sendRawTransaction
to sign and send a transaction or call the sendTransaction
function to send a transaction directly with the user's JoyID.
import * as React from 'react'
import { JoyIDProvider } from '@joyid/ethers'
import { parseEther } from 'ethers/lib/utils'
import './style.css'
const JOY_ID_URL = 'https://app.joyid.dev'
const AXON_RPC_URL = 'https://axon-rpc.internal.joyid.dev'
export default function App() {
const [joyidInfo, setJoyidInfo] = React.useState(null)
const [toAddress, setToAddress] = React.useState('0xA6eBeCE9938C3e1757bE3024D2296666d6F8Fc49')
const [amount, setAmount] = React.useState('0.01')
const provider = new JoyIDProvider({
name: 'JoyID EVM Demo',
logo: 'https://fav.farm/๐',
joyidAppURL: JOY_ID_URL,
rpcURL: AXON_RPC_URL,
})
const onConnect = async () => {
try {
const authData = await provider.connect()
setJoyidInfo(authData)
} catch (error) {
console.log(error)
}
}
const onSend = async () => {
const signer = provider.getSigner(joyidInfo.ethAddress)
// There are two ways to implement the signing and sending of transactions, the following is way one:
const signedTx = await signer.signTransaction({
to: toAddress,
from: joyidInfo.ethAddress,
value: parseEther(amount).toString(),
})
try {
const txHash = await provider.send('eth_sendRawTransaction', [signedTx])
console.log(`txHash: ${txHash}`)
} catch (e) {
console.error(e)
}
// The following is way two:
// try {
// const tx = await signer.sendTransaction({
// to: toAddress,
// from: joyidInfo.ethAddress,
// value: parseEther(amount).toString(),
// })
// console.log(`txHash: ${txHash}`)
// } catch (e) {
// console.error(e)
// }
}
return (
<div>
<h1>Hello JoyID!</h1>
{joyidInfo ? null : <button onClick={onConnect}>Connect JoyID</button>}
{joyidInfo ? (
<div>
<textarea value={toAddress} onChange={e => setToAddress(e.target.value)} />
<textarea value={amount} onChange={e => setAmount(e.target.value)} />
<button onClick={onSend}>Send</button>
</div>
) : null}
</div>
)
}
signTransaction
vs. sendTransaction
signTransaction
function, please check the API Reference.Try it out
To learn more about the ethers demo, please check the react-ethers and vue-ethers