Skip to content

Commit 4901ff4

Browse files
committed
wip on server side
1 parent 3145bb6 commit 4901ff4

File tree

4 files changed

+32
-19
lines changed

4 files changed

+32
-19
lines changed

apps/connect/src/routes/login.lazy.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import { type ConnectedWallet, useIdentityToken, usePrivy, useWallets } from '@p
55
import { createLazyFileRoute, useRouter } from '@tanstack/react-router';
66
import { useCallback, useEffect, useState } from 'react';
77
import { type WalletClient, createWalletClient, custom } from 'viem';
8-
import { mainnet } from 'viem/chains';
98

9+
const CHAIN = import.meta.env.VITE_HYPERGRAPH_CHAIN === 'geogenesis' ? GEOGENESIS : GEO_TESTNET;
1010
const syncServerUri = import.meta.env.VITE_HYPERGRAPH_SYNC_SERVER_ORIGIN;
1111
const storage = localStorage;
1212

@@ -45,10 +45,10 @@ function Login() {
4545
if (!address) {
4646
return;
4747
}
48-
const chain = import.meta.env.VITE_HYPERGRAPH_CHAIN === 'geogenesis' ? GEOGENESIS : GEO_TESTNET;
48+
4949
const rpcUrl = import.meta.env.VITE_HYPERGRAPH_RPC_URL;
5050

51-
await Connect.login({ walletClient, signer, syncServerUri, storage, identityToken, rpcUrl, chain });
51+
await Connect.login({ walletClient, signer, syncServerUri, storage, identityToken, rpcUrl, chain: CHAIN });
5252
},
5353
[identityToken, signMessage],
5454
);
@@ -66,7 +66,7 @@ function Login() {
6666
const embeddedWallet = wallets.find((wallet) => wallet.walletClientType === 'privy') || wallets[0];
6767
const privyProvider = await embeddedWallet.getEthereumProvider();
6868
const walletClient = createWalletClient({
69-
chain: mainnet,
69+
chain: CHAIN,
7070
transport: custom(privyProvider),
7171
});
7272

apps/server/src/index.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { parse } from 'node:url';
22
import { Identity, Inboxes, Messages, SpaceEvents, Utils } from '@graphprotocol/hypergraph';
3+
import { GEOGENESIS, GEO_TESTNET } from '@graphprotocol/hypergraph/connect/smart-account';
34
import { bytesToHex, randomBytes } from '@noble/hashes/utils.js';
45
import cors from 'cors';
56
import { Effect, Exit, Schema } from 'effect';
@@ -41,6 +42,8 @@ const decodeRequestMessage = Schema.decodeUnknownEither(Messages.RequestMessage)
4142
const webSocketServer = new WebSocketServer({ noServer: true });
4243
const PORT = process.env.PORT !== undefined ? Number.parseInt(process.env.PORT) : 3030;
4344
const app = express();
45+
const CHAIN = process.env.HYPERGRAPH_CHAIN === 'geogenesis' ? GEOGENESIS : GEO_TESTNET;
46+
const RPC_URL = process.env.HYPERGRAPH_RPC_URL ?? CHAIN.rpcUrls.default.http[0];
4447

4548
type AuthenticatedRequest = Request & { accountAddress?: string };
4649

@@ -166,19 +169,18 @@ app.post('/connect/identity', async (req, res) => {
166169
console.log('POST connect/identity');
167170
try {
168171
const idToken = req.headers['privy-id-token'];
169-
const accountAddressPrivy = await getAddressByPrivyToken(Array.isArray(idToken) ? idToken[0] : idToken);
172+
const signerAddress = await getAddressByPrivyToken(Array.isArray(idToken) ? idToken[0] : idToken);
170173
const message = Schema.decodeUnknownSync(Messages.RequestConnectCreateIdentity)(req.body);
171174
const accountAddress = message.keyBox.accountAddress;
172-
if (accountAddressPrivy !== accountAddress) {
173-
res.status(401).send('Unauthorized');
174-
return;
175-
}
175+
176176
if (
177177
!Identity.verifyIdentityOwnership(
178178
accountAddress,
179179
message.signaturePublicKey,
180180
message.accountProof,
181181
message.keyProof,
182+
CHAIN,
183+
RPC_URL,
182184
)
183185
) {
184186
console.log('Ownership proof is invalid');
@@ -188,6 +190,7 @@ app.post('/connect/identity', async (req, res) => {
188190

189191
try {
190192
await createIdentity({
193+
signerAddress,
191194
accountAddress,
192195
ciphertext: message.keyBox.ciphertext,
193196
nonce: message.keyBox.nonce,

packages/hypergraph/src/connect/smart-account.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import {
2020
getUsageLimitPolicy,
2121
getValueLimitPolicy,
2222
} from '@rhinestone/module-sdk';
23-
import { privateKeyToAccount, toAccount } from 'viem/accounts';
23+
import { privateKeyToAccount } from 'viem/accounts';
2424

2525
import { MAINNET, TESTNET } from '@graphprotocol/grc-20/contracts';
2626
import { type SmartAccountClient, createSmartAccountClient, encodeInstallModule } from 'permissionless';
@@ -61,8 +61,8 @@ import {
6161
smartSessionsAbi,
6262
} from './abis.js';
6363

64-
const DEFAULT_RPC_URL = 'https://rpc-geo-genesis-h0q2s21xx8.t.conduit.xyz';
65-
const TESTNET_RPC_URL = 'https://rpc-geo-test-zc16z3tcvf.t.conduit.xyz';
64+
export const DEFAULT_RPC_URL = 'https://rpc-geo-genesis-h0q2s21xx8.t.conduit.xyz';
65+
export const TESTNET_RPC_URL = 'https://rpc-geo-test-zc16z3tcvf.t.conduit.xyz';
6666
/**
6767
* We provide a fallback API key for gas sponsorship for the duration of the
6868
* Geo Genesis early access period. This API key is gas-limited.
@@ -74,7 +74,6 @@ const SAFE_7579_MODULE_ADDRESS = '0x7579EE8307284F293B1927136486880611F20002';
7474
const SAFE_4337_MODULE_ADDRESS = '0x75cf11467937ce3F2f357CE24ffc3DBF8fD5c226';
7575
const ERC7579_LAUNCHPAD_ADDRESS = '0x7579011aB74c46090561ea277Ba79D510c6C00ff';
7676

77-
// TODO: add address for testnet
7877
const SPACE_FACTORY_ADDRESS: Record<string, Hex> = {
7978
'80451': MAINNET.DAO_FACTORY_ADDRESS,
8079
'19411': TESTNET.DAO_FACTORY_ADDRESS,
@@ -109,7 +108,7 @@ const PERSONAL_SPACE_FUNCTIONS = [
109108
'submitNewEditor',
110109
'submitRemoveEditor',
111110
];
112-
// TODO: add details for testnet too
111+
113112
export const GEOGENESIS = {
114113
id: Number('80451'),
115114
name: 'Geo Genesis',

packages/hypergraph/src/identity/prove-ownership.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
import { type Hex, verifyMessage } from 'viem';
1+
import { http, type Account, type Chain, type Hex, createPublicClient, verifyMessage } from 'viem';
22
import { privateKeyToAccount } from 'viem/accounts';
33

4+
import type { SmartAccountClient } from 'permissionless';
5+
import { DEFAULT_RPC_URL, GEOGENESIS } from '../connect/smart-account.js';
46
import { publicKeyToAddress } from '../utils/index.js';
5-
import type { IdentityKeys, Signer } from './types.js';
7+
import type { IdentityKeys } from './types.js';
68

79
export const getAccountProofMessage = (accountAddress: string, publicKey: string): string => {
810
return `This message proves I am the owner of the account ${accountAddress} and the public key ${publicKey}`;
@@ -13,14 +15,17 @@ export const getKeyProofMessage = (accountAddress: string, publicKey: string): s
1315
};
1416

1517
export const proveIdentityOwnership = async (
16-
signer: Signer,
18+
smartAccountClient: SmartAccountClient,
1719
accountAddress: string,
1820
keys: IdentityKeys,
1921
): Promise<{ accountProof: string; keyProof: string }> => {
2022
const publicKey = keys.signaturePublicKey;
2123
const accountProofMessage = getAccountProofMessage(accountAddress, publicKey);
2224
const keyProofMessage = getKeyProofMessage(accountAddress, publicKey);
23-
const accountProof = await signer.signMessage(accountProofMessage);
25+
const accountProof = await smartAccountClient.signMessage({
26+
account: smartAccountClient.account as Account,
27+
message: accountProofMessage,
28+
});
2429
const account = privateKeyToAccount(keys.signaturePrivateKey as Hex);
2530
const keyProof = await account.signMessage({ message: keyProofMessage });
2631
return { accountProof, keyProof };
@@ -31,10 +36,16 @@ export const verifyIdentityOwnership = async (
3136
publicKey: string,
3237
accountProof: string,
3338
keyProof: string,
39+
chain: Chain = GEOGENESIS,
40+
rpcUrl: string = DEFAULT_RPC_URL,
3441
): Promise<boolean> => {
3542
const accountProofMessage = getAccountProofMessage(accountAddress, publicKey);
3643
const keyProofMessage = getKeyProofMessage(accountAddress, publicKey);
37-
const validAccountProof = await verifyMessage({
44+
const publicClient = createPublicClient({
45+
chain,
46+
transport: http(rpcUrl),
47+
});
48+
const validAccountProof = await publicClient.verifyMessage({
3849
address: accountAddress as Hex,
3950
message: accountProofMessage,
4051
signature: accountProof as Hex,

0 commit comments

Comments
 (0)