### Initialize SessionKit Instance Source: https://context7.com/wharfkit/session/llms.txt Demonstrates how to create and configure a SessionKit instance. This involves specifying application name, blockchain chains (with IDs and URLs), a user interface implementation, and wallet plugins. It also shows how to set up storage, session expiration, transaction plugins, and ABIs for contract interactions. Additionally, it includes an example of dynamically updating a chain endpoint. ```typescript import {SessionKit} from '@wharfkit/session' import {WalletPluginPrivateKey} from '@wharfkit/wallet-plugin-privatekey' const sessionKit = new SessionKit({ appName: 'myapp', chains: [ { id: '73e4385a2708e6d7048834fbc1079f2fabb17b3c125b146af438971e90716c4d', url: 'https://jungle4.greymass.com' }, { id: 'aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906', url: 'https://eos.greymass.com' } ], ui: myUserInterface, // Custom UI implementation walletPlugins: [new WalletPluginPrivateKey('5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3')] }, { storage: new BrowserLocalStorage('myapp'), expireSeconds: 300, transactPlugins: [new ResourceProviderPlugin()], abis: [ { account: 'eosio.token', abi: tokenContractAbi } ] }) // Modify chain endpoint dynamically sessionKit.setEndpoint( '73e4385a2708e6d7048834fbc1079f2fabb17b3c125b146af438971e90716c4d', 'https://new-jungle4-endpoint.com' ) ``` -------------------------------- ### Authenticate User and Create Session Source: https://context7.com/wharfkit/session/llms.txt Provides examples for user authentication using SessionKit. It covers a simple login with automatic chain and wallet selection, as well as a more detailed login specifying chain, permission level, wallet plugin, default settings, transaction plugins, and arbitrary data. It also demonstrates how to access the login context and wallet response, and how to restore previous or specific sessions from storage. ```typescript // Simple login with automatic chain/wallet selection const {session, response} = await sessionKit.login() console.log(`Logged in as ${session.actor}@${session.permission}`) console.log(`Chain: ${session.chain.id}`) // Login with specific options const result = await sessionKit.login({ chain: '73e4385a2708e6d7048834fbc1079f2fabb17b3c125b146af438971e90716c4d', permissionLevel: 'teamgreymass@active', walletPlugin: 'wallet-plugin-privatekey', setAsDefault: true, transactPlugins: [customPlugin], arbitrary: {customData: 'passed to wallet plugin'} }) // Access login context and wallet response console.log(`Wallet: ${result.response.chain}`) console.log(`Permission: ${result.response.permissionLevel}`) if (result.response.identityProof) { console.log('Identity proof received') } // Restore previous session from storage const restored = await sessionKit.restore() if (restored) { console.log(`Restored: ${restored.actor}`) } else { console.log('No session found') } // Restore specific session const specific = await sessionKit.restore({ chain: '73e4385a2708e6d7048834fbc1079f2fabb17b3c125b146af438971e90716c4d', actor: 'teamgreymass', permission: 'active' }) ``` -------------------------------- ### UserInterfaceHeadless Implementation for Testing in TypeScript Source: https://github.com/wharfkit/session/wiki/UserInterface-Implementation UserInterfaceHeadless implements the UserInterface for testing purposes, primarily by adding logging. It serves as an example of how to implement the UserInterface. It does not support permission, chain, or wallet selection and throws errors when these methods are called. ```typescript export class UserInterfaceHeadless implements UserInterface { public consoleLog = false public messages: string[] = [] public log(message: string) { if (this.consoleLog) { // eslint-disable-next-line no-console console.info('UserInterfaceHeadless', message) } } onLogin(options?: LoginOptions) { this.log('onLogin: ' + JSON.stringify(options)) } onLoginResult() { this.log('onLoginResult') } public async onSelectPermissionLevel(context: LoginContext): Promise { throw new Error('The headless user interface does not support permission selection') } public async onSelectChain(context: LoginContext): Promise { throw new Error('The headless user interface does not support chain selection') } public async onSelectWallet(context: LoginContext): Promise { throw new Error('The headless user interface does not support wallet selection') } public async onTransact(context: TransactContext) { this.log('onTransact' + String(context.accountName)) } public async onTransactResult(context: TransactResult) { this.log('onTransactResult' + String(context.transaction)) } public status(message: string) { this.messages.push(message) this.log(message) } } ``` -------------------------------- ### Implement Custom Account Creation Plugin - TypeScript Source: https://context7.com/wharfkit/session/llms.txt Extends AbstractAccountCreationPlugin to facilitate new account creation. It defines an ID, name, and configuration, and implements the 'create' method to handle the account creation logic, including generating account names and keys, and calling an external creation service. Dependencies include '@wharfkit/session'. ```typescript // Custom account creation plugin class MyAccountCreator extends AbstractAccountCreationPlugin { get id() { return 'my-account-creator' } get name() { return 'My Account Creator' } config = { requiresChainSelect: true, supportedChains: [ {id: '73e4385a...', url: 'https://jungle4.greymass.com'} ] } async create(context) { // Implement account creation logic const accountName = await this.generateAccountName() const keys = await this.generateKeys() // Call account creation service await fetch('https://api.example.com/create', { method: 'POST', body: JSON.stringify({ account: accountName, publicKey: keys.publicKey }) }) return { chain: context.chain, accountName } } } const kit = new SessionKit({ /* ... */ accountCreationPlugins: [new MyAccountCreator()] }) ``` -------------------------------- ### Create Custom Wallet Plugin (TypeScript) Source: https://context7.com/wharfkit/session/llms.txt Implement custom wallet integrations by extending the AbstractWalletPlugin. This involves defining plugin metadata, supported chains, and handling login, signing, and logout operations. It allows interaction with external wallet services. ```typescript import {AbstractWalletPlugin, WalletPluginLoginResponse, WalletPluginSignResponse} from '@wharfkit/session' import {Checksum256, PermissionLevel, Signature} from '@wharfkit/antelope' class MyWalletPlugin extends AbstractWalletPlugin { get id() { return 'my-wallet-plugin' } config = { requiresChainSelect: false, requiresPermissionSelect: true, supportedChains: ['73e4385a2708e6d7048834fbc1079f2fabb17b3c125b146af438971e90716c4d'] } metadata = { name: 'My Wallet', description: 'Custom wallet integration', logo: {uri: 'https://example.com/logo.png'}, homepage: 'https://example.com', download: 'https://example.com/download' } async login(context) { // Interact with external wallet const account = await this.connectToWallet(context.chain) return { chain: Checksum256.from(context.chain.id), permissionLevel: PermissionLevel.from(`${account}@active`) } } async sign(resolved, context) { // Request signature from wallet const signature = await this.requestSignature(resolved.transaction) return { signatures: [Signature.from(signature)] } } async logout(context) { // Clean up wallet connection await this.disconnectWallet() } async retrievePublicKey(chainId) { return PublicKey.from(await this.getPublicKeyFromWallet(chainId)) } } // Use custom wallet plugin const kit = new SessionKit({ appName: 'myapp', chains: [/* ... */], ui: myUI, walletPlugins: [new MyWalletPlugin()] }) ``` -------------------------------- ### Implement Login Analytics Plugin - TypeScript Source: https://context7.com/wharfkit/session/llms.txt Extends AbstractLoginPlugin to add logging and analytics hooks before and after the login process. It logs login initiation and completion, sending data to analytics endpoints. Dependencies include the '@wharfkit/session' package. ```typescript import {AbstractLoginPlugin} from '@wharfkit/session' class LoginAnalyticsPlugin extends AbstractLoginPlugin { register(context) { // Hook before wallet interaction context.addHook('beforeLogin', async (ctx) => { console.log(`Login initiated for chain: ${ctx.chain?.id}`) await fetch('https://analytics.example.com/login-start', { method: 'POST', body: JSON.stringify({ app: ctx.appName, chain: ctx.chain?.id, timestamp: Date.now() }) }) }) // Hook after successful login context.addHook('afterLogin', async (ctx) => { console.log(`Login completed for ${ctx.permissionLevel}`) await fetch('https://analytics.example.com/login-complete', { method: 'POST', body: JSON.stringify({ app: ctx.appName, actor: ctx.permissionLevel?.actor, timestamp: Date.now() }) }) }) } } const kit = new SessionKit({ /* ... */ loginPlugins: [new LoginAnalyticsPlugin()] }) ``` -------------------------------- ### Create Transaction Plugins with Hooks (TypeScript) Source: https://context7.com/wharfkit/session/llms.txt Extend transaction flows by implementing custom logic using hooks provided by AbstractTransactPlugin. This allows intercepting and modifying transaction stages like pre-signing, post-signing, and post-broadcast. Hooks can access transaction data and UI/storage contexts. ```typescript import {AbstractTransactPlugin} from '@wharfkit/session' class CostWarningPlugin extends AbstractTransactPlugin { get id() { return 'cost-warning-plugin' } register(context) { // Hook before signing context.addHook('beforeSign', async (request, ctx) => { const actions = request.data.actions let totalCost = 0 for (const action of actions) { if (action.account === 'eosio.token' && action.name === 'transfer') { const quantity = action.data.quantity.split(' ')[0] totalCost += parseFloat(quantity) } } if (totalCost > 100) { console.warn(`High transaction cost: ${totalCost}`) ctx.ui?.status(`Warning: Sending ${totalCost} tokens`) } // Return undefined to allow transaction to proceed // Return modified request to change transaction return undefined }) // Hook after signing context.addHook('afterSign', async (result, ctx) => { console.log(`Signed with ${result.signatures.length} signatures`) await ctx.storage?.write('last-tx', result.request.encode()) }) // Hook after broadcast context.addHook('afterBroadcast', async (result, ctx) => { console.log(`Broadcast: ${result.response.transaction_id}`) await fetch('https://api.example.com/log', { method: 'POST', body: JSON.stringify({txid: result.response.transaction_id}) }) }) } } // Use in SessionKit or per-transaction const kit = new SessionKit({ /* ... */ transactPlugins: [new CostWarningPlugin()] }) // Or override per transaction await session.transact({action: /* ... */}, { transactPlugins: [new CostWarningPlugin(), new ResourceProviderPlugin()] }) ``` -------------------------------- ### Manage Active Blockchain Sessions Source: https://context7.com/wharfkit/session/llms.txt Illustrates how to manage active blockchain sessions within the SessionKit. This includes retrieving all stored sessions, restoring all sessions, and logging out specific or all sessions. It also shows how to access properties of a session object like actor, permission, chain URL, and the API client. Additionally, it demonstrates how to store custom data within a session and persist it. ```typescript // Get all stored sessions const sessions = await sessionKit.getSessions() for (const serialized of sessions) { console.log(`${serialized.actor}@${serialized.permission} on ${serialized.chain}`) } // Restore all sessions const activeSessions = await sessionKit.restoreAll() for (const session of activeSessions) { const info = await session.client.v1.chain.get_account(session.actor) console.log(`Balance: ${info.core_liquid_balance}`) } // Logout specific session await sessionKit.logout(session) // Logout all sessions await sessionKit.logout() // Access session properties console.log(`Actor: ${session.actor}`) console.log(`Permission: ${session.permission}`) console.log(`Chain URL: ${session.chain.url}`) console.log(`API Client: ${session.client}`) // Store custom data in session session.data = {preferences: 'dark-mode', lastVisit: Date.now()} await sessionKit.persistSession(session) ``` -------------------------------- ### Use Browser Local Storage - TypeScript Source: https://context7.com/wharfkit/session/llms.txt Demonstrates using the built-in BrowserLocalStorage for session persistence. This class is part of the '@wharfkit/session' package and allows session data to be stored in the browser's local storage. It requires an application name for initialization. ```typescript import {BrowserLocalStorage} from '@wharfkit/session' const browserStorage = new BrowserLocalStorage('myapp') ``` -------------------------------- ### Execute Transactions with WharfKit Session Source: https://context7.com/wharfkit/session/llms.txt Execute blockchain transactions using an authenticated WharfKit session. Supports single actions, multiple actions in one transaction, and custom transaction options like broadcast, expiration, ABIs, and plugins. Outputs transaction details such as transaction ID, block number, signatures, and return values. ```typescript const result = await session.transact({ action: { account: 'eosio.token', name: 'transfer', authorization: [session.permissionLevel], data: { from: session.actor, to: 'teamgreymass', quantity: '1.0000 EOS', memo: 'Payment via Wharf' } } }) console.log(`Transaction ID: ${result.response.transaction_id}`) console.log(`Block: ${result.response.processed.block_num}`) // Multiple actions in one transaction const multiResult = await session.transact({ actions: [ { account: 'eosio.token', name: 'transfer', authorization: [session.permissionLevel], data: {from: session.actor, to: 'alice', quantity: '5.0000 EOS', memo: ''} }, { account: 'eosio.token', name: 'transfer', authorization: [session.permissionLevel], data: {from: session.actor, to: 'bob', quantity: '3.0000 EOS', memo: ''} } ] }) // Transaction with custom options const customResult = await session.transact({ action: { account: 'mycontract', name: 'myaction', authorization: [session.permissionLevel], data: {user: session.actor, value: 42} } }, { broadcast: true, expireSeconds: 600, allowModify: true, abis: [{account: 'mycontract', abi: myContractAbi}], transactPlugins: [resourceProvider, customPlugin] }) // Access transaction details console.log(`Signatures: ${customResult.signatures.length}`) console.log(`Request: ${customResult.request}`) console.log(`Resolved: ${customResult.resolved}`) // Process return values for (const returnVal of customResult.returns) { console.log(`${returnVal.contract}::${returnVal.action} returned:`, returnVal.data) } // Inspect revision history for (const revision of customResult.revisions.revisions) { console.log(`Modified by ${revision.code}: ${revision.modified}`) } ``` -------------------------------- ### Implement Redis Session Storage - TypeScript Source: https://context7.com/wharfkit/session/llms.txt Implements the SessionStorage interface for persisting session data in Redis. It provides methods for writing, reading, and removing data using Redis commands. Dependencies include a Redis client library and '@wharfkit/session'. ```typescript import {SessionStorage} from '@wharfkit/session' class RedisStorage implements SessionStorage { constructor(private redis) {} async write(key: string, data: string): Promise { await this.redis.set(`wharf:${key}`, data) } async read(key: string): Promise { return await this.redis.get(`wharf:${key}`) } async remove(key: string): Promise { await this.redis.del(`wharf:${key}`) } } // Use custom storage const storage = new RedisStorage(redisClient) const kit = new SessionKit({ /* ... */ }, { storage }) ``` -------------------------------- ### TransactContext Class for Transaction Handling in TypeScript Source: https://github.com/wharfkit/session/wiki/UserInterface-Implementation The TransactContext class facilitates UI interactions during transaction calls within the SessionKit. It stores transaction request state and allows plugins to hook into the process. It requires dependencies like AbiProvider, APIClient, Fetch, PermissionLevel, TransactPluginsOptions, and UserInterface. ```typescript /** * Temporary context created for the duration of a [[Session.transact]] call. * * This context is used to store the state of the transact request and * provide a way for plugins to add hooks into the process. */ export class TransactContext { readonly abiProvider: AbiProvider readonly client: APIClient readonly fetch: Fetch readonly hooks: TransactHooks = { afterBroadcast: [], afterSign: [], beforeSign: [], } readonly permissionLevel: PermissionLevel readonly transactPluginsOptions: TransactPluginsOptions readonly ui: UserInterface constructor(options: TransactContextOptions) { this.abiProvider = options.abiProvider this.client = options.client this.fetch = options.fetch this.permissionLevel = options.permissionLevel this.transactPluginsOptions = options.transactPluginsOptions || {} this.ui = options.ui options.transactPlugins?.forEach((plugin: AbstractTransactPlugin) => { plugin.register(this) }) } get accountName(): Name { return this.permissionLevel.actor } get permissionName(): Name { return this.permissionLevel.permission } get esrOptions(): SigningRequestEncodingOptions { return { abiProvider: this.abiProvider, zlib, } } addHook(t: TransactHookTypes, hook: TransactHook) { this.hooks[t].push(hook) } async resolve(request: SigningRequest, expireSeconds = 120): Promise { // TODO: Cache the info/header first time the context resolves? // If multiple plugins resolve the same request and call get_info, tapos might change const info = await this.client.v1.chain.get_info() const header = info.getTransactionHeader(expireSeconds) // Load ABIs required to resolve this request const abis = await request.fetchAbis(this.abiProvider) // Resolve the request and return return request.resolve(abis, this.permissionLevel, header) } } ``` -------------------------------- ### UserInterface Interface Definition in TypeScript Source: https://github.com/wharfkit/session/wiki/UserInterface-Implementation Defines the UserInterface contract that SessionKit utilizes for UI interactions during login and transaction processes. It specifies methods for handling login states, chain and wallet selections, and transaction updates. ```typescript /** * Interface which a [[UserInteface]] plugins must implement. */ export interface UserInterface { // Inform the UI that a login call has started onLogin: (options?: LoginOptions) => void // Inform the UI that a login call has completed onLoginResult: () => void // Ask the user to select a blockchain, and return the chain id onSelectChain: (context: LoginContext) => Promise // Ask the user to select an account, and return the PermissionLevel onSelectPermissionLevel: (context: LoginContext) => Promise // Ask the user to select a wallet, and return the index based on the metadata onSelectWallet: (context: LoginContext) => Promise // Inform the UI that a transact call has started onTransact: (context: TransactContext) => void // Inform the UI that a transact call has completed onTransactResult: (context: TransactResult) => void // Update the displayed modal status from a TransactPlugin status: (message: string) => void } ``` -------------------------------- ### LoginContext Class Definition in TypeScript Source: https://github.com/wharfkit/session/wiki/UserInterface-Implementation Represents the context passed during a SessionKit.login() call, providing the UI with information about the login process. It includes details like available chains, wallet plugins, and hooks for modifying the login flow. ```typescript /** * Temporary context created for the duration of a [[Kit.login]] call. * * This context is used to store the state of the login request and * provide a way for plugins to add hooks into the process. */ export class LoginContext { // client: APIClient chain: ChainDefinition chains: ChainDefinition[] = [] hooks: LoginHooks = { afterLogin: [], beforeLogin: [], } ui: UserInterface walletPlugins: WalletPluginMetadata[] = [] constructor(options: LoginContextOptions) { // this.client = options.client if (options.chains) { this.chains = options.chains } this.chain = options.chain || this.chains[0] this.walletPlugins = options.walletPlugins || [] this.ui = options.ui // options.loginPlugins?.forEach((plugin: AbstractLoginPlugin) => { // plugin.register(this) // }) } addHook(t: LoginHookTypes, hook: LoginHook) { this.hooks[t].push(hook) } } ``` -------------------------------- ### Sign Transactions Offline with WharfKit Session Source: https://context7.com/wharfkit/session/llms.txt Sign blockchain transactions without broadcasting, enabling offline workflows. This involves creating a `Transaction` object, signing it using the session, and then manually broadcasting the signed transaction if needed. Requires `@wharfkit/antelope` for transaction construction. ```typescript import {Transaction} from '@wharfkit/antelope' // Create a complete transaction const transaction = Transaction.from({ expiration: '2025-01-15T12:00:00', ref_block_num: 12345, ref_block_prefix: 67890, max_net_usage_words: 0, max_cpu_usage_ms: 0, delay_sec: 0, context_free_actions: [], actions: [ { account: 'eosio.token', name: 'transfer', authorization: [session.permissionLevel], data: { from: session.actor, to: 'recipient', quantity: '10.0000 EOS', memo: 'offline signing' } } ] }) // Sign without broadcasting const signatures = await session.signTransaction(transaction) console.log(`Signatures: ${signatures.map(s => s.toString())}`) // Manually broadcast later const signed = SignedTransaction.from({ ...transaction, signatures }) const response = await session.client.v1.chain.send_transaction(signed) console.log(`Broadcast result: ${response.transaction_id}`) ``` -------------------------------- ### Serialize and Restore WharfKit Sessions Source: https://context7.com/wharfkit/session/llms.txt Persist and restore WharfKit session state across application restarts. Sessions can be serialized into a JSON-compatible format for storage and then restored using session data. SessionKit can also automatically manage session persistence. ```typescript // Serialize session for storage const serialized = session.serialize() console.log(JSON.stringify(serialized)) // { // "chain": "73e4385a2708e6d7048834fbc1079f2fabb17b3c125b146af438971e90716c4d", // "actor": "teamgreymass", // "permission": "active", // "walletPlugin": { // "id": "wallet-plugin-privatekey", // "data": {} // }, // "data": {"preferences": "dark-mode"} // } // Restore from serialized data const restoredSession = await sessionKit.restore({ chain: serialized.chain, actor: serialized.actor, permission: serialized.permission, walletPlugin: serialized.walletPlugin, data: serialized.data }) // SessionKit handles persistence automatically await sessionKit.persistSession(session, true) // Set as default const sessions = await sessionKit.getSessions() const defaultSession = sessions.find(s => s.default) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.