Skip to content

Commit

Permalink
docs(examples): adds new example to repo (#621)
Browse files Browse the repository at this point in the history
* docs(examples): adds new example to repo

Creates a new example in the repository that demonstrates how to use the
Ethereum Attestation Service with a Defender Relay Signer

* style(imports): use default import of node:process pkg

Use default import of node:process instead of only importing env method
  • Loading branch information
emnul authored Dec 3, 2024
1 parent bd2128f commit 01d227f
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 0 deletions.
23 changes: 23 additions & 0 deletions examples/eas-relayer-signer/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "@openzeppelin/defender-sdk-example-eas-relay-signer",
"version": "1.15.2",
"private": true,
"main": "index.js",
"type": "module",
"scripts": {
"build": "tsc",
"start": "node dist/index.js"
},
"author": "OpenZeppelin Defender <[email protected]>",
"license": "MIT",
"description": "An example of using the Ethereum Attestation Service with a Defender Relay Signer",
"devDependencies": {
"typescript": "^5.6.3"
},
"dependencies": {
"@ethereum-attestation-service/eas-sdk": "^2.7.0",
"@openzeppelin/defender-sdk": "1.15.2",
"dotenv": "^16.4.5",
"ethers": "^6.13.4"
}
}
57 changes: 57 additions & 0 deletions examples/eas-relayer-signer/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { EAS, NO_EXPIRATION, SchemaEncoder, TransactionSigner } from '@ethereum-attestation-service/eas-sdk';

import dotenv from 'dotenv';
dotenv.config();
import { Agent } from 'node:https';
import process from 'node:process';

import { Defender, DefenderOptions } from '@openzeppelin/defender-sdk';
import { TypeDataSigner } from '@ethereum-attestation-service/eas-sdk/dist/offchain/typed-data-handler.js';

export const EASContractAddress = '0xC2679fBD37d54388Ce493F1DB75320D236e1815e'; // Sepolia v0.26

const creds = {
relayerApiKey: process.env.RELAYER_API_KEY,
relayerApiSecret: process.env.RELAYER_API_SECRET,
//optional https config to keep connection alive. You can pass any configs that are accepted by https.Agent
httpsAgent: new Agent({ keepAlive: true }),
};

const validForSeconds = 60 * 60 * 24;
const client = new Defender(creds as DefenderOptions);
const provider = client.relaySigner.getProvider({ ethersVersion: 'v6' });
const signer = await client.relaySigner.getSigner(provider, {
speed: 'fast',
validForSeconds,
ethersVersion: 'v6',
});

// Initialize EAS with the EAS contract address on whichever chain where your schema is defined
const eas = new EAS(EASContractAddress);
eas.connect(provider as unknown as TransactionSigner);

const offchain = await eas.getOffchain();

// Initialize SchemaEncoder with the schema string
// Note these values are sample values and should be filled with actual values
// Code samples can be found when viewing each schema on easscan.org
const schemaEncoder = new SchemaEncoder('uint256 eventId, uint8 voteIndex');
const encodedData = schemaEncoder.encodeData([
{ name: 'eventId', value: 1, type: 'uint256' },
{ name: 'voteIndex', value: 1, type: 'uint8' },
]);

const offchainAttestation = await offchain.signOffchainAttestation(
{
recipient: '0xFD50b031E778fAb33DfD2Fc3Ca66a1EeF0652165',
expirationTime: NO_EXPIRATION, // Unix timestamp of when attestation expires (0 for no expiration)
time: BigInt(Math.floor(Date.now() / 1000)), // Unix timestamp of current time
revocable: true, // Be aware that if your schema is not revocable, this MUST be false
schema: '0xb16fa048b0d597f5a821747eba64efa4762ee5143e9a80600d0005386edfc995',
refUID: '0x0000000000000000000000000000000000000000000000000000000000000000',
data: encodedData,
},
signer as TypeDataSigner,
);

console.log(offchainAttestation);
34 changes: 34 additions & 0 deletions examples/eas-relayer-signer/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"compilerOptions": {
/* Language and Environment */
"target": "es2022" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,

/* Modules */
"module": "nodenext" /* Specify what module code is generated. */,
"rootDir": "src" /* Specify the root folder within your source files. */,
"moduleResolution": "nodenext" /* Specify how TypeScript looks up a file from a given module specifier. */,
"baseUrl": ".",
"resolveJsonModule": true /* Enable importing .json files. */,

/* JavaScript Support */
"allowJs": true /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */,

/* Emit */
"declaration": true /* Generate .d.ts files from TypeScript and JavaScript files in your project. */,
"sourceMap": true /* Create source map files for emitted JavaScript files. */,
"outDir": "dist" /* Specify an output folder for all emitted files. */,
"importHelpers": true /* Allow importing helper functions from tslib once per project, instead of including them per-file. */,

/* Interop Constraints */
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,

/* Type Checking */
"strict": true /* Enable all strict type-checking options. */,

/* Completeness */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
},
"include": ["src/**/*"],
"exclude": ["dist", "node_modules"]
}

0 comments on commit 01d227f

Please sign in to comment.