Ethers
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