Skip to content

Commit 3220cbf

Browse files
authored
feat: viem session sdk (#226)
1 parent 67cb83d commit 3220cbf

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+5941
-256
lines changed

.markdownlint-cli2.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ config:
33
code_blocks: false
44
line_length: 80
55
tables: false
6+
headings: false # Allow long headings
67
MD033: false
78
MD024: false
89
MD029: false
910
gitignore: true
1011
ignores:
1112
- ".github/**/*.md"
13+
- "**/docs/**/*.md" # Skip strict line length for detailed documentation

cspell-config/cspell-misc.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ dockerized
1313
ethereum
1414
sepolia
1515
foundryup
16+
unpermitted
1617

1718
// examples/bank-demo
1819
ctap

cspell-config/cspell-rust.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// package names
2+
tokio
3+
serde

cspell.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
"dict-zksync",
5858
"dict-packages",
5959
"dict-misc",
60+
"dict-rust",
6061
"dict-sol"
6162
],
6263
"dictionaryDefinitions": [
@@ -80,6 +81,11 @@
8081
"addWords": true,
8182
"path": "./cspell-config/cspell-sol.txt"
8283
},
84+
{
85+
"name": "dict-rust",
86+
"addWords": true,
87+
"path": "./cspell-config/cspell-rust.txt"
88+
},
8389
{
8490
"name": "dict-circom",
8591
"addWords": true,
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
<template>
2+
<div class="bg-indigo-50 p-4 rounded-lg mb-4 border border-indigo-200">
3+
<h2 class="text-xl font-semibold mb-3">
4+
Session Configuration
5+
</h2>
6+
7+
<label class="flex items-center mb-2">
8+
<input
9+
v-model="config!.deployWithSession"
10+
type="checkbox"
11+
class="mr-2"
12+
:disabled="isDeployed"
13+
>
14+
<span>
15+
Deploy with Session Support
16+
<span
17+
v-if="isDeployed"
18+
class="text-xs text-gray-500 ml-1"
19+
>(Set before deployment)</span>
20+
</span>
21+
</label>
22+
<p
23+
v-if="config?.deployWithSession"
24+
class="text-xs text-gray-600 mb-3 ml-6"
25+
>
26+
Session validator will be pre-installed during account deployment
27+
</p>
28+
29+
<label class="flex items-center mb-2">
30+
<input
31+
v-model="config!.enabled"
32+
type="checkbox"
33+
class="mr-2"
34+
>
35+
Enable Session Configuration
36+
</label>
37+
38+
<div
39+
v-if="config?.enabled"
40+
class="space-y-2"
41+
>
42+
<div>
43+
<label class="block text-sm font-medium mb-1">Session Validator Address</label>
44+
<input
45+
v-model="config!.validatorAddress"
46+
type="text"
47+
placeholder="0x..."
48+
class="w-full p-2 border rounded"
49+
readonly
50+
>
51+
<p class="text-xs text-gray-500 mt-1">
52+
Loaded from contracts.json
53+
</p>
54+
</div>
55+
56+
<div>
57+
<label class="block text-sm font-medium mb-1">Session Signer (auto-generated)</label>
58+
<input
59+
:value="config?.sessionSigner"
60+
type="text"
61+
readonly
62+
class="w-full p-2 border rounded bg-gray-100"
63+
>
64+
<p class="text-xs text-gray-500 mt-1">
65+
This address will be authorized to send transactions on behalf of the smart account
66+
</p>
67+
</div>
68+
69+
<div>
70+
<label class="block text-sm font-medium mb-1">Expires At (timestamp)</label>
71+
<input
72+
v-model.number="config!.expiresAt"
73+
type="number"
74+
class="w-full p-2 border rounded"
75+
>
76+
<p class="text-xs text-gray-500 mt-1">
77+
Unix timestamp (default: {{ formatTimestamp(config!.expiresAt) }})
78+
</p>
79+
</div>
80+
81+
<div>
82+
<label class="block text-sm font-medium mb-1">Max Fee (wei)</label>
83+
<input
84+
v-model="config!.feeLimit"
85+
type="text"
86+
class="w-full p-2 border rounded"
87+
>
88+
<p class="text-xs text-gray-500 mt-1">
89+
Maximum fee the session can spend (1 ETH = 1000000000000000000 wei)
90+
</p>
91+
</div>
92+
93+
<div>
94+
<label class="block text-sm font-medium mb-1">Allowed Recipient (address)</label>
95+
<input
96+
v-model="config!.allowedRecipient"
97+
type="text"
98+
placeholder="0x..."
99+
class="w-full p-2 border rounded"
100+
>
101+
<p class="text-xs text-gray-500 mt-1">
102+
The session validator currently requires an explicit transfer policy target. Set this to the recipient you will send to.
103+
</p>
104+
</div>
105+
</div>
106+
</div>
107+
</template>
108+
109+
<script setup lang="ts">
110+
import { watch } from "vue";
111+
import { privateKeyToAccount, generatePrivateKey } from "viem/accounts";
112+
113+
interface SessionConfig {
114+
enabled: boolean;
115+
deployWithSession: boolean;
116+
validatorAddress: string;
117+
sessionPrivateKey: string;
118+
sessionSigner: string;
119+
expiresAt: number;
120+
feeLimit: string;
121+
// Optional: Restrict transfers to a single recipient (required by current validator)
122+
allowedRecipient?: string;
123+
}
124+
125+
defineProps<{
126+
isDeployed?: boolean;
127+
}>();
128+
129+
const config = defineModel<SessionConfig>();
130+
131+
// Format timestamp to readable date
132+
function formatTimestamp(timestamp: number): string {
133+
return new Date(timestamp * 1000).toLocaleDateString("en-US", {
134+
year: "numeric",
135+
month: "short",
136+
day: "numeric",
137+
});
138+
}
139+
140+
// Auto-generate session signer on enable or deployWithSession
141+
watch(
142+
() => [config.value?.enabled, config.value?.deployWithSession],
143+
([enabled, deployWithSession]) => {
144+
if ((enabled || deployWithSession) && !config.value?.sessionPrivateKey) {
145+
const privateKey = generatePrivateKey();
146+
if (config.value) {
147+
config.value.sessionPrivateKey = privateKey;
148+
const account = privateKeyToAccount(privateKey);
149+
config.value.sessionSigner = account.address;
150+
}
151+
}
152+
},
153+
);
154+
</script>

0 commit comments

Comments
 (0)