Skip to content

Commit 00c1965

Browse files
committed
coherent state
1 parent 628b6b8 commit 00c1965

File tree

6 files changed

+2118
-54
lines changed

6 files changed

+2118
-54
lines changed

package.json

+7-1
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,11 @@
4242
"next": "~14.0.4",
4343
"vercel": "~32.4.1"
4444
},
45-
"packageManager": "[email protected]"
45+
"packageManager": "[email protected]",
46+
"dependencies": {
47+
"@ethereum-attestation-service/eas-sdk": "^1.5.0",
48+
"axios": "^1.6.8",
49+
"ethers": "^6.11.1",
50+
"moment-timezone": "^0.5.45"
51+
}
4652
}

packages/nextjs/app/api/vote/route.ts

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
; import axios from 'axios';
2+
import moment from 'moment-timezone';
3+
4+
class CryptoClock {
5+
private ethBlockTime: number;
6+
7+
constructor() {
8+
this.ethBlockTime = 13.5; // Average Ethereum block time in seconds
9+
}
10+
11+
async getEthBlockNumber(): Promise<number> {
12+
try {
13+
const response = await axios.get('https://api.etherscan.io/api?module=proxy&action=eth_blockNumber');
14+
return parseInt(response.data.result, 16);
15+
} catch (error) {
16+
throw new Error('Failed to fetch Ethereum block number');
17+
}
18+
}
19+
20+
async convertTimeToEthBlock(time: string, timeZone: string): Promise<number> {
21+
const currentTime = moment().tz(timeZone);
22+
const targetTime = moment.tz(time, timeZone);
23+
const timeDiff = targetTime.diff(currentTime, 'seconds');
24+
const blockDiff = Math.floor(timeDiff / this.ethBlockTime);
25+
const currentBlock = await this.getEthBlockNumber();
26+
const targetBlock = currentBlock + blockDiff;
27+
return targetBlock;
28+
}
29+
30+
convertEthBlocksToTime(ethBlocks: number, timeZone: string): string {
31+
const ethSeconds = ethBlocks * this.ethBlockTime;
32+
const currentTime = moment().tz(timeZone);
33+
const targetTime = currentTime.add(ethSeconds, 'seconds');
34+
return targetTime.format();
35+
}
36+
}
37+
38+
export default CryptoClock;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import React from 'react';
2+
import { EAS, SchemaEncoder } from "@ethereum-attestation-service/eas-sdk";
3+
import { useBlockNumber } from "wagmi";
4+
import { useSigner } from "~~/utils/wagmi-utils"
5+
import CryptoClock from './ClockComponent';
6+
7+
async function exampleUsage() {
8+
const clock = new CryptoClock();
9+
10+
// Convert time to Ethereum block
11+
const time = '2023-03-23 15:30:00';
12+
const timeZone = 'America/New_York';
13+
const ethBlock = await clock.convertTimeToEthBlock(time, timeZone);
14+
console.log(`Time ${time} (${timeZone}) corresponds to Ethereum block ${ethBlock}`);
15+
16+
// Convert Ethereum blocks to time
17+
const ethBlocks = 100;
18+
const targetTime = clock.convertEthBlocksToTime(ethBlocks, timeZone);
19+
console.log(`${ethBlocks} Ethereum blocks from now is ${targetTime} (${timeZone})`);
20+
}
21+
22+
exampleUsage();
23+
24+
const CreateSession = () => {
25+
const signer = useSigner();
26+
const numba = useBlockNumber();
27+
const easContractAddress = "0x4200000000000000000000000000000000000021";
28+
const eas = new EAS(easContractAddress);
29+
const [title, setTitle] = React.useState("");
30+
if (!signer) return null;
31+
eas.connect(signer);
32+
const Attest = async () => {
33+
const schemaUID = "0x4e36b4880c16106a434c64c4217d519f98711ec82b44c09b0d3e10971bbb11e8";
34+
// Signer must be an ethers-like signer.
35+
// Initialize SchemaEncoder with the schema string
36+
const schemaEncoder = new SchemaEncoder("string sesionTitle,uint32 startBlock");
37+
const encodedData = schemaEncoder.encodeData([
38+
{ name: "sesionTitle", value: "", type: "string" },
39+
{ name: "startBlock", value: numba, type: "uint32" }
40+
]);
41+
const tx = await eas.attest({
42+
schema: schemaUID,
43+
data: {
44+
recipient: "0x0000000000000000000000000000000000000000",
45+
expirationTime: 0n,
46+
revocable: true, // Be aware that if your schema is not revocable, this MUST be false
47+
data: encodedData,
48+
},
49+
});
50+
const newAttestationUID = await tx.wait();
51+
console.log("New attestation UID:", newAttestationUID);
52+
53+
}
54+
55+
56+
return (<></>);
57+
}
58+
59+
export default CreateSession;

packages/nextjs/utils/wagmi-utils.ts

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import { type PublicClient, type WalletClient } from "@wagmi/core";
2+
import { type HttpTransport } from "viem";
3+
import { useEffect, useState } from "react";
4+
import { usePublicClient, useWalletClient } from "wagmi";
5+
import { ethers, JsonRpcProvider, JsonRpcSigner } from "ethers";
6+
7+
export function publicClientToProvider(publicClient: PublicClient) {
8+
const { chain, transport } = publicClient;
9+
const network = {
10+
chainId: chain.id,
11+
name: chain.name,
12+
ensAddress: chain.contracts?.ensRegistry?.address,
13+
};
14+
if (transport.type === "fallback")
15+
return new ethers.FallbackProvider(
16+
(transport.transports as ReturnType<HttpTransport>[]).map(
17+
({ value }) => new ethers.JsonRpcProvider(value?.url, network)
18+
)
19+
);
20+
return new ethers.JsonRpcProvider(transport.url, network);
21+
}
22+
23+
export async function walletClientToSigner(walletClient: WalletClient) {
24+
const { account, chain, transport } = walletClient;
25+
const network = {
26+
chainId: chain.id,
27+
name: chain.name,
28+
ensAddress: chain.contracts?.ensRegistry?.address,
29+
};
30+
const provider = new ethers.BrowserProvider(transport, network);
31+
return provider.getSigner(account.address);
32+
}
33+
34+
export function useSigner() {
35+
const { data: walletClient } = useWalletClient();
36+
37+
const [signer, setSigner] = useState<JsonRpcSigner | undefined>(undefined);
38+
useEffect(() => {
39+
async function getSigner() {
40+
if (!walletClient) return;
41+
42+
const tmpSigner = await walletClientToSigner(walletClient);
43+
44+
setSigner(tmpSigner);
45+
}
46+
47+
getSigner();
48+
}, [walletClient]);
49+
return signer;
50+
}
51+
52+
export function useProvider() {
53+
const publicClient = usePublicClient();
54+
55+
const [provider, setProvider] = useState<JsonRpcProvider | undefined>(
56+
undefined
57+
);
58+
useEffect(() => {
59+
async function getSigner() {
60+
if (!publicClient) return;
61+
62+
const tmpProvider = publicClientToProvider(publicClient);
63+
64+
setProvider(tmpProvider as JsonRpcProvider);
65+
}
66+
67+
getSigner();
68+
}, [publicClient]);
69+
return provider;
70+
}

0 commit comments

Comments
 (0)