@tenprotocol/session-keys 1.0.0 → 1.0.1
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/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,2 +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=
|
|
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=8443,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
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +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"]}
|
|
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 = 8443\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
CHANGED
|
@@ -1,2 +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=
|
|
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=8443,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
2
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +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"]}
|
|
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 = 8443\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"]}
|