Express Backend¶
Start from a simple Express backend. You can use any backend infrastructure or library, but current library support is limited to JavaScript/TypeScript. Install express, @ethsign/sp-sdk, and viem.
import express from "express";
const app = express()
const port = 3000
app.get('/', (req, res) => {
res.send('Hello World!')
})
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
This boilerplate creates a server that listens for requests on port 3000.
Initializing the Sign Protocol client¶
On a backend server, the SDK requires a private key account when you create your SignProtocolClient. Without an account, the client uses window.ethereum, which does not exist in a backend environment. For Sepolia, your code should look like this:
import {
SignProtocolClient,
SpMode,
EvmChains
} from "@ethsign/sp-sdk";
import { privateKeyToAccount } from "viem/accounts";
const privateKey = "0x..."; // account responsible for paying gas fees
const client = new SignProtocolClient(SpMode.OnChain, {
chain: EvmChains.sepolia,
account: privateKeyToAccount(privateKey) // required in backend environments
});
Setting up your controller¶
The controller creates the attestation. For a delegate attestation, it must provide the attestation object and the delegation signature. The user's wallet produces the delegation signature by signing a message; the backend does not generate it. Your controller should look like this:
app.post(
"/delegate",
async (req: Request<{}, {}, { attestation: Attestation; delegationSignature: string }>, res: Response) => {
try {
const { attestation, delegationSignature } = req.body;
const response = await client.createAttestation(attestation, {
delegationSignature
});
res.status(200).json({ message: response });
} catch (error: any) {
res.status(500).json({
error: {
message: error.message
}
});
}
}
);
(Frontend) Generating a delegation signature¶
Implement this section on your frontend. A delegation signature lets a third party upload an attestation on behalf of an attester. The attester must approve (sign) the attestation first, which prevents fraudulent attestations made with their wallet address. Once the user (attester) signs, send the attestation and signature to the backend above. Your frontend code should include the following:
import {
EvmChains,
delegateSignAttestation
} from "@ethsign/sp-sdk";
const schemaId = "0x...";
const attestationData = {
// The fields your schema defines
};
const indexingValue = "0x...";
const res = await delegateSignAttestation(
{
schemaId: schemaId,
data: attestationData,
indexingValue: indexingValue
},
{ chain: EvmChains.sepolia }
);
const attResponse = await fetch(`${YOUR_BACKEND_URL}/delegate`, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({ attestation: res.attestation, delegationSignature: res.delegationSignature })
});
// ...
// You can now use `attResponse` for anything you need in your frontend code
Recap¶
The general flow to create a delegated attestation using a backend:
- Generate the attestation content. You can do this on the frontend (as shown above) or on a dedicated backend, which then sends it to the frontend for step 2.
- Request a delegation signature from the user in a browser.
- Forward the attestation and delegation signature to your dedicated backend.
- Create the attestation, providing the attestation and delegation signature.