Skip to content

Commit 894c8b9

Browse files
committed
feat: smart account utilities
1 parent 7d9f306 commit 894c8b9

File tree

3 files changed

+201
-1
lines changed

3 files changed

+201
-1
lines changed

packages/hypergraph/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,12 @@
2929
"@automerge/automerge": "^2.2.9",
3030
"@automerge/automerge-repo": "=2.0.0-beta.5",
3131
"@effect/experimental": "^0.44.20",
32+
"@graphprotocol/grc-20": "^0.11.5",
3233
"@noble/ciphers": "^1.3.0",
3334
"@noble/curves": "^1.9.0",
3435
"@noble/hashes": "^1.8.0",
3536
"@noble/secp256k1": "^2.2.3",
37+
"@rhinestone/module-sdk": "^0.2.8",
3638
"@serenity-kit/noble-sodium": "^0.2.1",
3739
"@xstate/store": "^3.5.1",
3840
"bs58check": "^4.0.0",
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
import {
2+
OWNABLE_VALIDATOR_ADDRESS,
3+
Session,
4+
encodeSmartSessionSignature,
5+
encodeValidationData,
6+
encodeValidatorNonce,
7+
getAccount,
8+
getEnableSessionDetails,
9+
getOwnableValidator,
10+
getOwnableValidatorMockSignature,
11+
getSmartSessionsValidator,
12+
getSudoPolicy,
13+
} from '@rhinestone/module-sdk';
14+
import { createSmartAccountClient } from 'permissionless';
15+
import { toSafeSmartAccount } from 'permissionless/accounts';
16+
import { erc7579Actions } from 'permissionless/actions/erc7579';
17+
import { createPimlicoClient } from 'permissionless/clients/pimlico';
18+
import { http, type WalletClient, createPublicClient } from 'viem';
19+
import { entryPoint07Address } from 'viem/account-abstraction';
20+
21+
const DEFAULT_RPC_URL = 'https://rpc-geo-genesis-h0q2s21xx8.t.conduit.xyz';
22+
/**
23+
* We provide a fallback API key for gas sponsorship for the duration of the
24+
* Geo Genesis early access period. This API key is gas-limited.
25+
*/
26+
const DEFAULT_API_KEY = 'pim_KqHm63txxhbCYjdDaWaHqH';
27+
const BUNDLER_TRANSPORT_URL_BASE = 'https://api.pimlico.io/v2/80451/rpc?apikey=';
28+
29+
const SAFE_7579_MODULE_ADDRESS = '0x7579EE8307284F293B1927136486880611F20002';
30+
const ERC7579_LAUNCHPAD_ADDRESS = '0x7579011aB74c46090561ea277Ba79D510c6C00ff';
31+
32+
const GEOGENESIS = {
33+
id: Number('80451'),
34+
name: 'Geo Genesis',
35+
nativeCurrency: {
36+
name: 'Ethereum',
37+
symbol: 'ETH',
38+
decimals: 18,
39+
},
40+
rpcUrls: {
41+
default: {
42+
http: [DEFAULT_RPC_URL],
43+
},
44+
public: {
45+
http: [DEFAULT_RPC_URL],
46+
},
47+
},
48+
};
49+
50+
export const getLegacySmartAccountWalletClient = async (
51+
walletClient: WalletClient,
52+
rpcUrl: string = DEFAULT_RPC_URL,
53+
apiKey: string = DEFAULT_API_KEY,
54+
) => {
55+
const transport = http(rpcUrl);
56+
const publicClient = createPublicClient({
57+
transport,
58+
chain: GEOGENESIS,
59+
});
60+
61+
const safeAccount = await toSafeSmartAccount({
62+
client: publicClient,
63+
owners: [walletClient],
64+
entryPoint: {
65+
// optional, defaults to 0.7
66+
address: entryPoint07Address,
67+
version: '0.7',
68+
},
69+
version: '1.4.1',
70+
});
71+
72+
const bundlerTransport = http(`${BUNDLER_TRANSPORT_URL_BASE}${apiKey}`);
73+
const paymasterClient = createPimlicoClient({
74+
transport: bundlerTransport,
75+
chain: GEOGENESIS,
76+
entryPoint: {
77+
address: entryPoint07Address,
78+
version: '0.7',
79+
},
80+
});
81+
82+
const smartAccount = createSmartAccountClient({
83+
chain: GEOGENESIS,
84+
account: safeAccount,
85+
paymaster: paymasterClient,
86+
bundlerTransport,
87+
userOperation: {
88+
estimateFeesPerGas: async () => {
89+
return (await paymasterClient.getUserOperationGasPrice()).fast;
90+
},
91+
},
92+
});
93+
return smartAccount;
94+
};
95+
96+
export const get7579SmartAccountWalletClient = async (
97+
walletClient: WalletClient,
98+
address: string | undefined,
99+
rpcUrl: string = DEFAULT_RPC_URL,
100+
apiKey: string = DEFAULT_API_KEY,
101+
) => {
102+
if (!walletClient.account) {
103+
throw new Error('Wallet client must be an account');
104+
}
105+
106+
const transport = http(rpcUrl);
107+
const publicClient = createPublicClient({
108+
transport,
109+
chain: GEOGENESIS,
110+
});
111+
112+
const ownableValidator = getOwnableValidator({
113+
owners: [walletClient.account.address],
114+
threshold: 1,
115+
});
116+
117+
const safeAccount = await toSafeSmartAccount({
118+
client: publicClient,
119+
address,
120+
owners: [walletClient],
121+
version: '1.4.1',
122+
entryPoint: {
123+
address: entryPoint07Address,
124+
version: '0.7',
125+
},
126+
safe4337ModuleAddress: SAFE_7579_MODULE_ADDRESS,
127+
erc7579LaunchpadAddress: ERC7579_LAUNCHPAD_ADDRESS,
128+
attesters: [],
129+
attestersThreshold: 0,
130+
validators: [
131+
{
132+
address: ownableValidator.address,
133+
context: ownableValidator.initData,
134+
},
135+
],
136+
});
137+
138+
const bundlerTransport = http(`${BUNDLER_TRANSPORT_URL_BASE}${apiKey}`);
139+
const paymasterClient = createPimlicoClient({
140+
transport: bundlerTransport,
141+
chain: GEOGENESIS,
142+
entryPoint: {
143+
address: entryPoint07Address,
144+
version: '0.7',
145+
},
146+
});
147+
148+
const smartAccount = createSmartAccountClient({
149+
chain: GEOGENESIS,
150+
account: safeAccount,
151+
paymaster: paymasterClient,
152+
bundlerTransport,
153+
userOperation: {
154+
estimateFeesPerGas: async () => {
155+
return (await paymasterClient.getUserOperationGasPrice()).fast;
156+
},
157+
},
158+
}).extend(erc7579Actions());
159+
return smartAccount;
160+
};
161+
162+
const updateLegacySmartAccount = async (smartAccount: GeoSmartAccount) => {
163+
// TODO We need to enable the 7579 module and disable the 4337 module
164+
};
165+
166+
const createSmartSession = async (smartAccount: GeoSmartAccount) => {
167+
// TODO
168+
// Check if the smart account has the smart session module enabled
169+
// Enable it if needed
170+
// Create a smart session
171+
// Execute the userOp
172+
};

pnpm-lock.yaml

Lines changed: 27 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)