@tenprotocol/session-keys 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,299 @@
1
+ # @tenprotocol/session-keys
2
+
3
+ Framework-agnostic session key management for TEN Protocol. Provides seamless transaction execution without wallet popups.
4
+
5
+ ## Features
6
+
7
+ - 🔑 **Session Key Management** - Create, fund, activate, and manage session keys
8
+ - 🚀 **Framework Agnostic** - Works with Ethers, Wagmi, Viem, or any EIP-1193 provider
9
+ - ⚡ **No Wallet Popups** - Execute transactions seamlessly once session key is active
10
+ - ðŸŠķ **Lightweight** - Only one dependency (`rlp`)
11
+ - 🔒 **Type Safe** - Full TypeScript support
12
+ - ⚛ïļ **React Ready** - Optional React hooks included
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install @tenprotocol/session-keys
18
+ ```
19
+
20
+ ## Quick Start
21
+
22
+ ```typescript
23
+ import {
24
+ createSessionKey,
25
+ fundSessionKey,
26
+ activateSessionKey,
27
+ sendTransaction
28
+ } from '@tenprotocol/session-keys'
29
+
30
+ // 1. Setup session key (one time)
31
+ const provider = window.ethereum // or any EIP-1193 provider
32
+ const userAddress = '0x...' // Connected user address
33
+
34
+ const sessionKey = await createSessionKey(provider)
35
+ await fundSessionKey(sessionKey, '0.025', provider, userAddress)
36
+ await activateSessionKey(provider)
37
+
38
+ // 2. Execute transactions without wallet popups
39
+ await sendTransaction({
40
+ to: '0x...',
41
+ data: '0x...', // Your encoded contract call
42
+ value: '0x0'
43
+ }, provider)
44
+ ```
45
+
46
+ ## API Reference
47
+
48
+ ### Session Key Management
49
+
50
+ #### `createSessionKey(provider)`
51
+ Creates a new session key or retrieves existing one.
52
+
53
+ ```typescript
54
+ const sessionKey = await createSessionKey(provider)
55
+ // Returns: "0x742d35Cc6635C0532925a3b8D29187cf8b4E87f1"
56
+ ```
57
+
58
+ #### `fundSessionKey(sessionKeyAddress, amount, provider, userAddress)`
59
+ Funds the session key with ETH for transaction fees.
60
+
61
+ ```typescript
62
+ await fundSessionKey(sessionKey, '0.025', provider, userAddress)
63
+ ```
64
+
65
+ #### `activateSessionKey(provider)`
66
+ Activates the session key for transaction execution.
67
+
68
+ ```typescript
69
+ await activateSessionKey(provider)
70
+ ```
71
+
72
+ #### `deactivateSessionKey(provider)`
73
+ Deactivates the session key.
74
+
75
+ ```typescript
76
+ await deactivateSessionKey(provider)
77
+ ```
78
+
79
+ #### `deleteSessionKey(provider)`
80
+ Permanently deletes the session key.
81
+
82
+ ```typescript
83
+ await deleteSessionKey(provider)
84
+ ```
85
+
86
+ #### `cleanupSessionKey(provider)`
87
+ Deactivates and deletes the session key in one call.
88
+
89
+ ```typescript
90
+ await cleanupSessionKey(provider)
91
+ ```
92
+
93
+ ### Transaction Execution
94
+
95
+ #### `sendTransaction(txParams, provider)`
96
+ Executes a transaction using the active session key.
97
+
98
+ ```typescript
99
+ await sendTransaction({
100
+ to: '0x...',
101
+ data: '0x...',
102
+ value: '0x0',
103
+ // Optional gas parameters
104
+ gasLimit: 100000,
105
+ maxFeePerGas: '20000000000',
106
+ maxPriorityFeePerGas: '1000000000'
107
+ }, provider)
108
+ ```
109
+
110
+ ### State Management
111
+
112
+ #### State Getters
113
+ ```typescript
114
+ import {
115
+ getSessionKey,
116
+ getIsActive,
117
+ getBalance,
118
+ getIsLoading,
119
+ getError
120
+ } from '@tenprotocol/session-keys'
121
+
122
+ const sessionKey = getSessionKey() // string | null
123
+ const isActive = getIsActive() // boolean
124
+ const balance = getBalance() // { eth: number, estimatedTransactions: number } | null
125
+ const isLoading = getIsLoading() // boolean
126
+ const error = getError() // Error | null
127
+ ```
128
+
129
+ #### State Subscription
130
+ ```typescript
131
+ import { subscribeToState } from '@tenprotocol/session-keys'
132
+
133
+ const unsubscribe = subscribeToState((state) => {
134
+ console.log('Session key state updated:', state)
135
+ })
136
+
137
+ // Later: unsubscribe()
138
+ ```
139
+
140
+ ## React Integration
141
+
142
+ ```typescript
143
+ import { useSessionKeyState } from '@tenprotocol/session-keys/react'
144
+
145
+ function MyComponent() {
146
+ const { sessionKey, isActive, balance, isLoading, error } = useSessionKeyState()
147
+
148
+ return (
149
+ <div>
150
+ <p>Session Key: {sessionKey}</p>
151
+ <p>Active: {isActive ? 'Yes' : 'No'}</p>
152
+ <p>Balance: {balance?.eth} ETH</p>
153
+ {isLoading && <p>Loading...</p>}
154
+ {error && <p>Error: {error.message}</p>}
155
+ </div>
156
+ )
157
+ }
158
+ ```
159
+
160
+ ## Framework Examples
161
+
162
+ ### With Ethers.js
163
+ ```typescript
164
+ import { ethers } from 'ethers'
165
+ import { sendTransaction } from '@tenprotocol/session-keys'
166
+
167
+ const provider = new ethers.BrowserProvider(window.ethereum)
168
+ const contract = new ethers.Contract(address, abi, provider)
169
+
170
+ // Encode function call
171
+ const data = contract.interface.encodeFunctionData('transfer', [recipient, amount])
172
+
173
+ // Execute with session key
174
+ await sendTransaction({
175
+ to: address,
176
+ data: data
177
+ }, provider)
178
+ ```
179
+
180
+ ### With Viem
181
+ ```typescript
182
+ import { encodeFunctionData } from 'viem'
183
+ import { sendTransaction } from '@tenprotocol/session-keys'
184
+
185
+ const data = encodeFunctionData({
186
+ abi: erc20Abi,
187
+ functionName: 'transfer',
188
+ args: [recipient, amount]
189
+ })
190
+
191
+ await sendTransaction({
192
+ to: tokenAddress,
193
+ data: data
194
+ }, walletClient)
195
+ ```
196
+
197
+ ### With Wagmi
198
+ ```typescript
199
+ import { prepareWriteContract } from 'wagmi'
200
+ import { sendTransaction } from '@tenprotocol/session-keys'
201
+
202
+ const { config } = await prepareWriteContract({
203
+ address: tokenAddress,
204
+ abi: erc20Abi,
205
+ functionName: 'transfer',
206
+ args: [recipient, amount]
207
+ })
208
+
209
+ await sendTransaction({
210
+ to: config.address,
211
+ data: config.data
212
+ }, walletClient)
213
+ ```
214
+
215
+ ## Complete Example
216
+
217
+ ```typescript
218
+ import {
219
+ createSessionKey,
220
+ fundSessionKey,
221
+ activateSessionKey,
222
+ sendTransaction,
223
+ getSessionKey,
224
+ getIsActive
225
+ } from '@tenprotocol/session-keys'
226
+
227
+ async function setupAndUseSessionKey() {
228
+ const provider = window.ethereum
229
+ const [userAddress] = await provider.request({ method: 'eth_accounts' })
230
+
231
+ // 1. Setup session key
232
+ const sessionKey = await createSessionKey(provider)
233
+ console.log('Created session key:', sessionKey)
234
+
235
+ // 2. Fund with ETH for transaction fees
236
+ await fundSessionKey(sessionKey, '0.025', provider, userAddress)
237
+ console.log('Funded session key')
238
+
239
+ // 3. Activate for transaction execution
240
+ await activateSessionKey(provider)
241
+ console.log('Activated session key')
242
+
243
+ // 4. Now execute transactions without wallet popups
244
+ const tokenTransferData = '0xa9059cbb...' // Your encoded contract call
245
+
246
+ const txHash = await sendTransaction({
247
+ to: '0x...', // Token contract address
248
+ data: tokenTransferData,
249
+ value: '0x0'
250
+ }, provider)
251
+
252
+ console.log('Transaction sent:', txHash)
253
+ }
254
+ ```
255
+
256
+ ## Error Handling
257
+
258
+ ```typescript
259
+ try {
260
+ await sendTransaction({
261
+ to: '0x...',
262
+ data: '0x...'
263
+ }, provider)
264
+ } catch (error) {
265
+ if (error.message.includes('No active session key')) {
266
+ // Handle session key not ready
267
+ console.log('Please create and activate a session key first')
268
+ } else if (error.message.includes('Insufficient')) {
269
+ // Handle insufficient funds
270
+ console.log('Session key needs more ETH funding')
271
+ } else {
272
+ // Handle other errors
273
+ console.error('Transaction failed:', error)
274
+ }
275
+ }
276
+ ```
277
+
278
+ ## TypeScript Support
279
+
280
+ Full TypeScript support with complete type definitions:
281
+
282
+ ```typescript
283
+ import type {
284
+ EIP1193Provider,
285
+ TransactionParams,
286
+ SessionKeyState
287
+ } from '@tenprotocol/session-keys'
288
+
289
+ const txParams: TransactionParams = {
290
+ to: '0x...',
291
+ data: '0x...',
292
+ value: '0x0',
293
+ gasLimit: 100000
294
+ }
295
+ ```
296
+
297
+ ## License
298
+
299
+ MIT
@@ -0,0 +1,30 @@
1
+ interface EIP1193Provider {
2
+ request(args: {
3
+ method: string;
4
+ params?: any[];
5
+ }): Promise<any>;
6
+ on?(event: string, listener: (...args: any[]) => void): void;
7
+ removeListener?(event: string, listener: (...args: any[]) => void): void;
8
+ }
9
+ interface TransactionParams {
10
+ to: string;
11
+ data: string;
12
+ value?: string;
13
+ nonce?: number;
14
+ gasLimit?: number;
15
+ maxFeePerGas?: string;
16
+ maxPriorityFeePerGas?: string;
17
+ }
18
+ interface SessionKeyState {
19
+ sessionKey: string | null;
20
+ isActive: boolean;
21
+ balance: {
22
+ eth: number;
23
+ estimatedTransactions: number;
24
+ } | null;
25
+ isLoading: boolean;
26
+ error: Error | null;
27
+ }
28
+ type StateSubscriber = (state: SessionKeyState) => void;
29
+
30
+ export type { EIP1193Provider as E, SessionKeyState as S, TransactionParams as T, StateSubscriber as a };
@@ -0,0 +1,30 @@
1
+ interface EIP1193Provider {
2
+ request(args: {
3
+ method: string;
4
+ params?: any[];
5
+ }): Promise<any>;
6
+ on?(event: string, listener: (...args: any[]) => void): void;
7
+ removeListener?(event: string, listener: (...args: any[]) => void): void;
8
+ }
9
+ interface TransactionParams {
10
+ to: string;
11
+ data: string;
12
+ value?: string;
13
+ nonce?: number;
14
+ gasLimit?: number;
15
+ maxFeePerGas?: string;
16
+ maxPriorityFeePerGas?: string;
17
+ }
18
+ interface SessionKeyState {
19
+ sessionKey: string | null;
20
+ isActive: boolean;
21
+ balance: {
22
+ eth: number;
23
+ estimatedTransactions: number;
24
+ } | null;
25
+ isLoading: boolean;
26
+ error: Error | null;
27
+ }
28
+ type StateSubscriber = (state: SessionKeyState) => void;
29
+
30
+ export type { EIP1193Provider as E, SessionKeyState as S, TransactionParams as T, StateSubscriber as a };
@@ -0,0 +1,20 @@
1
+ import { E as EIP1193Provider, T as TransactionParams, S as SessionKeyState, a as StateSubscriber } from './index-mYMQzYjE.mjs';
2
+
3
+ declare const createSessionKey: (provider: EIP1193Provider) => Promise<string>;
4
+ declare const fundSessionKey: (sessionKeyAddress: string, amount: string, provider: EIP1193Provider, userAddress: string) => Promise<string>;
5
+ declare const activateSessionKey: (provider: EIP1193Provider) => Promise<void>;
6
+ declare const deactivateSessionKey: (provider: EIP1193Provider) => Promise<void>;
7
+ declare const deleteSessionKey: (provider: EIP1193Provider) => Promise<void>;
8
+ declare const cleanupSessionKey: (provider: EIP1193Provider) => Promise<void>;
9
+
10
+ declare const sendTransaction: (txParams: TransactionParams, provider: EIP1193Provider) => Promise<string>;
11
+
12
+ declare const getState: () => SessionKeyState;
13
+ declare const subscribeToState: (callback: StateSubscriber) => (() => void);
14
+ declare const getSessionKey: () => string | null;
15
+ declare const getIsActive: () => boolean;
16
+ declare const getBalance: () => SessionKeyState["balance"];
17
+ declare const getIsLoading: () => boolean;
18
+ declare const getError: () => Error | null;
19
+
20
+ export { EIP1193Provider, SessionKeyState, StateSubscriber, TransactionParams, activateSessionKey, cleanupSessionKey, createSessionKey, deactivateSessionKey, deleteSessionKey, fundSessionKey, getBalance, getError, getIsActive, getIsLoading, getSessionKey, getState, sendTransaction, subscribeToState };
@@ -0,0 +1,20 @@
1
+ import { E as EIP1193Provider, T as TransactionParams, S as SessionKeyState, a as StateSubscriber } from './index-mYMQzYjE.js';
2
+
3
+ declare const createSessionKey: (provider: EIP1193Provider) => Promise<string>;
4
+ declare const fundSessionKey: (sessionKeyAddress: string, amount: string, provider: EIP1193Provider, userAddress: string) => Promise<string>;
5
+ declare const activateSessionKey: (provider: EIP1193Provider) => Promise<void>;
6
+ declare const deactivateSessionKey: (provider: EIP1193Provider) => Promise<void>;
7
+ declare const deleteSessionKey: (provider: EIP1193Provider) => Promise<void>;
8
+ declare const cleanupSessionKey: (provider: EIP1193Provider) => Promise<void>;
9
+
10
+ declare const sendTransaction: (txParams: TransactionParams, provider: EIP1193Provider) => Promise<string>;
11
+
12
+ declare const getState: () => SessionKeyState;
13
+ declare const subscribeToState: (callback: StateSubscriber) => (() => void);
14
+ declare const getSessionKey: () => string | null;
15
+ declare const getIsActive: () => boolean;
16
+ declare const getBalance: () => SessionKeyState["balance"];
17
+ declare const getIsLoading: () => boolean;
18
+ declare const getError: () => Error | null;
19
+
20
+ export { EIP1193Provider, SessionKeyState, StateSubscriber, TransactionParams, activateSessionKey, cleanupSessionKey, createSessionKey, deactivateSessionKey, deleteSessionKey, fundSessionKey, getBalance, getError, getIsActive, getIsLoading, getSessionKey, getState, sendTransaction, subscribeToState };
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";var p=Object.defineProperty;var W=Object.getOwnPropertyDescriptor;var j=Object.getOwnPropertyNames;var J=Object.prototype.hasOwnProperty;var X=(e,t)=>{for(var r in t)p(e,r,{get:t[r],enumerable:!0})},z=(e,t,r,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of j(t))!J.call(e,n)&&n!==r&&p(e,n,{get:()=>t[n],enumerable:!(s=W(t,n))||s.enumerable});return e};var Q=e=>z(p({},"__esModule",{value:!0}),e);var te={};X(te,{activateSessionKey:()=>B,cleanupSessionKey:()=>k,createSessionKey:()=>G,deactivateSessionKey:()=>H,deleteSessionKey:()=>O,fundSessionKey:()=>D,getBalance:()=>L,getError:()=>F,getIsActive:()=>K,getIsLoading:()=>v,getSessionKey:()=>I,getState:()=>P,sendTransaction:()=>R,subscribeToState:()=>A});module.exports=Q(te);var E={SESSION_KEY_CREATE:"0x0000000000000000000000000000000000000003",SESSION_KEY_RETRIEVE:"0x0000000000000000000000000000000000000007",SESSION_KEY_ACTIVATE:"0x0000000000000000000000000000000000000004",SESSION_KEY_DEACTIVATE:"0x0000000000000000000000000000000000000005",SESSION_KEY_DELETE:"0x0000000000000000000000000000000000000006",SESSION_KEY_EXECUTE:"0x0000000000000000000000000000000000000008"},u=443,T={PRIORITY_FEE_PERCENTILES:[25,50,75],FEE_HISTORY_BLOCKS:10,BASE_FEE_MULTIPLIERS:{LOW:1.1,MEDIUM:1.2,HIGH:1.5}};var c={sessionKey:null,isActive:!1,balance:null,isLoading:!1,error:null},w=new Set,x=!1;try{let e=localStorage.getItem("ten-session-key-state");if(e){let t=JSON.parse(e);c={...c,sessionKey:t.sessionKey,isActive:t.isActive}}}catch(e){console.warn("Failed to load persisted state:",e)}var P=()=>({...c}),o=async e=>{for(;x;)await new Promise(t=>setTimeout(t,50));try{if(x=!0,c={...c,...e},"sessionKey"in e||"isActive"in e)try{localStorage.setItem("ten-session-key-state",JSON.stringify({sessionKey:c.sessionKey,isActive:c.isActive}))}catch(t){console.warn("Failed to persist state:",t)}w.forEach(t=>{try{t(P())}catch(r){console.error("Error in state subscriber:",r)}})}finally{x=!1}},A=e=>(w.add(e),()=>{w.delete(e)}),b=()=>{try{localStorage.removeItem("ten-session-key-state")}catch(e){console.warn("Failed to clear persisted state:",e)}},I=()=>c.sessionKey,K=()=>c.isActive,L=()=>c.balance,v=()=>c.isLoading,F=()=>c.error;var g=e=>{let t=BigInt(e).toString(16);return t=t||"0","0x"+t},N=e=>{let t=e.replace("0x",""),r=new Uint8Array(t.length/2);for(let s=0;s<t.length;s+=2)r[s/2]=parseInt(t.substr(s,2),16);return r};var C=e=>{let[t,r=""]=e.split("."),s=r.padEnd(18,"0").slice(0,18);return BigInt(t+s)};var y=null,Z=e=>{y&&y();let t=()=>{o({isActive:!1,error:new Error("Provider disconnected")})},r=()=>{o({isActive:!1,error:new Error("Chain changed")})};e.on?.("disconnect",t),e.on?.("chainChanged",r),y=()=>{e.removeListener?.("disconnect",t),e.removeListener?.("chainChanged",r)}},h=async e=>{let t=await e.request({method:"eth_chainId"});if(parseInt(t,16)!==u)throw new Error("Session Keys is only for TEN chain, please add or switch to TEN.")},G=async e=>{try{o({isLoading:!0,error:null}),Z(e),await h(e),console.log("\u{1F511} Creating session key on TEN network..."),console.log("\u{1F511} Using address:",E.SESSION_KEY_CREATE);let t=await e.request({method:"eth_getStorageAt",params:[E.SESSION_KEY_CREATE,"0x0","latest"]});if(console.log("\u{1F511} Create response:",t),!t||t==="0x0000000000000000000000000000000000000000000000000000000000000000"){console.log("\u{1F511} Creation failed, trying to retrieve existing session key...");let s=await e.request({method:"eth_getStorageAt",params:[E.SESSION_KEY_RETRIEVE,"0x0","latest"]});if(console.log("\u{1F511} Existing key response:",s),s&&s!=="0x0000000000000000000000000000000000000000000000000000000000000000"){let n="0x"+s.slice(-40);return console.log("\u{1F511} Retrieved existing session key:",n),o({sessionKey:n,isLoading:!1}),n}throw new Error("Failed to create session key - both creation and retrieval returned empty response")}let r="0x"+t.slice(-40);return console.log("\u{1F511} Created new session key:",r),o({sessionKey:r,isLoading:!1}),r}catch(t){console.error("\u{1F511} Session key creation error:",t);let r=t instanceof Error?t:new Error("Unknown error");throw o({error:r,isLoading:!1}),r}},D=async(e,t,r,s)=>{try{o({isLoading:!0,error:null}),await h(r),console.log("\u{1F4B0} Funding session key:",e,"with",t,"ETH");let n=C(t),a=g(n),l=await r.request({method:"eth_sendTransaction",params:[{to:e,value:a,from:s}]});console.log("\u{1F4B0} Funding transaction sent:",l);let d=async()=>{let S=await r.request({method:"eth_getTransactionReceipt",params:[l]});return S?(console.log("\u{1F4B0} Funding confirmed!"),S):(await new Promise(f=>setTimeout(f,2e3)),d())};return await d(),o({isLoading:!1}),l}catch(n){let a=n instanceof Error?n:new Error("Unknown error");throw o({error:a,isLoading:!1}),a}},B=async e=>{try{o({isLoading:!0,error:null}),await h(e),await e.request({method:"eth_getStorageAt",params:[E.SESSION_KEY_ACTIVATE,"0x0","latest"]}),o({isActive:!0,isLoading:!1})}catch(t){let r=t instanceof Error?t:new Error("Activation failed");throw o({error:r,isLoading:!1}),r}},H=async e=>{try{o({isLoading:!0,error:null}),await h(e),await e.request({method:"eth_getStorageAt",params:[E.SESSION_KEY_DEACTIVATE,"0x0","latest"]}),o({isActive:!1,isLoading:!1})}catch(t){let r=t instanceof Error?t:new Error("Deactivation failed");throw o({error:r,isLoading:!1}),r}},O=async e=>{try{o({isLoading:!0,error:null}),await h(e),await e.request({method:"eth_getStorageAt",params:[E.SESSION_KEY_DELETE,"0x0","latest"]}),b(),y&&(y(),y=null),o({sessionKey:null,isActive:!1,balance:null,isLoading:!1})}catch(t){let r=t instanceof Error?t:new Error("Deletion failed");throw o({error:r,isLoading:!1}),r}},k=async e=>{try{o({isLoading:!0,error:null}),await h(e),await e.request({method:"eth_getStorageAt",params:[E.SESSION_KEY_DEACTIVATE,"0x0","latest"]}),await e.request({method:"eth_getStorageAt",params:[E.SESSION_KEY_DELETE,"0x0","latest"]}),o({sessionKey:null,isActive:!1,balance:null,isLoading:!1})}catch(t){let r=t instanceof Error?t:new Error("Cleanup failed");throw o({error:r,isLoading:!1}),r}};var U=require("rlp");var $=async e=>{let t=await e.request({method:"eth_chainId"});if(parseInt(t,16)!==u)throw new Error("Session Keys is only for TEN chain, please add or switch to TEN.")},ee=async(e,t="MEDIUM")=>{let{BASE_FEE_MULTIPLIERS:r}=T;try{let s=await e.request({method:"eth_feeHistory",params:[1,"latest",[]]});if(console.log("Fee history response:",s),!s?.baseFeePerGas?.[0])throw new Error("Invalid fee history response");let n=BigInt(s.baseFeePerGas[0]);console.log("Base fee:",n.toString());let a=BigInt(1e8),l=r[t],d=BigInt(Math.floor(Number(n)*l))+a;return console.log("Priority fee:",a.toString()),console.log("Max fee:",d.toString()),{maxFeePerGas:d,maxPriorityFeePerGas:a}}catch(s){console.warn("Error getting fee history, using fallback values:",s);let n=BigInt(1e9),a=BigInt(1e8),l=r[t];return{maxFeePerGas:BigInt(Math.floor(Number(n)*l))+a,maxPriorityFeePerGas:a}}},R=async(e,t)=>{try{o({isLoading:!0,error:null}),await $(t);let r=I();if(!r)throw new Error("No active session key. Create and activate a session key first.");let s=await t.request({method:"eth_chainId"}),n=parseInt(s,16),a;if(e.nonce!==void 0)a=e.nonce;else{let i=await t.request({method:"eth_getTransactionCount",params:[r,"latest"]});a=parseInt(i,16)}let l,d;if(e.maxFeePerGas&&e.maxPriorityFeePerGas)l=BigInt(e.maxFeePerGas),d=BigInt(e.maxPriorityFeePerGas);else{let i=await ee(t,"MEDIUM");l=i.maxFeePerGas,d=i.maxPriorityFeePerGas}let S;if(e.gasLimit)S=e.gasLimit;else{let i=await t.request({method:"eth_estimateGas",params:[{to:e.to,data:e.data,value:e.value||"0x0",from:r}]});S=parseInt(i,16)}let f=[g(n),a===0?"0x":g(a),g(d),g(l),g(S),e.to.toLowerCase(),e.value?.toLowerCase()||"0x0",e.data?.toLowerCase()||"0x",[],"0x","0x","0x"].map(i=>typeof i=="string"&&!i.startsWith("0x")?"0x"+i:i),m=(0,U.encode)(f),_;if(m&&typeof m=="object"&&"length"in m)_=Array.from(m).map(V=>V.toString(16).padStart(2,"0")).join("");else throw new Error("Unexpected RLP encoding result");let q=new Uint8Array([2,...N("0x"+_)]),Y=btoa(String.fromCharCode(...q)),M=await t.request({method:"eth_getStorageAt",params:[E.SESSION_KEY_EXECUTE,Y,"latest"]});return o({isLoading:!1}),M}catch(r){let s=r instanceof Error?r:new Error("Transaction failed");throw o({error:s,isLoading:!1}),s}};0&&(module.exports={activateSessionKey,cleanupSessionKey,createSessionKey,deactivateSessionKey,deleteSessionKey,fundSessionKey,getBalance,getError,getIsActive,getIsLoading,getSessionKey,getState,sendTransaction,subscribeToState});
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/utils/constants.ts","../src/core/state.ts","../src/utils/encoding.ts","../src/core/sessionKey.ts","../src/core/transaction.ts"],"sourcesContent":["// Core functionality\nexport {\n createSessionKey,\n fundSessionKey,\n activateSessionKey,\n deactivateSessionKey,\n deleteSessionKey,\n cleanupSessionKey\n } from './core/sessionKey'\n \n // Transaction execution\n export { sendTransaction } from './core/transaction'\n \n // State management\n export {\n getState,\n getSessionKey,\n getIsActive,\n getBalance,\n getIsLoading,\n getError,\n subscribeToState\n } from './core/state'\n \n // Types\n export type {\n EIP1193Provider,\n TransactionParams,\n SessionKeyState,\n StateSubscriber\n } from './types'","export const TEN_ADDRESSES = {\n SESSION_KEY_CREATE: '0x0000000000000000000000000000000000000003',\n SESSION_KEY_RETRIEVE: '0x0000000000000000000000000000000000000007',\n SESSION_KEY_ACTIVATE: '0x0000000000000000000000000000000000000004',\n SESSION_KEY_DEACTIVATE: '0x0000000000000000000000000000000000000005',\n SESSION_KEY_DELETE: '0x0000000000000000000000000000000000000006',\n SESSION_KEY_EXECUTE: '0x0000000000000000000000000000000000000008'\n} as const\n\nexport const TEN_CHAIN_ID = 443\n\nexport const DEFAULT_GAS_SETTINGS = {\n // Use percentiles for different network conditions\n PRIORITY_FEE_PERCENTILES: [25, 50, 75],\n // Number of blocks to look back for fee estimation\n FEE_HISTORY_BLOCKS: 10,\n // Base fee multipliers for different network conditions\n BASE_FEE_MULTIPLIERS: {\n LOW: 1.1, // Low priority\n MEDIUM: 1.2, // Medium priority (default)\n HIGH: 1.5 // High priority\n }\n} as const","import type { SessionKeyState, StateSubscriber } from '../types'\n\n// Internal state\nlet state: SessionKeyState = {\n sessionKey: null,\n isActive: false,\n balance: null,\n isLoading: false,\n error: null\n}\n\n// Subscribers\nconst subscribers = new Set<StateSubscriber>()\n\n// Simple mutex for state updates\nlet isUpdating = false\n\n// Load persisted state on init\ntry {\n const persisted = localStorage.getItem('ten-session-key-state')\n if (persisted) {\n const parsed = JSON.parse(persisted)\n state = {\n ...state,\n sessionKey: parsed.sessionKey,\n isActive: parsed.isActive\n }\n }\n} catch (error) {\n console.warn('Failed to load persisted state:', error)\n}\n\nexport const getState = (): SessionKeyState => ({ ...state })\n\nexport const updateState = async (updates: Partial<SessionKeyState>): Promise<void> => {\n // Wait if another update is in progress\n while (isUpdating) {\n await new Promise(resolve => setTimeout(resolve, 50))\n }\n \n try {\n isUpdating = true\n state = { ...state, ...updates }\n \n // Persist key state changes\n if ('sessionKey' in updates || 'isActive' in updates) {\n try {\n localStorage.setItem('ten-session-key-state', JSON.stringify({\n sessionKey: state.sessionKey,\n isActive: state.isActive\n }))\n } catch (error) {\n console.warn('Failed to persist state:', error)\n }\n }\n\n // Notify all subscribers\n subscribers.forEach(callback => {\n try {\n callback(getState())\n } catch (error) {\n console.error('Error in state subscriber:', error)\n }\n })\n } finally {\n isUpdating = false\n }\n}\n\nexport const subscribeToState = (callback: StateSubscriber): (() => void) => {\n subscribers.add(callback)\n return () => {\n subscribers.delete(callback)\n }\n}\n\nexport const clearPersistedState = (): void => {\n try {\n localStorage.removeItem('ten-session-key-state')\n } catch (error) {\n console.warn('Failed to clear persisted state:', error)\n }\n}\n\n// State getters\nexport const getSessionKey = (): string | null => state.sessionKey\nexport const getIsActive = (): boolean => state.isActive\nexport const getBalance = (): SessionKeyState['balance'] => state.balance\nexport const getIsLoading = (): boolean => state.isLoading\nexport const getError = (): Error | null => state.error","export const toHex = (value: number | bigint | string): string => {\n // Convert to hex string and remove leading zeros\n let hexStr = BigInt(value).toString(16)\n // Ensure at least one digit\n hexStr = hexStr || '0'\n // Add 0x prefix\n return '0x' + hexStr\n}\n\nexport const hexToBytes = (hex: string): Uint8Array => {\n const cleanHex = hex.replace('0x', '')\n const bytes = new Uint8Array(cleanHex.length / 2)\n for (let i = 0; i < cleanHex.length; i += 2) {\n bytes[i / 2] = parseInt(cleanHex.substr(i, 2), 16)\n }\n return bytes\n}\n\nexport const bytesToHex = (bytes: Uint8Array): string => {\n return '0x' + Array.from(bytes)\n .map(b => b.toString(16).padStart(2, '0'))\n .join('')\n}\n\nexport const parseEther = (value: string): bigint => {\n const [whole, decimal = ''] = value.split('.')\n const paddedDecimal = decimal.padEnd(18, '0').slice(0, 18)\n return BigInt(whole + paddedDecimal)\n}\n\nexport const formatEther = (wei: bigint): number => {\n const ethString = wei.toString()\n if (ethString.length <= 18) {\n return parseFloat('0.' + ethString.padStart(18, '0'))\n }\n const wholePart = ethString.slice(0, -18)\n const decimalPart = ethString.slice(-18)\n return parseFloat(wholePart + '.' + decimalPart)\n}\n\nexport const estimateTransactions = (ethBalance: number): number => {\n // Rough estimate: each transaction costs ~0.005 ETH\n return Math.floor(ethBalance / 0.005)\n}","import type { EIP1193Provider } from '../types'\nimport { TEN_ADDRESSES, TEN_CHAIN_ID } from '../utils/constants'\nimport { updateState, clearPersistedState } from './state'\nimport { parseEther, toHex, formatEther, estimateTransactions } from '../utils/encoding'\n\n// Track provider event listeners\nlet providerCleanup: (() => void) | null = null\n\nconst setupProviderListeners = (provider: EIP1193Provider) => {\n if (providerCleanup) {\n providerCleanup()\n }\n\n const handleDisconnect = () => {\n updateState({ \n isActive: false,\n error: new Error('Provider disconnected')\n })\n }\n\n const handleChainChanged = () => {\n updateState({ \n isActive: false,\n error: new Error('Chain changed')\n })\n }\n\n provider.on?.('disconnect', handleDisconnect)\n provider.on?.('chainChanged', handleChainChanged)\n\n providerCleanup = () => {\n provider.removeListener?.('disconnect', handleDisconnect)\n provider.removeListener?.('chainChanged', handleChainChanged)\n }\n}\n\nconst checkTenNetwork = async (provider: EIP1193Provider): Promise<void> => {\n const chainId = await provider.request({ method: 'eth_chainId' })\n const chainIdInt = parseInt(chainId, 16)\n \n if (chainIdInt !== TEN_CHAIN_ID) {\n throw new Error('Session Keys is only for TEN chain, please add or switch to TEN.')\n }\n}\n\nexport const createSessionKey = async (provider: EIP1193Provider): Promise<string> => {\n try {\n updateState({ isLoading: true, error: null })\n\n // Setup provider listeners\n setupProviderListeners(provider)\n\n // Check if connected to TEN network\n await checkTenNetwork(provider)\n\n console.log('🔑 Creating session key on TEN network...')\n console.log('🔑 Using address:', TEN_ADDRESSES.SESSION_KEY_CREATE)\n\n // Try to create a new session key\n const response = await provider.request({\n method: 'eth_getStorageAt',\n params: [\n TEN_ADDRESSES.SESSION_KEY_CREATE,\n '0x0',\n 'latest'\n ]\n })\n\n console.log('🔑 Create response:', response)\n\n if (!response || response === '0x0000000000000000000000000000000000000000000000000000000000000000') {\n console.log('🔑 Creation failed, trying to retrieve existing session key...')\n \n // If creation failed, try to retrieve existing session key\n const existingKey = await provider.request({\n method: 'eth_getStorageAt',\n params: [\n TEN_ADDRESSES.SESSION_KEY_RETRIEVE,\n '0x0',\n 'latest'\n ]\n })\n\n console.log('🔑 Existing key response:', existingKey)\n\n if (existingKey && existingKey !== '0x0000000000000000000000000000000000000000000000000000000000000000') {\n const sessionKeyAddress = '0x' + existingKey.slice(-40) // Extract address from response\n console.log('🔑 Retrieved existing session key:', sessionKeyAddress)\n updateState({ \n sessionKey: sessionKeyAddress,\n isLoading: false \n })\n return sessionKeyAddress\n }\n\n throw new Error('Failed to create session key - both creation and retrieval returned empty response')\n }\n\n const sessionKeyAddress = '0x' + response.slice(-40) // Extract address from response\n console.log('🔑 Created new session key:', sessionKeyAddress)\n updateState({ \n sessionKey: sessionKeyAddress,\n isLoading: false \n })\n\n return sessionKeyAddress\n } catch (error) {\n console.error('🔑 Session key creation error:', error)\n const err = error instanceof Error ? error : new Error('Unknown error')\n updateState({ error: err, isLoading: false })\n throw err\n }\n}\n\nexport const fundSessionKey = async (\n sessionKeyAddress: string,\n amount: string,\n provider: EIP1193Provider,\n userAddress: string\n): Promise<string> => {\n try {\n updateState({ isLoading: true, error: null })\n\n // Check if connected to TEN network\n await checkTenNetwork(provider)\n\n console.log('💰 Funding session key:', sessionKeyAddress, 'with', amount, 'ETH')\n\n // Convert amount to hex\n const valueInWei = parseEther(amount)\n const valueHex = toHex(valueInWei)\n\n // Send transaction\n const txHash = await provider.request({\n method: 'eth_sendTransaction',\n params: [{\n to: sessionKeyAddress,\n value: valueHex,\n from: userAddress\n }]\n })\n\n console.log('💰 Funding transaction sent:', txHash)\n\n // Monitor transaction confirmation\n const checkTx = async () => {\n const receipt = await provider.request({\n method: 'eth_getTransactionReceipt',\n params: [txHash]\n })\n if (receipt) {\n console.log('💰 Funding confirmed!')\n return receipt\n }\n // Check again in 2 seconds\n await new Promise(resolve => setTimeout(resolve, 2000))\n return checkTx()\n }\n\n await checkTx()\n updateState({ isLoading: false })\n return txHash\n\n } catch (error) {\n const err = error instanceof Error ? error : new Error('Unknown error')\n updateState({ error: err, isLoading: false })\n throw err\n }\n}\n\nexport const activateSessionKey = async (provider: EIP1193Provider): Promise<void> => {\n try {\n updateState({ isLoading: true, error: null })\n\n // Check if connected to TEN network\n await checkTenNetwork(provider)\n\n await provider.request({\n method: 'eth_getStorageAt',\n params: [\n TEN_ADDRESSES.SESSION_KEY_ACTIVATE,\n '0x0',\n 'latest'\n ]\n })\n\n updateState({ \n isActive: true,\n isLoading: false \n })\n\n } catch (error) {\n const err = error instanceof Error ? error : new Error('Activation failed')\n updateState({ error: err, isLoading: false })\n throw err\n }\n}\n\nexport const deactivateSessionKey = async (provider: EIP1193Provider): Promise<void> => {\n try {\n updateState({ isLoading: true, error: null })\n\n // Check if connected to TEN network\n await checkTenNetwork(provider)\n\n await provider.request({\n method: 'eth_getStorageAt',\n params: [\n TEN_ADDRESSES.SESSION_KEY_DEACTIVATE,\n '0x0',\n 'latest'\n ]\n })\n\n updateState({ \n isActive: false,\n isLoading: false \n })\n\n } catch (error) {\n const err = error instanceof Error ? error : new Error('Deactivation failed')\n updateState({ error: err, isLoading: false })\n throw err\n }\n}\n\nexport const deleteSessionKey = async (provider: EIP1193Provider): Promise<void> => {\n try {\n updateState({ isLoading: true, error: null })\n\n // Check if connected to TEN network\n await checkTenNetwork(provider)\n\n await provider.request({\n method: 'eth_getStorageAt',\n params: [\n TEN_ADDRESSES.SESSION_KEY_DELETE,\n '0x0',\n 'latest'\n ]\n })\n\n // Clear persisted state when deleting\n clearPersistedState()\n \n // Remove provider listeners\n if (providerCleanup) {\n providerCleanup()\n providerCleanup = null\n }\n\n updateState({ \n sessionKey: null,\n isActive: false,\n balance: null,\n isLoading: false \n })\n\n } catch (error) {\n const err = error instanceof Error ? error : new Error('Deletion failed')\n updateState({ error: err, isLoading: false })\n throw err\n }\n}\n\nexport const cleanupSessionKey = async (provider: EIP1193Provider): Promise<void> => {\n try {\n updateState({ isLoading: true, error: null })\n\n // Check if connected to TEN network\n await checkTenNetwork(provider)\n\n // First deactivate\n await provider.request({\n method: 'eth_getStorageAt',\n params: [\n TEN_ADDRESSES.SESSION_KEY_DEACTIVATE,\n '0x0',\n 'latest'\n ]\n })\n\n // Then delete\n await provider.request({\n method: 'eth_getStorageAt',\n params: [\n TEN_ADDRESSES.SESSION_KEY_DELETE,\n '0x0',\n 'latest'\n ]\n })\n\n updateState({ \n sessionKey: null,\n isActive: false,\n balance: null,\n isLoading: false \n })\n\n } catch (error) {\n const err = error instanceof Error ? error : new Error('Cleanup failed')\n updateState({ error: err, isLoading: false })\n throw err\n }\n}\n\n// Helper function to update balance\nconst updateBalance = async (sessionKeyAddress: string, provider: EIP1193Provider): Promise<void> => {\n try {\n const balanceHex = await provider.request({\n method: 'eth_getBalance',\n params: [sessionKeyAddress, 'latest']\n })\n\n const balanceWei = BigInt(balanceHex)\n const ethBalance = formatEther(balanceWei)\n \n updateState({\n balance: {\n eth: ethBalance,\n estimatedTransactions: estimateTransactions(ethBalance)\n }\n })\n } catch (error) {\n console.warn('Failed to update balance:', error)\n }\n}","import { encode as rlpEncode } from 'rlp'\nimport type { EIP1193Provider, TransactionParams } from '../types'\nimport { TEN_ADDRESSES, TEN_CHAIN_ID, DEFAULT_GAS_SETTINGS } from '../utils/constants'\nimport { toHex, hexToBytes } from '../utils/encoding'\nimport { getSessionKey, updateState } from './state'\n\nconst checkTenNetwork = async (provider: EIP1193Provider): Promise<void> => {\n const chainId = await provider.request({ method: 'eth_chainId' })\n const chainIdInt = parseInt(chainId, 16)\n \n if (chainIdInt !== TEN_CHAIN_ID) {\n throw new Error('Session Keys is only for TEN chain, please add or switch to TEN.')\n }\n}\n\nconst calculateGasFees = async (\n provider: EIP1193Provider,\n priority: 'LOW' | 'MEDIUM' | 'HIGH' = 'MEDIUM'\n): Promise<{ maxFeePerGas: bigint; maxPriorityFeePerGas: bigint }> => {\n const { BASE_FEE_MULTIPLIERS } = DEFAULT_GAS_SETTINGS\n \n try {\n // Get fee history for last block\n const feeHistory = await provider.request({\n method: 'eth_feeHistory',\n params: [\n 1, // just get latest block\n 'latest',\n [] // no percentiles needed since we don't get rewards\n ]\n })\n\n console.log('Fee history response:', feeHistory)\n\n if (!feeHistory?.baseFeePerGas?.[0]) {\n throw new Error('Invalid fee history response')\n }\n\n // Get base fee from response\n const baseFee = BigInt(feeHistory.baseFeePerGas[0])\n console.log('Base fee:', baseFee.toString())\n \n // Use a fixed priority fee since the network doesn't provide reward data\n const priorityFeePerGas = BigInt(100000000) // 0.1 gwei\n \n // Calculate max fee using appropriate multiplier\n const multiplier = BASE_FEE_MULTIPLIERS[priority]\n const maxFeePerGas = BigInt(Math.floor(Number(baseFee) * multiplier)) + priorityFeePerGas\n console.log('Priority fee:', priorityFeePerGas.toString())\n console.log('Max fee:', maxFeePerGas.toString())\n\n return { maxFeePerGas, maxPriorityFeePerGas: priorityFeePerGas }\n } catch (error) {\n console.warn('Error getting fee history, using fallback values:', error)\n // Fallback to fixed values if anything goes wrong\n const baseFeePerGas = BigInt(1000000000) // 1 gwei\n const priorityFeePerGas = BigInt(100000000) // 0.1 gwei\n const multiplier = BASE_FEE_MULTIPLIERS[priority]\n const maxFeePerGas = BigInt(Math.floor(Number(baseFeePerGas) * multiplier)) + priorityFeePerGas\n return { maxFeePerGas, maxPriorityFeePerGas: priorityFeePerGas }\n }\n}\n\nexport const sendTransaction = async (\n txParams: TransactionParams,\n provider: EIP1193Provider\n): Promise<string> => {\n try {\n updateState({ isLoading: true, error: null })\n\n // Check if connected to TEN network\n await checkTenNetwork(provider)\n\n const sessionKeyAddress = getSessionKey()\n if (!sessionKeyAddress) {\n throw new Error('No active session key. Create and activate a session key first.')\n }\n\n // 1. Get chain ID\n const chainId = await provider.request({ method: 'eth_chainId' })\n const chainIdInt = parseInt(chainId, 16)\n\n // 2. Get nonce\n let nonce: number\n if (txParams.nonce !== undefined) {\n nonce = txParams.nonce\n } else {\n const nonceHex = await provider.request({\n method: 'eth_getTransactionCount',\n params: [sessionKeyAddress, 'latest']\n })\n nonce = parseInt(nonceHex, 16)\n }\n\n // 3. Calculate gas fees\n let maxFeePerGas: bigint\n let maxPriorityFeePerGas: bigint\n\n if (txParams.maxFeePerGas && txParams.maxPriorityFeePerGas) {\n maxFeePerGas = BigInt(txParams.maxFeePerGas)\n maxPriorityFeePerGas = BigInt(txParams.maxPriorityFeePerGas)\n } else {\n // Use dynamic fee calculation\n const gasFees = await calculateGasFees(provider, 'MEDIUM')\n maxFeePerGas = gasFees.maxFeePerGas\n maxPriorityFeePerGas = gasFees.maxPriorityFeePerGas\n }\n\n // 4. Get gas limit (use provided or estimate)\n let gasLimit: number\n if (txParams.gasLimit) {\n gasLimit = txParams.gasLimit\n } else {\n const gasEstimate = await provider.request({\n method: 'eth_estimateGas',\n params: [{\n to: txParams.to,\n data: txParams.data,\n value: txParams.value || '0x0',\n from: sessionKeyAddress\n }]\n })\n gasLimit = parseInt(gasEstimate, 16)\n }\n\n // 5. Build EIP-1559 transaction array\n const txArray = [\n toHex(chainIdInt), // chainId\n nonce === 0 ? '0x' : toHex(nonce), // nonce (special case for 0)\n toHex(maxPriorityFeePerGas), // maxPriorityFeePerGas\n toHex(maxFeePerGas), // maxFeePerGas\n toHex(gasLimit), // gasLimit\n txParams.to.toLowerCase(), // to (ensure lowercase)\n txParams.value?.toLowerCase() || '0x0', // value (ensure lowercase)\n txParams.data?.toLowerCase() || '0x', // data (ensure lowercase)\n [], // accessList (empty for now)\n '0x', // v (signature placeholder)\n '0x', // r (signature placeholder)\n '0x' // s (signature placeholder)\n ].map(value => {\n // Ensure all hex strings start with 0x\n if (typeof value === 'string' && !value.startsWith('0x')) {\n return '0x' + value;\n }\n return value;\n });\n\n // 6. RLP encode the transaction\n const rlpEncoded = rlpEncode(txArray)\n \n // 7. Prepare EIP-1559 transaction (type 2)\n // Convert RLP result to hex string - handle any type\n let rlpHex: string\n \n // The RLP library returns a Buffer or Uint8Array\n if (rlpEncoded && typeof rlpEncoded === 'object' && 'length' in rlpEncoded) {\n // It's array-like (Buffer or Uint8Array)\n const bytes = Array.from(rlpEncoded as Uint8Array)\n rlpHex = bytes.map((byte: number) => byte.toString(16).padStart(2, '0')).join('')\n } else {\n // Fallback - shouldn't happen with RLP but just in case\n throw new Error('Unexpected RLP encoding result')\n }\n \n const txBytes = new Uint8Array([\n 2, // EIP-1559 transaction type\n ...hexToBytes('0x' + rlpHex) // RLP encoded transaction\n ])\n\n // 8. Convert to base64 for TEN\n const txBase64 = btoa(String.fromCharCode(...txBytes))\n\n // 9. Send through TEN session key execution\n const txHash = await provider.request({\n method: 'eth_getStorageAt',\n params: [\n TEN_ADDRESSES.SESSION_KEY_EXECUTE,\n txBase64,\n 'latest'\n ]\n })\n\n updateState({ isLoading: false })\n return txHash\n\n } catch (error) {\n const err = error instanceof Error ? error : new Error('Transaction failed')\n updateState({ error: err, isLoading: false })\n throw err\n }\n}"],"mappings":"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","names":["src_exports","__export","activateSessionKey","cleanupSessionKey","createSessionKey","deactivateSessionKey","deleteSessionKey","fundSessionKey","getBalance","getError","getIsActive","getIsLoading","getSessionKey","getState","sendTransaction","subscribeToState","__toCommonJS","TEN_ADDRESSES","TEN_CHAIN_ID","DEFAULT_GAS_SETTINGS","state","subscribers","isUpdating","persisted","parsed","error","getState","updateState","updates","resolve","callback","subscribeToState","clearPersistedState","getSessionKey","getIsActive","getBalance","getIsLoading","getError","toHex","value","hexStr","hexToBytes","hex","cleanHex","bytes","i","parseEther","value","whole","decimal","paddedDecimal","providerCleanup","setupProviderListeners","provider","handleDisconnect","updateState","handleChainChanged","checkTenNetwork","chainId","TEN_CHAIN_ID","createSessionKey","TEN_ADDRESSES","response","existingKey","sessionKeyAddress","error","err","fundSessionKey","amount","userAddress","valueInWei","parseEther","valueHex","toHex","txHash","checkTx","receipt","resolve","activateSessionKey","deactivateSessionKey","deleteSessionKey","clearPersistedState","cleanupSessionKey","import_rlp","checkTenNetwork","provider","chainId","TEN_CHAIN_ID","calculateGasFees","priority","BASE_FEE_MULTIPLIERS","DEFAULT_GAS_SETTINGS","feeHistory","baseFee","priorityFeePerGas","multiplier","maxFeePerGas","error","baseFeePerGas","sendTransaction","txParams","updateState","sessionKeyAddress","getSessionKey","chainIdInt","nonce","nonceHex","maxPriorityFeePerGas","gasFees","gasLimit","gasEstimate","txArray","toHex","value","rlpEncoded","rlpEncode","rlpHex","byte","txBytes","hexToBytes","txBase64","txHash","TEN_ADDRESSES","err"]}
package/dist/index.mjs ADDED
@@ -0,0 +1,2 @@
1
+ var E={SESSION_KEY_CREATE:"0x0000000000000000000000000000000000000003",SESSION_KEY_RETRIEVE:"0x0000000000000000000000000000000000000007",SESSION_KEY_ACTIVATE:"0x0000000000000000000000000000000000000004",SESSION_KEY_DEACTIVATE:"0x0000000000000000000000000000000000000005",SESSION_KEY_DELETE:"0x0000000000000000000000000000000000000006",SESSION_KEY_EXECUTE:"0x0000000000000000000000000000000000000008"},u=443,P={PRIORITY_FEE_PERCENTILES:[25,50,75],FEE_HISTORY_BLOCKS:10,BASE_FEE_MULTIPLIERS:{LOW:1.1,MEDIUM:1.2,HIGH:1.5}};var c={sessionKey:null,isActive:!1,balance:null,isLoading:!1,error:null},p=new Set,f=!1;try{let e=localStorage.getItem("ten-session-key-state");if(e){let t=JSON.parse(e);c={...c,sessionKey:t.sessionKey,isActive:t.isActive}}}catch(e){console.warn("Failed to load persisted state:",e)}var _=()=>({...c}),s=async e=>{for(;f;)await new Promise(t=>setTimeout(t,50));try{if(f=!0,c={...c,...e},"sessionKey"in e||"isActive"in e)try{localStorage.setItem("ten-session-key-state",JSON.stringify({sessionKey:c.sessionKey,isActive:c.isActive}))}catch(t){console.warn("Failed to persist state:",t)}p.forEach(t=>{try{t(_())}catch(r){console.error("Error in state subscriber:",r)}})}finally{f=!1}},N=e=>(p.add(e),()=>{p.delete(e)}),T=()=>{try{localStorage.removeItem("ten-session-key-state")}catch(e){console.warn("Failed to clear persisted state:",e)}},x=()=>c.sessionKey,C=()=>c.isActive,G=()=>c.balance,D=()=>c.isLoading,B=()=>c.error;var g=e=>{let t=BigInt(e).toString(16);return t=t||"0","0x"+t},A=e=>{let t=e.replace("0x",""),r=new Uint8Array(t.length/2);for(let o=0;o<t.length;o+=2)r[o/2]=parseInt(t.substr(o,2),16);return r};var b=e=>{let[t,r=""]=e.split("."),o=r.padEnd(18,"0").slice(0,18);return BigInt(t+o)};var y=null,H=e=>{y&&y();let t=()=>{s({isActive:!1,error:new Error("Provider disconnected")})},r=()=>{s({isActive:!1,error:new Error("Chain changed")})};e.on?.("disconnect",t),e.on?.("chainChanged",r),y=()=>{e.removeListener?.("disconnect",t),e.removeListener?.("chainChanged",r)}},h=async e=>{let t=await e.request({method:"eth_chainId"});if(parseInt(t,16)!==u)throw new Error("Session Keys is only for TEN chain, please add or switch to TEN.")},O=async e=>{try{s({isLoading:!0,error:null}),H(e),await h(e),console.log("\u{1F511} Creating session key on TEN network..."),console.log("\u{1F511} Using address:",E.SESSION_KEY_CREATE);let t=await e.request({method:"eth_getStorageAt",params:[E.SESSION_KEY_CREATE,"0x0","latest"]});if(console.log("\u{1F511} Create response:",t),!t||t==="0x0000000000000000000000000000000000000000000000000000000000000000"){console.log("\u{1F511} Creation failed, trying to retrieve existing session key...");let o=await e.request({method:"eth_getStorageAt",params:[E.SESSION_KEY_RETRIEVE,"0x0","latest"]});if(console.log("\u{1F511} Existing key response:",o),o&&o!=="0x0000000000000000000000000000000000000000000000000000000000000000"){let a="0x"+o.slice(-40);return console.log("\u{1F511} Retrieved existing session key:",a),s({sessionKey:a,isLoading:!1}),a}throw new Error("Failed to create session key - both creation and retrieval returned empty response")}let r="0x"+t.slice(-40);return console.log("\u{1F511} Created new session key:",r),s({sessionKey:r,isLoading:!1}),r}catch(t){console.error("\u{1F511} Session key creation error:",t);let r=t instanceof Error?t:new Error("Unknown error");throw s({error:r,isLoading:!1}),r}},k=async(e,t,r,o)=>{try{s({isLoading:!0,error:null}),await h(r),console.log("\u{1F4B0} Funding session key:",e,"with",t,"ETH");let a=b(t),n=g(a),l=await r.request({method:"eth_sendTransaction",params:[{to:e,value:n,from:o}]});console.log("\u{1F4B0} Funding transaction sent:",l);let d=async()=>{let S=await r.request({method:"eth_getTransactionReceipt",params:[l]});return S?(console.log("\u{1F4B0} Funding confirmed!"),S):(await new Promise(I=>setTimeout(I,2e3)),d())};return await d(),s({isLoading:!1}),l}catch(a){let n=a instanceof Error?a:new Error("Unknown error");throw s({error:n,isLoading:!1}),n}},U=async e=>{try{s({isLoading:!0,error:null}),await h(e),await e.request({method:"eth_getStorageAt",params:[E.SESSION_KEY_ACTIVATE,"0x0","latest"]}),s({isActive:!0,isLoading:!1})}catch(t){let r=t instanceof Error?t:new Error("Activation failed");throw s({error:r,isLoading:!1}),r}},R=async e=>{try{s({isLoading:!0,error:null}),await h(e),await e.request({method:"eth_getStorageAt",params:[E.SESSION_KEY_DEACTIVATE,"0x0","latest"]}),s({isActive:!1,isLoading:!1})}catch(t){let r=t instanceof Error?t:new Error("Deactivation failed");throw s({error:r,isLoading:!1}),r}},q=async e=>{try{s({isLoading:!0,error:null}),await h(e),await e.request({method:"eth_getStorageAt",params:[E.SESSION_KEY_DELETE,"0x0","latest"]}),T(),y&&(y(),y=null),s({sessionKey:null,isActive:!1,balance:null,isLoading:!1})}catch(t){let r=t instanceof Error?t:new Error("Deletion failed");throw s({error:r,isLoading:!1}),r}},Y=async e=>{try{s({isLoading:!0,error:null}),await h(e),await e.request({method:"eth_getStorageAt",params:[E.SESSION_KEY_DEACTIVATE,"0x0","latest"]}),await e.request({method:"eth_getStorageAt",params:[E.SESSION_KEY_DELETE,"0x0","latest"]}),s({sessionKey:null,isActive:!1,balance:null,isLoading:!1})}catch(t){let r=t instanceof Error?t:new Error("Cleanup failed");throw s({error:r,isLoading:!1}),r}};import{encode as M}from"rlp";var V=async e=>{let t=await e.request({method:"eth_chainId"});if(parseInt(t,16)!==u)throw new Error("Session Keys is only for TEN chain, please add or switch to TEN.")},W=async(e,t="MEDIUM")=>{let{BASE_FEE_MULTIPLIERS:r}=P;try{let o=await e.request({method:"eth_feeHistory",params:[1,"latest",[]]});if(console.log("Fee history response:",o),!o?.baseFeePerGas?.[0])throw new Error("Invalid fee history response");let a=BigInt(o.baseFeePerGas[0]);console.log("Base fee:",a.toString());let n=BigInt(1e8),l=r[t],d=BigInt(Math.floor(Number(a)*l))+n;return console.log("Priority fee:",n.toString()),console.log("Max fee:",d.toString()),{maxFeePerGas:d,maxPriorityFeePerGas:n}}catch(o){console.warn("Error getting fee history, using fallback values:",o);let a=BigInt(1e9),n=BigInt(1e8),l=r[t];return{maxFeePerGas:BigInt(Math.floor(Number(a)*l))+n,maxPriorityFeePerGas:n}}},j=async(e,t)=>{try{s({isLoading:!0,error:null}),await V(t);let r=x();if(!r)throw new Error("No active session key. Create and activate a session key first.");let o=await t.request({method:"eth_chainId"}),a=parseInt(o,16),n;if(e.nonce!==void 0)n=e.nonce;else{let i=await t.request({method:"eth_getTransactionCount",params:[r,"latest"]});n=parseInt(i,16)}let l,d;if(e.maxFeePerGas&&e.maxPriorityFeePerGas)l=BigInt(e.maxFeePerGas),d=BigInt(e.maxPriorityFeePerGas);else{let i=await W(t,"MEDIUM");l=i.maxFeePerGas,d=i.maxPriorityFeePerGas}let S;if(e.gasLimit)S=e.gasLimit;else{let i=await t.request({method:"eth_estimateGas",params:[{to:e.to,data:e.data,value:e.value||"0x0",from:r}]});S=parseInt(i,16)}let I=[g(a),n===0?"0x":g(n),g(d),g(l),g(S),e.to.toLowerCase(),e.value?.toLowerCase()||"0x0",e.data?.toLowerCase()||"0x",[],"0x","0x","0x"].map(i=>typeof i=="string"&&!i.startsWith("0x")?"0x"+i:i),m=M(I),w;if(m&&typeof m=="object"&&"length"in m)w=Array.from(m).map(F=>F.toString(16).padStart(2,"0")).join("");else throw new Error("Unexpected RLP encoding result");let K=new Uint8Array([2,...A("0x"+w)]),L=btoa(String.fromCharCode(...K)),v=await t.request({method:"eth_getStorageAt",params:[E.SESSION_KEY_EXECUTE,L,"latest"]});return s({isLoading:!1}),v}catch(r){let o=r instanceof Error?r:new Error("Transaction failed");throw s({error:o,isLoading:!1}),o}};export{U as activateSessionKey,Y as cleanupSessionKey,O as createSessionKey,R as deactivateSessionKey,q as deleteSessionKey,k as fundSessionKey,G as getBalance,B as getError,C as getIsActive,D as getIsLoading,x as getSessionKey,_ as getState,j as sendTransaction,N as subscribeToState};
2
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/constants.ts","../src/core/state.ts","../src/utils/encoding.ts","../src/core/sessionKey.ts","../src/core/transaction.ts"],"sourcesContent":["export const TEN_ADDRESSES = {\n SESSION_KEY_CREATE: '0x0000000000000000000000000000000000000003',\n SESSION_KEY_RETRIEVE: '0x0000000000000000000000000000000000000007',\n SESSION_KEY_ACTIVATE: '0x0000000000000000000000000000000000000004',\n SESSION_KEY_DEACTIVATE: '0x0000000000000000000000000000000000000005',\n SESSION_KEY_DELETE: '0x0000000000000000000000000000000000000006',\n SESSION_KEY_EXECUTE: '0x0000000000000000000000000000000000000008'\n} as const\n\nexport const TEN_CHAIN_ID = 443\n\nexport const DEFAULT_GAS_SETTINGS = {\n // Use percentiles for different network conditions\n PRIORITY_FEE_PERCENTILES: [25, 50, 75],\n // Number of blocks to look back for fee estimation\n FEE_HISTORY_BLOCKS: 10,\n // Base fee multipliers for different network conditions\n BASE_FEE_MULTIPLIERS: {\n LOW: 1.1, // Low priority\n MEDIUM: 1.2, // Medium priority (default)\n HIGH: 1.5 // High priority\n }\n} as const","import type { SessionKeyState, StateSubscriber } from '../types'\n\n// Internal state\nlet state: SessionKeyState = {\n sessionKey: null,\n isActive: false,\n balance: null,\n isLoading: false,\n error: null\n}\n\n// Subscribers\nconst subscribers = new Set<StateSubscriber>()\n\n// Simple mutex for state updates\nlet isUpdating = false\n\n// Load persisted state on init\ntry {\n const persisted = localStorage.getItem('ten-session-key-state')\n if (persisted) {\n const parsed = JSON.parse(persisted)\n state = {\n ...state,\n sessionKey: parsed.sessionKey,\n isActive: parsed.isActive\n }\n }\n} catch (error) {\n console.warn('Failed to load persisted state:', error)\n}\n\nexport const getState = (): SessionKeyState => ({ ...state })\n\nexport const updateState = async (updates: Partial<SessionKeyState>): Promise<void> => {\n // Wait if another update is in progress\n while (isUpdating) {\n await new Promise(resolve => setTimeout(resolve, 50))\n }\n \n try {\n isUpdating = true\n state = { ...state, ...updates }\n \n // Persist key state changes\n if ('sessionKey' in updates || 'isActive' in updates) {\n try {\n localStorage.setItem('ten-session-key-state', JSON.stringify({\n sessionKey: state.sessionKey,\n isActive: state.isActive\n }))\n } catch (error) {\n console.warn('Failed to persist state:', error)\n }\n }\n\n // Notify all subscribers\n subscribers.forEach(callback => {\n try {\n callback(getState())\n } catch (error) {\n console.error('Error in state subscriber:', error)\n }\n })\n } finally {\n isUpdating = false\n }\n}\n\nexport const subscribeToState = (callback: StateSubscriber): (() => void) => {\n subscribers.add(callback)\n return () => {\n subscribers.delete(callback)\n }\n}\n\nexport const clearPersistedState = (): void => {\n try {\n localStorage.removeItem('ten-session-key-state')\n } catch (error) {\n console.warn('Failed to clear persisted state:', error)\n }\n}\n\n// State getters\nexport const getSessionKey = (): string | null => state.sessionKey\nexport const getIsActive = (): boolean => state.isActive\nexport const getBalance = (): SessionKeyState['balance'] => state.balance\nexport const getIsLoading = (): boolean => state.isLoading\nexport const getError = (): Error | null => state.error","export const toHex = (value: number | bigint | string): string => {\n // Convert to hex string and remove leading zeros\n let hexStr = BigInt(value).toString(16)\n // Ensure at least one digit\n hexStr = hexStr || '0'\n // Add 0x prefix\n return '0x' + hexStr\n}\n\nexport const hexToBytes = (hex: string): Uint8Array => {\n const cleanHex = hex.replace('0x', '')\n const bytes = new Uint8Array(cleanHex.length / 2)\n for (let i = 0; i < cleanHex.length; i += 2) {\n bytes[i / 2] = parseInt(cleanHex.substr(i, 2), 16)\n }\n return bytes\n}\n\nexport const bytesToHex = (bytes: Uint8Array): string => {\n return '0x' + Array.from(bytes)\n .map(b => b.toString(16).padStart(2, '0'))\n .join('')\n}\n\nexport const parseEther = (value: string): bigint => {\n const [whole, decimal = ''] = value.split('.')\n const paddedDecimal = decimal.padEnd(18, '0').slice(0, 18)\n return BigInt(whole + paddedDecimal)\n}\n\nexport const formatEther = (wei: bigint): number => {\n const ethString = wei.toString()\n if (ethString.length <= 18) {\n return parseFloat('0.' + ethString.padStart(18, '0'))\n }\n const wholePart = ethString.slice(0, -18)\n const decimalPart = ethString.slice(-18)\n return parseFloat(wholePart + '.' + decimalPart)\n}\n\nexport const estimateTransactions = (ethBalance: number): number => {\n // Rough estimate: each transaction costs ~0.005 ETH\n return Math.floor(ethBalance / 0.005)\n}","import type { EIP1193Provider } from '../types'\nimport { TEN_ADDRESSES, TEN_CHAIN_ID } from '../utils/constants'\nimport { updateState, clearPersistedState } from './state'\nimport { parseEther, toHex, formatEther, estimateTransactions } from '../utils/encoding'\n\n// Track provider event listeners\nlet providerCleanup: (() => void) | null = null\n\nconst setupProviderListeners = (provider: EIP1193Provider) => {\n if (providerCleanup) {\n providerCleanup()\n }\n\n const handleDisconnect = () => {\n updateState({ \n isActive: false,\n error: new Error('Provider disconnected')\n })\n }\n\n const handleChainChanged = () => {\n updateState({ \n isActive: false,\n error: new Error('Chain changed')\n })\n }\n\n provider.on?.('disconnect', handleDisconnect)\n provider.on?.('chainChanged', handleChainChanged)\n\n providerCleanup = () => {\n provider.removeListener?.('disconnect', handleDisconnect)\n provider.removeListener?.('chainChanged', handleChainChanged)\n }\n}\n\nconst checkTenNetwork = async (provider: EIP1193Provider): Promise<void> => {\n const chainId = await provider.request({ method: 'eth_chainId' })\n const chainIdInt = parseInt(chainId, 16)\n \n if (chainIdInt !== TEN_CHAIN_ID) {\n throw new Error('Session Keys is only for TEN chain, please add or switch to TEN.')\n }\n}\n\nexport const createSessionKey = async (provider: EIP1193Provider): Promise<string> => {\n try {\n updateState({ isLoading: true, error: null })\n\n // Setup provider listeners\n setupProviderListeners(provider)\n\n // Check if connected to TEN network\n await checkTenNetwork(provider)\n\n console.log('🔑 Creating session key on TEN network...')\n console.log('🔑 Using address:', TEN_ADDRESSES.SESSION_KEY_CREATE)\n\n // Try to create a new session key\n const response = await provider.request({\n method: 'eth_getStorageAt',\n params: [\n TEN_ADDRESSES.SESSION_KEY_CREATE,\n '0x0',\n 'latest'\n ]\n })\n\n console.log('🔑 Create response:', response)\n\n if (!response || response === '0x0000000000000000000000000000000000000000000000000000000000000000') {\n console.log('🔑 Creation failed, trying to retrieve existing session key...')\n \n // If creation failed, try to retrieve existing session key\n const existingKey = await provider.request({\n method: 'eth_getStorageAt',\n params: [\n TEN_ADDRESSES.SESSION_KEY_RETRIEVE,\n '0x0',\n 'latest'\n ]\n })\n\n console.log('🔑 Existing key response:', existingKey)\n\n if (existingKey && existingKey !== '0x0000000000000000000000000000000000000000000000000000000000000000') {\n const sessionKeyAddress = '0x' + existingKey.slice(-40) // Extract address from response\n console.log('🔑 Retrieved existing session key:', sessionKeyAddress)\n updateState({ \n sessionKey: sessionKeyAddress,\n isLoading: false \n })\n return sessionKeyAddress\n }\n\n throw new Error('Failed to create session key - both creation and retrieval returned empty response')\n }\n\n const sessionKeyAddress = '0x' + response.slice(-40) // Extract address from response\n console.log('🔑 Created new session key:', sessionKeyAddress)\n updateState({ \n sessionKey: sessionKeyAddress,\n isLoading: false \n })\n\n return sessionKeyAddress\n } catch (error) {\n console.error('🔑 Session key creation error:', error)\n const err = error instanceof Error ? error : new Error('Unknown error')\n updateState({ error: err, isLoading: false })\n throw err\n }\n}\n\nexport const fundSessionKey = async (\n sessionKeyAddress: string,\n amount: string,\n provider: EIP1193Provider,\n userAddress: string\n): Promise<string> => {\n try {\n updateState({ isLoading: true, error: null })\n\n // Check if connected to TEN network\n await checkTenNetwork(provider)\n\n console.log('💰 Funding session key:', sessionKeyAddress, 'with', amount, 'ETH')\n\n // Convert amount to hex\n const valueInWei = parseEther(amount)\n const valueHex = toHex(valueInWei)\n\n // Send transaction\n const txHash = await provider.request({\n method: 'eth_sendTransaction',\n params: [{\n to: sessionKeyAddress,\n value: valueHex,\n from: userAddress\n }]\n })\n\n console.log('💰 Funding transaction sent:', txHash)\n\n // Monitor transaction confirmation\n const checkTx = async () => {\n const receipt = await provider.request({\n method: 'eth_getTransactionReceipt',\n params: [txHash]\n })\n if (receipt) {\n console.log('💰 Funding confirmed!')\n return receipt\n }\n // Check again in 2 seconds\n await new Promise(resolve => setTimeout(resolve, 2000))\n return checkTx()\n }\n\n await checkTx()\n updateState({ isLoading: false })\n return txHash\n\n } catch (error) {\n const err = error instanceof Error ? error : new Error('Unknown error')\n updateState({ error: err, isLoading: false })\n throw err\n }\n}\n\nexport const activateSessionKey = async (provider: EIP1193Provider): Promise<void> => {\n try {\n updateState({ isLoading: true, error: null })\n\n // Check if connected to TEN network\n await checkTenNetwork(provider)\n\n await provider.request({\n method: 'eth_getStorageAt',\n params: [\n TEN_ADDRESSES.SESSION_KEY_ACTIVATE,\n '0x0',\n 'latest'\n ]\n })\n\n updateState({ \n isActive: true,\n isLoading: false \n })\n\n } catch (error) {\n const err = error instanceof Error ? error : new Error('Activation failed')\n updateState({ error: err, isLoading: false })\n throw err\n }\n}\n\nexport const deactivateSessionKey = async (provider: EIP1193Provider): Promise<void> => {\n try {\n updateState({ isLoading: true, error: null })\n\n // Check if connected to TEN network\n await checkTenNetwork(provider)\n\n await provider.request({\n method: 'eth_getStorageAt',\n params: [\n TEN_ADDRESSES.SESSION_KEY_DEACTIVATE,\n '0x0',\n 'latest'\n ]\n })\n\n updateState({ \n isActive: false,\n isLoading: false \n })\n\n } catch (error) {\n const err = error instanceof Error ? error : new Error('Deactivation failed')\n updateState({ error: err, isLoading: false })\n throw err\n }\n}\n\nexport const deleteSessionKey = async (provider: EIP1193Provider): Promise<void> => {\n try {\n updateState({ isLoading: true, error: null })\n\n // Check if connected to TEN network\n await checkTenNetwork(provider)\n\n await provider.request({\n method: 'eth_getStorageAt',\n params: [\n TEN_ADDRESSES.SESSION_KEY_DELETE,\n '0x0',\n 'latest'\n ]\n })\n\n // Clear persisted state when deleting\n clearPersistedState()\n \n // Remove provider listeners\n if (providerCleanup) {\n providerCleanup()\n providerCleanup = null\n }\n\n updateState({ \n sessionKey: null,\n isActive: false,\n balance: null,\n isLoading: false \n })\n\n } catch (error) {\n const err = error instanceof Error ? error : new Error('Deletion failed')\n updateState({ error: err, isLoading: false })\n throw err\n }\n}\n\nexport const cleanupSessionKey = async (provider: EIP1193Provider): Promise<void> => {\n try {\n updateState({ isLoading: true, error: null })\n\n // Check if connected to TEN network\n await checkTenNetwork(provider)\n\n // First deactivate\n await provider.request({\n method: 'eth_getStorageAt',\n params: [\n TEN_ADDRESSES.SESSION_KEY_DEACTIVATE,\n '0x0',\n 'latest'\n ]\n })\n\n // Then delete\n await provider.request({\n method: 'eth_getStorageAt',\n params: [\n TEN_ADDRESSES.SESSION_KEY_DELETE,\n '0x0',\n 'latest'\n ]\n })\n\n updateState({ \n sessionKey: null,\n isActive: false,\n balance: null,\n isLoading: false \n })\n\n } catch (error) {\n const err = error instanceof Error ? error : new Error('Cleanup failed')\n updateState({ error: err, isLoading: false })\n throw err\n }\n}\n\n// Helper function to update balance\nconst updateBalance = async (sessionKeyAddress: string, provider: EIP1193Provider): Promise<void> => {\n try {\n const balanceHex = await provider.request({\n method: 'eth_getBalance',\n params: [sessionKeyAddress, 'latest']\n })\n\n const balanceWei = BigInt(balanceHex)\n const ethBalance = formatEther(balanceWei)\n \n updateState({\n balance: {\n eth: ethBalance,\n estimatedTransactions: estimateTransactions(ethBalance)\n }\n })\n } catch (error) {\n console.warn('Failed to update balance:', error)\n }\n}","import { encode as rlpEncode } from 'rlp'\nimport type { EIP1193Provider, TransactionParams } from '../types'\nimport { TEN_ADDRESSES, TEN_CHAIN_ID, DEFAULT_GAS_SETTINGS } from '../utils/constants'\nimport { toHex, hexToBytes } from '../utils/encoding'\nimport { getSessionKey, updateState } from './state'\n\nconst checkTenNetwork = async (provider: EIP1193Provider): Promise<void> => {\n const chainId = await provider.request({ method: 'eth_chainId' })\n const chainIdInt = parseInt(chainId, 16)\n \n if (chainIdInt !== TEN_CHAIN_ID) {\n throw new Error('Session Keys is only for TEN chain, please add or switch to TEN.')\n }\n}\n\nconst calculateGasFees = async (\n provider: EIP1193Provider,\n priority: 'LOW' | 'MEDIUM' | 'HIGH' = 'MEDIUM'\n): Promise<{ maxFeePerGas: bigint; maxPriorityFeePerGas: bigint }> => {\n const { BASE_FEE_MULTIPLIERS } = DEFAULT_GAS_SETTINGS\n \n try {\n // Get fee history for last block\n const feeHistory = await provider.request({\n method: 'eth_feeHistory',\n params: [\n 1, // just get latest block\n 'latest',\n [] // no percentiles needed since we don't get rewards\n ]\n })\n\n console.log('Fee history response:', feeHistory)\n\n if (!feeHistory?.baseFeePerGas?.[0]) {\n throw new Error('Invalid fee history response')\n }\n\n // Get base fee from response\n const baseFee = BigInt(feeHistory.baseFeePerGas[0])\n console.log('Base fee:', baseFee.toString())\n \n // Use a fixed priority fee since the network doesn't provide reward data\n const priorityFeePerGas = BigInt(100000000) // 0.1 gwei\n \n // Calculate max fee using appropriate multiplier\n const multiplier = BASE_FEE_MULTIPLIERS[priority]\n const maxFeePerGas = BigInt(Math.floor(Number(baseFee) * multiplier)) + priorityFeePerGas\n console.log('Priority fee:', priorityFeePerGas.toString())\n console.log('Max fee:', maxFeePerGas.toString())\n\n return { maxFeePerGas, maxPriorityFeePerGas: priorityFeePerGas }\n } catch (error) {\n console.warn('Error getting fee history, using fallback values:', error)\n // Fallback to fixed values if anything goes wrong\n const baseFeePerGas = BigInt(1000000000) // 1 gwei\n const priorityFeePerGas = BigInt(100000000) // 0.1 gwei\n const multiplier = BASE_FEE_MULTIPLIERS[priority]\n const maxFeePerGas = BigInt(Math.floor(Number(baseFeePerGas) * multiplier)) + priorityFeePerGas\n return { maxFeePerGas, maxPriorityFeePerGas: priorityFeePerGas }\n }\n}\n\nexport const sendTransaction = async (\n txParams: TransactionParams,\n provider: EIP1193Provider\n): Promise<string> => {\n try {\n updateState({ isLoading: true, error: null })\n\n // Check if connected to TEN network\n await checkTenNetwork(provider)\n\n const sessionKeyAddress = getSessionKey()\n if (!sessionKeyAddress) {\n throw new Error('No active session key. Create and activate a session key first.')\n }\n\n // 1. Get chain ID\n const chainId = await provider.request({ method: 'eth_chainId' })\n const chainIdInt = parseInt(chainId, 16)\n\n // 2. Get nonce\n let nonce: number\n if (txParams.nonce !== undefined) {\n nonce = txParams.nonce\n } else {\n const nonceHex = await provider.request({\n method: 'eth_getTransactionCount',\n params: [sessionKeyAddress, 'latest']\n })\n nonce = parseInt(nonceHex, 16)\n }\n\n // 3. Calculate gas fees\n let maxFeePerGas: bigint\n let maxPriorityFeePerGas: bigint\n\n if (txParams.maxFeePerGas && txParams.maxPriorityFeePerGas) {\n maxFeePerGas = BigInt(txParams.maxFeePerGas)\n maxPriorityFeePerGas = BigInt(txParams.maxPriorityFeePerGas)\n } else {\n // Use dynamic fee calculation\n const gasFees = await calculateGasFees(provider, 'MEDIUM')\n maxFeePerGas = gasFees.maxFeePerGas\n maxPriorityFeePerGas = gasFees.maxPriorityFeePerGas\n }\n\n // 4. Get gas limit (use provided or estimate)\n let gasLimit: number\n if (txParams.gasLimit) {\n gasLimit = txParams.gasLimit\n } else {\n const gasEstimate = await provider.request({\n method: 'eth_estimateGas',\n params: [{\n to: txParams.to,\n data: txParams.data,\n value: txParams.value || '0x0',\n from: sessionKeyAddress\n }]\n })\n gasLimit = parseInt(gasEstimate, 16)\n }\n\n // 5. Build EIP-1559 transaction array\n const txArray = [\n toHex(chainIdInt), // chainId\n nonce === 0 ? '0x' : toHex(nonce), // nonce (special case for 0)\n toHex(maxPriorityFeePerGas), // maxPriorityFeePerGas\n toHex(maxFeePerGas), // maxFeePerGas\n toHex(gasLimit), // gasLimit\n txParams.to.toLowerCase(), // to (ensure lowercase)\n txParams.value?.toLowerCase() || '0x0', // value (ensure lowercase)\n txParams.data?.toLowerCase() || '0x', // data (ensure lowercase)\n [], // accessList (empty for now)\n '0x', // v (signature placeholder)\n '0x', // r (signature placeholder)\n '0x' // s (signature placeholder)\n ].map(value => {\n // Ensure all hex strings start with 0x\n if (typeof value === 'string' && !value.startsWith('0x')) {\n return '0x' + value;\n }\n return value;\n });\n\n // 6. RLP encode the transaction\n const rlpEncoded = rlpEncode(txArray)\n \n // 7. Prepare EIP-1559 transaction (type 2)\n // Convert RLP result to hex string - handle any type\n let rlpHex: string\n \n // The RLP library returns a Buffer or Uint8Array\n if (rlpEncoded && typeof rlpEncoded === 'object' && 'length' in rlpEncoded) {\n // It's array-like (Buffer or Uint8Array)\n const bytes = Array.from(rlpEncoded as Uint8Array)\n rlpHex = bytes.map((byte: number) => byte.toString(16).padStart(2, '0')).join('')\n } else {\n // Fallback - shouldn't happen with RLP but just in case\n throw new Error('Unexpected RLP encoding result')\n }\n \n const txBytes = new Uint8Array([\n 2, // EIP-1559 transaction type\n ...hexToBytes('0x' + rlpHex) // RLP encoded transaction\n ])\n\n // 8. Convert to base64 for TEN\n const txBase64 = btoa(String.fromCharCode(...txBytes))\n\n // 9. Send through TEN session key execution\n const txHash = await provider.request({\n method: 'eth_getStorageAt',\n params: [\n TEN_ADDRESSES.SESSION_KEY_EXECUTE,\n txBase64,\n 'latest'\n ]\n })\n\n updateState({ isLoading: false })\n return txHash\n\n } catch (error) {\n const err = error instanceof Error ? error : new Error('Transaction failed')\n updateState({ error: err, isLoading: false })\n throw err\n }\n}"],"mappings":"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","names":["TEN_ADDRESSES","TEN_CHAIN_ID","DEFAULT_GAS_SETTINGS","state","subscribers","isUpdating","persisted","parsed","error","getState","updateState","updates","resolve","callback","subscribeToState","clearPersistedState","getSessionKey","getIsActive","getBalance","getIsLoading","getError","toHex","value","hexStr","hexToBytes","hex","cleanHex","bytes","i","parseEther","value","whole","decimal","paddedDecimal","providerCleanup","setupProviderListeners","provider","handleDisconnect","updateState","handleChainChanged","checkTenNetwork","chainId","TEN_CHAIN_ID","createSessionKey","TEN_ADDRESSES","response","existingKey","sessionKeyAddress","error","err","fundSessionKey","amount","userAddress","valueInWei","parseEther","valueHex","toHex","txHash","checkTx","receipt","resolve","activateSessionKey","deactivateSessionKey","deleteSessionKey","clearPersistedState","cleanupSessionKey","rlpEncode","checkTenNetwork","provider","chainId","TEN_CHAIN_ID","calculateGasFees","priority","BASE_FEE_MULTIPLIERS","DEFAULT_GAS_SETTINGS","feeHistory","baseFee","priorityFeePerGas","multiplier","maxFeePerGas","error","baseFeePerGas","sendTransaction","txParams","updateState","sessionKeyAddress","getSessionKey","chainIdInt","nonce","nonceHex","maxPriorityFeePerGas","gasFees","gasLimit","gasEstimate","txArray","toHex","value","rlpEncoded","rlpEncode","rlpHex","byte","txBytes","hexToBytes","txBase64","txHash","TEN_ADDRESSES","err"]}
@@ -0,0 +1,27 @@
1
+ import { S as SessionKeyState } from './index-mYMQzYjE.mjs';
2
+
3
+ /**
4
+ * React hook for subscribing to session key state
5
+ *
6
+ * @example
7
+ * ```tsx
8
+ * import { useSessionKeyState } from '@tenprotocol/session-keys/react'
9
+ *
10
+ * function MyComponent() {
11
+ * const { sessionKey, isActive, balance, isLoading, error } = useSessionKeyState()
12
+ *
13
+ * return (
14
+ * <div>
15
+ * <p>Session Key: {sessionKey}</p>
16
+ * <p>Active: {isActive ? 'Yes' : 'No'}</p>
17
+ * <p>Balance: {balance?.eth} ETH</p>
18
+ * {isLoading && <p>Loading...</p>}
19
+ * {error && <p>Error: {error.message}</p>}
20
+ * </div>
21
+ * )
22
+ * }
23
+ * ```
24
+ */
25
+ declare const useSessionKeyState: () => SessionKeyState;
26
+
27
+ export { useSessionKeyState };
@@ -0,0 +1,27 @@
1
+ import { S as SessionKeyState } from './index-mYMQzYjE.js';
2
+
3
+ /**
4
+ * React hook for subscribing to session key state
5
+ *
6
+ * @example
7
+ * ```tsx
8
+ * import { useSessionKeyState } from '@tenprotocol/session-keys/react'
9
+ *
10
+ * function MyComponent() {
11
+ * const { sessionKey, isActive, balance, isLoading, error } = useSessionKeyState()
12
+ *
13
+ * return (
14
+ * <div>
15
+ * <p>Session Key: {sessionKey}</p>
16
+ * <p>Active: {isActive ? 'Yes' : 'No'}</p>
17
+ * <p>Balance: {balance?.eth} ETH</p>
18
+ * {isLoading && <p>Loading...</p>}
19
+ * {error && <p>Error: {error.message}</p>}
20
+ * </div>
21
+ * )
22
+ * }
23
+ * ```
24
+ */
25
+ declare const useSessionKeyState: () => SessionKeyState;
26
+
27
+ export { useSessionKeyState };
package/dist/react.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";var i=Object.defineProperty;var y=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var u=Object.prototype.hasOwnProperty;var b=(e,t)=>{for(var s in t)i(e,s,{get:t[s],enumerable:!0})},d=(e,t,s,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of p(t))!u.call(e,o)&&o!==s&&i(e,o,{get:()=>t[o],enumerable:!(a=y(t,o))||a.enumerable});return e};var g=e=>d(i({},"__esModule",{value:!0}),e);var f={};b(f,{useSessionKeyState:()=>K});module.exports=g(f);var r=require("react");var n={sessionKey:null,isActive:!1,balance:null,isLoading:!1,error:null},c=new Set;try{let e=localStorage.getItem("ten-session-key-state");if(e){let t=JSON.parse(e);n={...n,sessionKey:t.sessionKey,isActive:t.isActive}}}catch(e){console.warn("Failed to load persisted state:",e)}var l=()=>({...n});var S=e=>(c.add(e),()=>{c.delete(e)});var K=()=>{let[e,t]=(0,r.useState)(l);return(0,r.useEffect)(()=>S(t),[]),e};0&&(module.exports={useSessionKeyState});
2
+ //# sourceMappingURL=react.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/react/index.ts","../src/core/state.ts"],"sourcesContent":["import { useState, useEffect } from 'react'\nimport type { SessionKeyState } from '../types'\nimport { getState, subscribeToState } from '../core/state'\n\n/**\n * React hook for subscribing to session key state\n * \n * @example\n * ```tsx\n * import { useSessionKeyState } from '@tenprotocol/session-keys/react'\n * \n * function MyComponent() {\n * const { sessionKey, isActive, balance, isLoading, error } = useSessionKeyState()\n * \n * return (\n * <div>\n * <p>Session Key: {sessionKey}</p>\n * <p>Active: {isActive ? 'Yes' : 'No'}</p>\n * <p>Balance: {balance?.eth} ETH</p>\n * {isLoading && <p>Loading...</p>}\n * {error && <p>Error: {error.message}</p>}\n * </div>\n * )\n * }\n * ```\n */\nexport const useSessionKeyState = (): SessionKeyState => {\n const [state, setState] = useState<SessionKeyState>(getState)\n\n useEffect(() => {\n const unsubscribe = subscribeToState(setState)\n return unsubscribe\n }, [])\n\n return state\n}","import type { SessionKeyState, StateSubscriber } from '../types'\n\n// Internal state\nlet state: SessionKeyState = {\n sessionKey: null,\n isActive: false,\n balance: null,\n isLoading: false,\n error: null\n}\n\n// Subscribers\nconst subscribers = new Set<StateSubscriber>()\n\n// Simple mutex for state updates\nlet isUpdating = false\n\n// Load persisted state on init\ntry {\n const persisted = localStorage.getItem('ten-session-key-state')\n if (persisted) {\n const parsed = JSON.parse(persisted)\n state = {\n ...state,\n sessionKey: parsed.sessionKey,\n isActive: parsed.isActive\n }\n }\n} catch (error) {\n console.warn('Failed to load persisted state:', error)\n}\n\nexport const getState = (): SessionKeyState => ({ ...state })\n\nexport const updateState = async (updates: Partial<SessionKeyState>): Promise<void> => {\n // Wait if another update is in progress\n while (isUpdating) {\n await new Promise(resolve => setTimeout(resolve, 50))\n }\n \n try {\n isUpdating = true\n state = { ...state, ...updates }\n \n // Persist key state changes\n if ('sessionKey' in updates || 'isActive' in updates) {\n try {\n localStorage.setItem('ten-session-key-state', JSON.stringify({\n sessionKey: state.sessionKey,\n isActive: state.isActive\n }))\n } catch (error) {\n console.warn('Failed to persist state:', error)\n }\n }\n\n // Notify all subscribers\n subscribers.forEach(callback => {\n try {\n callback(getState())\n } catch (error) {\n console.error('Error in state subscriber:', error)\n }\n })\n } finally {\n isUpdating = false\n }\n}\n\nexport const subscribeToState = (callback: StateSubscriber): (() => void) => {\n subscribers.add(callback)\n return () => {\n subscribers.delete(callback)\n }\n}\n\nexport const clearPersistedState = (): void => {\n try {\n localStorage.removeItem('ten-session-key-state')\n } catch (error) {\n console.warn('Failed to clear persisted state:', error)\n }\n}\n\n// State getters\nexport const getSessionKey = (): string | null => state.sessionKey\nexport const getIsActive = (): boolean => state.isActive\nexport const getBalance = (): SessionKeyState['balance'] => state.balance\nexport const getIsLoading = (): boolean => state.isLoading\nexport const getError = (): Error | null => state.error"],"mappings":"yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,wBAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAAoC,iBCGpC,IAAIC,EAAyB,CAC3B,WAAY,KACZ,SAAU,GACV,QAAS,KACT,UAAW,GACX,MAAO,IACT,EAGMC,EAAc,IAAI,IAMxB,GAAI,CACF,IAAMC,EAAY,aAAa,QAAQ,uBAAuB,EAC9D,GAAIA,EAAW,CACb,IAAMC,EAAS,KAAK,MAAMD,CAAS,EACnCE,EAAQ,CACN,GAAGA,EACH,WAAYD,EAAO,WACnB,SAAUA,EAAO,QACnB,CACF,CACF,OAASE,EAAO,CACd,QAAQ,KAAK,kCAAmCA,CAAK,CACvD,CAEO,IAAMC,EAAW,KAAwB,CAAE,GAAGF,CAAM,GAqCpD,IAAMG,EAAoBC,IAC/BC,EAAY,IAAID,CAAQ,EACjB,IAAM,CACXC,EAAY,OAAOD,CAAQ,CAC7B,GD/CK,IAAME,EAAqB,IAAuB,CACvD,GAAM,CAACC,EAAOC,CAAQ,KAAI,YAA0BC,CAAQ,EAE5D,sBAAU,IACYC,EAAiBF,CAAQ,EAE5C,CAAC,CAAC,EAEED,CACT","names":["react_exports","__export","useSessionKeyState","__toCommonJS","import_react","state","subscribers","persisted","parsed","state","error","getState","subscribeToState","callback","subscribers","useSessionKeyState","state","setState","getState","subscribeToState"]}
package/dist/react.mjs ADDED
@@ -0,0 +1,2 @@
1
+ import{useState as n,useEffect as a}from"react";var s={sessionKey:null,isActive:!1,balance:null,isLoading:!1,error:null},o=new Set;try{let e=localStorage.getItem("ten-session-key-state");if(e){let t=JSON.parse(e);s={...s,sessionKey:t.sessionKey,isActive:t.isActive}}}catch(e){console.warn("Failed to load persisted state:",e)}var r=()=>({...s});var i=e=>(o.add(e),()=>{o.delete(e)});var p=()=>{let[e,t]=n(r);return a(()=>i(t),[]),e};export{p as useSessionKeyState};
2
+ //# sourceMappingURL=react.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/react/index.ts","../src/core/state.ts"],"sourcesContent":["import { useState, useEffect } from 'react'\nimport type { SessionKeyState } from '../types'\nimport { getState, subscribeToState } from '../core/state'\n\n/**\n * React hook for subscribing to session key state\n * \n * @example\n * ```tsx\n * import { useSessionKeyState } from '@tenprotocol/session-keys/react'\n * \n * function MyComponent() {\n * const { sessionKey, isActive, balance, isLoading, error } = useSessionKeyState()\n * \n * return (\n * <div>\n * <p>Session Key: {sessionKey}</p>\n * <p>Active: {isActive ? 'Yes' : 'No'}</p>\n * <p>Balance: {balance?.eth} ETH</p>\n * {isLoading && <p>Loading...</p>}\n * {error && <p>Error: {error.message}</p>}\n * </div>\n * )\n * }\n * ```\n */\nexport const useSessionKeyState = (): SessionKeyState => {\n const [state, setState] = useState<SessionKeyState>(getState)\n\n useEffect(() => {\n const unsubscribe = subscribeToState(setState)\n return unsubscribe\n }, [])\n\n return state\n}","import type { SessionKeyState, StateSubscriber } from '../types'\n\n// Internal state\nlet state: SessionKeyState = {\n sessionKey: null,\n isActive: false,\n balance: null,\n isLoading: false,\n error: null\n}\n\n// Subscribers\nconst subscribers = new Set<StateSubscriber>()\n\n// Simple mutex for state updates\nlet isUpdating = false\n\n// Load persisted state on init\ntry {\n const persisted = localStorage.getItem('ten-session-key-state')\n if (persisted) {\n const parsed = JSON.parse(persisted)\n state = {\n ...state,\n sessionKey: parsed.sessionKey,\n isActive: parsed.isActive\n }\n }\n} catch (error) {\n console.warn('Failed to load persisted state:', error)\n}\n\nexport const getState = (): SessionKeyState => ({ ...state })\n\nexport const updateState = async (updates: Partial<SessionKeyState>): Promise<void> => {\n // Wait if another update is in progress\n while (isUpdating) {\n await new Promise(resolve => setTimeout(resolve, 50))\n }\n \n try {\n isUpdating = true\n state = { ...state, ...updates }\n \n // Persist key state changes\n if ('sessionKey' in updates || 'isActive' in updates) {\n try {\n localStorage.setItem('ten-session-key-state', JSON.stringify({\n sessionKey: state.sessionKey,\n isActive: state.isActive\n }))\n } catch (error) {\n console.warn('Failed to persist state:', error)\n }\n }\n\n // Notify all subscribers\n subscribers.forEach(callback => {\n try {\n callback(getState())\n } catch (error) {\n console.error('Error in state subscriber:', error)\n }\n })\n } finally {\n isUpdating = false\n }\n}\n\nexport const subscribeToState = (callback: StateSubscriber): (() => void) => {\n subscribers.add(callback)\n return () => {\n subscribers.delete(callback)\n }\n}\n\nexport const clearPersistedState = (): void => {\n try {\n localStorage.removeItem('ten-session-key-state')\n } catch (error) {\n console.warn('Failed to clear persisted state:', error)\n }\n}\n\n// State getters\nexport const getSessionKey = (): string | null => state.sessionKey\nexport const getIsActive = (): boolean => state.isActive\nexport const getBalance = (): SessionKeyState['balance'] => state.balance\nexport const getIsLoading = (): boolean => state.isLoading\nexport const getError = (): Error | null => state.error"],"mappings":"AAAA,OAAS,YAAAA,EAAU,aAAAC,MAAiB,QCGpC,IAAIC,EAAyB,CAC3B,WAAY,KACZ,SAAU,GACV,QAAS,KACT,UAAW,GACX,MAAO,IACT,EAGMC,EAAc,IAAI,IAMxB,GAAI,CACF,IAAMC,EAAY,aAAa,QAAQ,uBAAuB,EAC9D,GAAIA,EAAW,CACb,IAAMC,EAAS,KAAK,MAAMD,CAAS,EACnCE,EAAQ,CACN,GAAGA,EACH,WAAYD,EAAO,WACnB,SAAUA,EAAO,QACnB,CACF,CACF,OAASE,EAAO,CACd,QAAQ,KAAK,kCAAmCA,CAAK,CACvD,CAEO,IAAMC,EAAW,KAAwB,CAAE,GAAGF,CAAM,GAqCpD,IAAMG,EAAoBC,IAC/BC,EAAY,IAAID,CAAQ,EACjB,IAAM,CACXC,EAAY,OAAOD,CAAQ,CAC7B,GD/CK,IAAME,EAAqB,IAAuB,CACvD,GAAM,CAACC,EAAOC,CAAQ,EAAIC,EAA0BC,CAAQ,EAE5D,OAAAC,EAAU,IACYC,EAAiBJ,CAAQ,EAE5C,CAAC,CAAC,EAEED,CACT","names":["useState","useEffect","state","subscribers","persisted","parsed","state","error","getState","subscribeToState","callback","subscribers","useSessionKeyState","state","setState","useState","getState","useEffect","subscribeToState"]}
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "@tenprotocol/session-keys",
3
+ "version": "1.0.0",
4
+ "description": "Framework-agnostic session key management for TEN Protocol",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ },
14
+ "./react": {
15
+ "types": "./dist/react.d.ts",
16
+ "import": "./dist/react.mjs",
17
+ "require": "./dist/react.js"
18
+ }
19
+ },
20
+ "files": [
21
+ "dist"
22
+ ],
23
+ "scripts": {
24
+ "build": "tsup",
25
+ "dev": "tsup --watch",
26
+ "typecheck": "tsc --noEmit",
27
+ "prepublishOnly": "npm run build"
28
+ },
29
+ "keywords": [
30
+ "ethereum",
31
+ "ten",
32
+ "session-keys",
33
+ "blockchain",
34
+ "web3",
35
+ "privacy"
36
+ ],
37
+ "author": "TEN Protocol",
38
+ "license": "MIT",
39
+ "dependencies": {
40
+ "rlp": "^3.0.0"
41
+ },
42
+ "devDependencies": {
43
+ "@types/node": "^20.17.57",
44
+ "@types/react": "^18.3.23",
45
+ "tsup": "^8.5.0",
46
+ "typescript": "^5.8.3"
47
+ },
48
+ "peerDependencies": {
49
+ "react": ">=16.8.0"
50
+ },
51
+ "peerDependenciesMeta": {
52
+ "react": {
53
+ "optional": true
54
+ }
55
+ }
56
+ }