New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@argent/x-sessions

Package Overview
Dependencies
Maintainers
0
Versions
74
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@argent/x-sessions

Manage sessions for Argent X wallets

  • 7.0.0
  • next
  • latest
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
1.3K
decreased by-4.86%
Maintainers
0
Weekly downloads
 
Created
Source

Sessions

Sessions can be used to send transactions from a dapp on behalf of a user without requiring their confirmation with a wallet.

The user is guaranteed that the dapp can only execute transactions that comply to the policies of the session and until the session expires.

Installation

npm install @argent/x-sessions
# or
pnpm add @argent/x-sessions

Demo Dapp

A demo dapp using both sessions and offchain sessions can be found here https://github.com/argentlabs/session-keys-example-dapp

Session keys

Creating an Argent session account

First you need to have a deployed account. This is the account that will authorise the session and interact with the contracts of your dapp.

To sign the session message the method needed is createSession. After the user sign the message, a session account can be created using buildSessionAccount.

This example session will allow the dapp to execute an example endpoint on an example contract without asking the user to approve the transaction again. After signing the session the dapp can execute all transactions listed in allowedMethods whenever it wants and as many times as it wants.

The list of allowedMethods needs to be communicated with Argent, in order to be whitelisted.

export interface AllowedMethod {
  "Contract Address": string
  selector: string
}

export type MetadataTxFee = {
  tokenAddress: string
  maxAmount: string
}

export type SessionMetadata = {
  projectID: string
  txFees: MetadataTxFee[]
  projectSignature?: Signature
}

type CreateSessionParams = {
  sessionKey?: Uint8Array // this is optional. This sdk generate a sessionKey using ec.starkCurve.utils.randomPrivateKey() if not provided
  allowedMethods: AllowedMethod[]
  expiry: bigint
  metaData: SessionMetadata
}

The following snippet show how to create and use a session account

import {
  SignSessionError,
  CreateSessionParams,
  createSession,
  buildSessionAccount,
  bytesToHexString
} from "@argent/x-sessions"
import { ec } from "starknet"

const privateKey = ec.starkCurve.utils.randomPrivateKey()

const sessionKey: SessionKey = {
  privateKey: bytesToHexString(privateKey),
  publicKey: ec.starkCurve.getStarkKey(privateKey)
}

const sessionParams: CreateSessionParams = {
  sessionKey,
  allowedMethods: [
    {
      "Contract Address": contractAddress,
      selector: "method_selector"
    }
  ],
  expiry: Math.floor(
    (Date.now() + 1000 * 60 * 60 * 24) / 1000
  ) as any, // ie: 1 day
  sessionKey: ec.starkCurve.utils.randomPrivateKey(),
  metaData: {
    projectID: "test-dapp",
    txFees: [
      {
        tokenAddress: ETHTokenAddress,
        maxAmount: parseUnits("0.1", 18).value.toString()
      }
    ]
  }
}

// create the session request to get the typed data to be signed
const sessionRequest = createSessionRequest({
  sessionParams,
  chainId
})

// wallet is a StarknetWindowObject
const authorisationSignature = await wallet.request({
  type: "wallet_signTypedData",
  params: sessionRequest.sessionTypedData
})

// open session and sign message
const session = await createSession({
  sessionRequest, // SessionRequest
  address, // Account address
  chainId, // StarknetChainId
  authorisationSignature // Signature
})

const sessionAccount = await buildSessionAccount({
  useCacheAuthorisation: false, // optional and defaulted to false, will be added in future developments
  session,
  sessionKey,
  provider: new RpcProvider({
    nodeUrl: "https://starknet-sepolia.public.blastapi.io/rpc/v0_7",
    chainId: constants.StarknetChainId.SN_SEPOLIA
  }),
  argentSessionServiceBaseUrl: ARGENT_SESSION_SERVICE_BASE_URL // Optional: defaulted to mainnet url
})

try {
  const tx = sessionAccount.execute({
    // lets assume this is a erc20 contract
    contractAddress: "0x...",
    selector: "transfer",
    calldata: [
      "0x..."
      // ...
    ]
  })
} catch (e) {
  console.error((e as SignSessionError).cause, e.message)
}

Execute from outside

Executing transactions “from outside” allows an account to submit transactions on behalf of a user account, as long as they have the relevant signatures.

This package expose a method in order to get the Call required to perform an execution from outside.

const privateKey = ec.starkCurve.utils.randomPrivateKey()

const sessionKey: SessionKey = {
  privateKey: bytesToHexString(privateKey),
  publicKey: ec.starkCurve.getStarkKey(privateKey)
}

const sessionParams: CreateSessionParams = {
  sessionKey,
  allowedMethods: [
    {
      "Contract Address": contractAddress,
      selector: "method_selector"
    }
  ],
  expiry: Math.floor(
    (Date.now() + 1000 * 60 * 60 * 24) / 1000
  ) as any, // ie: 1 day
  sessionKey: ec.starkCurve.utils.randomPrivateKey(),
  metaData: {
    projectID: "test-dapp",
    txFees: [
      {
        tokenAddress: ETHTokenAddress,
        maxAmount: parseUnits("0.1", 18).value.toString()
      }
    ]
  }
}

// create the session request to get the typed data to be signed
const sessionRequest = createSessionRequest({
  sessionParams,
  chainId
})

// wallet is a StarknetWindowObject
const authorisationSignature = await wallet.request({
  type: "wallet_signTypedData",
  params: sessionRequest.sessionTypedData
})

// open session and sign message
const session = await createSession({
  sessionRequest, // SessionRequest
  address, // Account address
  chainId, // StarknetChainId
  authorisationSignature // Signature
})

const sessionAccount = await buildSessionAccount({
  useCacheAuthorisation: false, // optional and defaulted to false, will be added in future developments
  session,
  sessionKey,
  provider: new RpcProvider({
    nodeUrl: "https://starknet-sepolia.public.blastapi.io/rpc/v0_7",
    chainId: constants.StarknetChainId.SN_SEPOLIA
  }),
  argentSessionServiceBaseUrl: ARGENT_SESSION_SERVICE_BASE_URL // Optional: defaulted to mainnet url
})

// example for creating the calldata
const erc20Contract = new Contract(
  Erc20Abi as Abi,
  ETHTokenAddress,
  sessionAccount
)
const calldata = erc20Contract.populate("transfer", {
  recipient: address,
  amount: parseInputAmountToUint256(amount)
})

// get execute from outside data
const { contractAddress, entrypoint, calldata } =
  await createOutsideExecutionCall({
    session,
    sessionKey,
    calls: [transferCallData],
    argentSessionServiceUrl: ARGENT_SESSION_SERVICE_BASE_URL
    network // values "mainnet" | "sepolia", default to "mainnet"
  })

const { signature, outsideExecutionTypedData } =
  await createOutsideExecutionTypedData({
    session,
    sessionKey,
    calls: [transferCallData],
    argentSessionServiceUrl: ARGENT_SESSION_SERVICE_BASE_URL
    network // values "mainnet" | "sepolia", default to "mainnet"
  })

Keywords

FAQs

Package last updated on 23 Dec 2024

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc