# deployContract Source: https://docs.abs.xyz/abstract-global-wallet/agw-client/actions/deployContract Function to deploy a smart contract from the connected Abstract Global Wallet. The [AbstractClient](/abstract-global-wallet/agw-client/createAbstractClient) includes a `deployContract` method that can be used to deploy a smart contract from the connected Abstract Global Wallet. It extends the [deployContract](https://viem.sh/zksync/actions/deployContract) function from Viem to include options for [contract deployment on Abstract](/how-abstract-works/evm-differences/contract-deployment). ## Usage ```tsx import { useAbstractClient } from "@abstract-foundation/agw-react"; import { erc20Abi } from "viem"; // example abi import { abstractTestnet } from "viem/chains"; export default function DeployContract() { const { data: agwClient } = useAbstractClient(); async function deployContract() { if (!agwClient) return; const hash = await agwClient.deployContract({ abi: erc20Abi, // Your smart contract ABI account: agwClient.account, bytecode: "0x...", // Your smart contract bytecode chain: abstractTestnet, args: [], // Constructor arguments }); } } ``` ## Parameters The ABI of the contract to deploy. The bytecode of the contract to deploy. The account to deploy the contract from. Use the `account` from the [AbstractClient](/abstract-global-wallet/agw-client/createAbstractClient) to use the Abstract Global Wallet. The chain to deploy the contract on. e.g. `abstractTestnet`. Constructor arguments to call upon deployment. ```tsx import { deployContract } from "@abstract-foundation/agw-client"; import { contractAbi, contractBytecode } from "./const"; import { agwClient } from "./config"; import { abstractTestnet } from "viem/chains"; const hash = await deployContract({ abi: contractAbi, bytecode: contractBytecode, chain: abstractTestnet, account: agwClient.account, args: [123, "0x1234567890123456789012345678901234567890", true], }); ``` Specifies the type of contract deployment. Defaults to `create`. * `'create'`: Deploys the contract using the `CREATE` opcode. * `'create2'`: Deploys the contract using the `CREATE2` opcode. * `'createAccount'`: Deploys a [smart contract wallet](/how-abstract-works/native-account-abstraction/smart-contract-wallets) using the [ContractDeployer](/how-abstract-works/system-contracts/list-of-system-contracts#contractdeployer)’s `createAccount` function. * `'create2Account'`: Deploys a [smart contract wallet](/how-abstract-works/native-account-abstraction/smart-contract-wallets) using the [ContractDeployer](/how-abstract-works/system-contracts/list-of-system-contracts#contractdeployer)’s `create2Account` function. An array of bytecodes of contracts that are dependencies for the contract being deployed. This is used for deploying contracts that depend on other contracts that are not yet deployed on the network. Learn more on the [Contract deployment page](/how-abstract-works/evm-differences/contract-deployment). ```tsx import { contractAbi, contractBytecode } from "./const"; import { agwClient } from "./config"; import { abstractTestnet } from "viem/chains"; const hash = await agwClient.deployContract({ abi: contractAbi, bytecode: contractBytecode, chain: abstractTestnet, account: agwClient.account, factoryDeps: ["0x123", "0x456"], }); ``` Specifies a unique identifier for the contract deployment. The amount of gas to pay per byte of data on Ethereum. Address of the [paymaster](/how-abstract-works/native-account-abstraction/paymasters) smart contract that will pay the gas fees of the deployment transaction. Must also provide a `paymasterInput` field. Input data to the **paymaster**. Must also provide a `paymaster` field. ```tsx import { contractAbi, contractBytecode } from "./const"; import { agwClient } from "./config"; import { abstractTestnet } from "viem/chains"; import { getGeneralPaymasterInput } from "viem/zksync"; const hash = await agwClient.deployContract({ abi: contractAbi, bytecode: contractBytecode, chain: abstractTestnet, account: agwClient.account, paymaster: "0x5407B5040dec3D339A9247f3654E59EEccbb6391", paymasterInput: getGeneralPaymasterInput({ innerInput: "0x", }), }); ``` ## Returns Returns the `Hex` hash of the transaction that deployed the contract. Use [waitForTransactionReceipt](https://viem.sh/docs/actions/public/waitForTransactionReceipt) to get the transaction receipt from the hash. # sendTransaction Source: https://docs.abs.xyz/abstract-global-wallet/agw-client/actions/sendTransaction Function to send a transaction using the connected Abstract Global Wallet. The [AbstractClient](/abstract-global-wallet/agw-client/createAbstractClient) includes a `sendTransaction` method that can be used to sign and submit a transaction to the chain using the connected Abstract Global Wallet. Transactions are signed by the approved signer account (EOA) of the Abstract Global Wallet and sent `from` the AGW smart contract itself. ## Usage ```tsx import { useAbstractClient } from "@abstract-foundation/agw-react"; export default function SendTransaction() { const { data: agwClient } = useAbstractClient(); async function sendTransaction() { if (!agwClient) return; const hash = await agwClient.sendTransaction({ to: "0x273B3527BF5b607dE86F504fED49e1582dD2a1C6", data: "0x69", }); } } ``` ## Parameters The recipient address of the transaction. The sender address of the transaction. By default, this is set as the Abstract Global Wallet smart contract address. Contract code or a hashed method call with encoded args. Gas provided for transaction execution. Unique number identifying this transaction. Learn more in the [handling nonces](/how-abstract-works/native-account-abstraction/handling-nonces) section. Value in wei sent with this transaction. Total fee per gas in wei (`gasPrice/baseFeePerGas + maxPriorityFeePerGas`). Max priority fee per gas (in wei). The amount of gas to pay per byte of data on Ethereum. An array of bytecodes of contracts that are dependencies for the transaction. Address of the [paymaster](/how-abstract-works/native-account-abstraction/paymasters) smart contract that will pay the gas fees of the transaction. Must also provide a `paymasterInput` field. Input data to the **paymaster**. Must also provide a `paymaster` field. ```tsx import { agwClient } from "./config"; import { getGeneralPaymasterInput } from "viem/zksync"; const transactionHash = await agwClient.sendTransaction({ to: "0x273B3527BF5b607dE86F504fED49e1582dD2a1C6", data: "0x69", paymaster: "0x5407B5040dec3D339A9247f3654E59EEccbb6391", paymasterInput: getGeneralPaymasterInput({ innerInput: "0x", }), }); ``` Custom signature for the transaction. Transaction type. For EIP-712 transactions, this should be `eip712`. ## Returns Returns a `Promise` containing the transaction hash of the submitted transaction. # sendTransactionBatch Source: https://docs.abs.xyz/abstract-global-wallet/agw-client/actions/sendTransactionBatch Function to send a batch of transactions in a single call using the connected Abstract Global Wallet. The [AbstractClient](/abstract-global-wallet/agw-client/createAbstractClient) includes a `sendTransactionBatch` method that can be used to sign and submit multiple transactions in a single call using the connected Abstract Global Wallet. Watch our video tutorials to learn more about building on Abstract. ## Usage ```tsx Example.tsx import { useAbstractClient } from "@abstract-foundation/agw-react"; import { getGeneralPaymasterInput } from "viem/zksync"; import { encodeFunctionData, parseUnits } from "viem"; import { ROUTER_ADDRESS, TOKEN_ADDRESS, WETH_ADDRESS, PAYMASTER_ADDRESS, routerAbi, erc20Abi } from "./config"; export default function SendTransactionBatch() { const { data: agwClient } = useAbstractClient(); async function sendTransactionBatch() { if (!agwClient) return; // Batch an approval and a swap in a single call const hash = await agwClient.sendTransactionBatch({ calls: [ // 1 - Approval { to: TOKEN_ADDRESS, args: [ROUTER_ADDRESS, parseUnits("100", 18)], data: encodeFunctionData({ abi: erc20Abi, functionName: "approve", args: [ROUTER_ADDRESS, parseUnits("100", 18)], }), }, // 2 - Swap { to: ROUTER_ADDRESS, data: encodeFunctionData({ abi: routerAbi, functionName: "swapExactTokensForETH", args: [ parseUnits("100", 18), BigInt(0), [TOKEN_ADDRESS, WETH_ADDRESS], agwClient.account.address, BigInt(Math.floor(Date.now() / 1000) + 60 * 20), ], }), }, ], paymaster: PAYMASTER_ADDRESS, paymasterInput: getGeneralPaymasterInput({ innerInput: "0x", }), }); } } ``` ```tsx config.ts import { parseAbi } from "viem"; export const ROUTER_ADDRESS = "0x07551c0Daf6fCD9bc2A398357E5C92C139724Ef3"; export const TOKEN_ADDRESS = "0xdDD0Fb7535A71CD50E4B8735C0c620D6D85d80d5"; export const WETH_ADDRESS = "0x9EDCde0257F2386Ce177C3a7FCdd97787F0D841d"; export const PAYMASTER_ADDRESS = "0x5407B5040dec3D339A9247f3654E59EEccbb6391"; export const routerAbi = parseAbi([ "function swapExactTokensForETH(uint256,uint256,address[],address,uint256) external" ]); export const erc20Abi = parseAbi([ "function approve(address,uint256) external" ]); ``` ## Parameters An array of transaction requests. Each transaction request can include the following fields: The recipient address of the transaction. The sender address of the transaction. By default, this is set as the Abstract Global Wallet smart contract address. Contract code or a hashed method call with encoded args. Gas provided for transaction execution. Unique number identifying this transaction. Value in wei sent with this transaction. Total fee per gas in wei (`gasPrice/baseFeePerGas + maxPriorityFeePerGas`). Max priority fee per gas (in wei). The amount of gas to pay per byte of data on Ethereum. An array of bytecodes of contracts that are dependencies for the transaction. Custom signature for the transaction. Transaction type. For EIP-712 transactions, this should be `eip712`. Address of the [paymaster](/how-abstract-works/native-account-abstraction/paymasters) smart contract that will pay the gas fees of the transaction batch. Input data to the **paymaster**. ## Returns Returns a `Promise` containing the transaction hash of the submitted transaction batch. # signTransaction Source: https://docs.abs.xyz/abstract-global-wallet/agw-client/actions/signTransaction Function to sign a transaction using the connected Abstract Global Wallet. The [AbstractClient](/abstract-global-wallet/agw-client/createAbstractClient) includes a `signTransaction` method that can be used to sign a transaction using the connected Abstract Global Wallet. Transactions are signed by the approved signer account (EOA) of the Abstract Global Wallet. ## Usage ```tsx import { useAbstractClient } from "@abstract-foundation/agw-react"; export default function SignTransaction() { const { data: agwClient } = useAbstractClient(); async function signTransaction() { if (!agwClient) return; const signature = await agwClient.signTransaction({ to: "0x273B3527BF5b607dE86F504fED49e1582dD2a1C6", data: "0x69", }); } } ``` ## Parameters The recipient address of the transaction. The sender address of the transaction. By default, this is set as the Abstract Global Wallet smart contract address. Contract code or a hashed method call with encoded args. Gas provided for transaction execution. Unique number identifying this transaction. Learn more in the [handling nonces](/how-abstract-works/native-account-abstraction/handling-nonces) section. Value in wei sent with this transaction. Total fee per gas in wei (`gasPrice/baseFeePerGas + maxPriorityFeePerGas`). Max priority fee per gas (in wei). The amount of gas to pay per byte of data on Ethereum. An array of bytecodes of contracts that are dependencies for the transaction. Address of the [paymaster](/how-abstract-works/native-account-abstraction/paymasters) smart contract that will pay the gas fees of the transaction. Must also provide a `paymasterInput` field. Input data to the **paymaster**. Must also provide a `paymaster` field. ```tsx import { agwClient } from "./config"; import { getGeneralPaymasterInput } from "viem/zksync"; const signature = await agwClient.signTransaction({ to: "0x273B3527BF5b607dE86F504fED49e1582dD2a1C6", data: "0x69", paymaster: "0x5407B5040dec3D339A9247f3654E59EEccbb6391", paymasterInput: getGeneralPaymasterInput({ innerInput: "0x", }), }); ``` Custom signature for the transaction. Transaction type. For EIP-712 transactions, this should be `eip712`. ## Returns Returns a `Promise` containing the signed serialized transaction. # writeContract Source: https://docs.abs.xyz/abstract-global-wallet/agw-client/actions/writeContract Function to call functions on a smart contract using the connected Abstract Global Wallet. The [AbstractClient](/abstract-global-wallet/agw-client/createAbstractClient) includes a `writeContract` method that can be used to call functions on a smart contract using the connected Abstract Global Wallet. ## Usage ```tsx import { useAbstractClient } from "@abstract-foundation/agw-react"; import { parseAbi } from "viem"; export default function WriteContract() { const { data: agwClient } = useAbstractClient(); async function writeContract() { if (!agwClient) return; const transactionHash = await agwClient.writeContract({ abi: parseAbi(["function mint(address,uint256) external"]), // Your contract ABI address: "0xC4822AbB9F05646A9Ce44EFa6dDcda0Bf45595AA", functionName: "mint", args: ["0x273B3527BF5b607dE86F504fED49e1582dD2a1C6", BigInt(1)], }); } } ``` ## Parameters The address of the contract to write to. The ABI of the contract to write to. The name of the function to call on the contract. The arguments to pass to the function. The account to use for the transaction. By default, this is set to the Abstract Global Wallet's account. The chain to use for the transaction. By default, this is set to the chain specified in the AbstractClient. The amount of native token to send with the transaction (in wei). Data to append to the end of the calldata. Useful for adding a ["domain" tag](https://opensea.notion.site/opensea/Seaport-Order-Attributions-ec2d69bf455041a5baa490941aad307f). The amount of gas to pay per byte of data on Ethereum. Address of the [paymaster](/how-abstract-works/native-account-abstraction/paymasters) smart contract that will pay the gas fees of the transaction. Input data to the paymaster. Required if `paymaster` is provided. ```tsx import { agwClient } from "./config"; import { parseAbi } from "viem"; const transactionHash = await agwClient.writeContract({ abi: parseAbi(["function mint(address,uint256) external"]), address: "0xC4822AbB9F05646A9Ce44EFa6dDcda0Bf45595AA", functionName: "mint", args: ["0x273B3527BF5b607dE86F504fED49e1582dD2a1C6", BigInt(1)], }); ``` ## Returns Returns a `Promise` containing the transaction hash of the contract write operation. # getSmartAccountAddress FromInitialSigner Source: https://docs.abs.xyz/abstract-global-wallet/agw-client/getSmartAccountAddressFromInitialSigner Function to deterministically derive the deployed Abstract Global Wallet smart account address from the initial signer account. Use the `getSmartAccountAddressFromInitialSigner` function to get the smart contract address of the Abstract Global Wallet that will be deployed given an initial signer account. This is useful if you need to know what the address of the Abstract Global Wallet smart contract will be before it is deployed. ## Import ```tsx import { getSmartAccountAddressFromInitialSigner } from "@abstract-foundation/agw-client"; ``` ## Usage ```tsx import { getSmartAccountAddressFromInitialSigner } from "@abstract-foundation/agw-client"; import { createPublicClient, http } from "viem"; import { abstractTestnet } from "viem/chains"; // Create a public client connected to the desired chain const publicClient = createPublicClient({ chain: abstractTestnet, transport: http(), }); // Initial signer address (EOA) const initialSignerAddress = "0xYourSignerAddress"; // Get the smart account address const smartAccountAddress = await getSmartAccountAddressFromInitialSigner( initialSignerAddress, publicClient ); console.log("Smart Account Address:", smartAccountAddress); ``` ## Parameters The EOA account/signer that will be the owner of the AGW smart contract wallet. A [public client](https://viem.sh/zksync/client) connected to the desired chain (e.g. `abstractTestnet`). ## Returns Returns a `Hex`: The address of the AGW smart contract that will be deployed. ## How it works The smart account address is derived from the initial signer using the following process: ```tsx import AccountFactoryAbi from "./abis/AccountFactory.js"; // ABI of AGW factory contract import { keccak256, toBytes } from "viem"; import { SMART_ACCOUNT_FACTORY_ADDRESS } from "./constants.js"; // Generate salt based off address const addressBytes = toBytes(initialSigner); const salt = keccak256(addressBytes); // Get the deployed account address const accountAddress = (await publicClient.readContract({ address: SMART_ACCOUNT_FACTORY_ADDRESS, // "0xe86Bf72715dF28a0b7c3C8F596E7fE05a22A139c" abi: AccountFactoryAbi, functionName: "getAddressForSalt", args: [salt], })) as Hex; ``` This function returns the determined AGW smart contract address using the [Contract Deployer](/how-abstract-works/system-contracts/list-of-system-contracts#contractdeployer)’s `getNewAddressForCreate2` function. # createSession Source: https://docs.abs.xyz/abstract-global-wallet/agw-client/session-keys/createSession Function to create a session key for the connected Abstract Global Wallet. The [AbstractClient](/abstract-global-wallet/agw-client/createAbstractClient) includes a `createSession` method that can be used to create a session key for the connected Abstract Global Wallet. ## Usage ```tsx call-policies.ts // This example demonstrates how to create a session key for NFT minting on a specific contract. // The session key: // - Can only call the mint function on the specified NFT contract // - Has a lifetime gas fee limit of 1 ETH // - Expires after 24 hours import { useAbstractClient } from "@abstract-foundation/agw-react"; import { LimitType } from "@abstract-foundation/agw-client/sessions"; import { toFunctionSelector, parseEther } from "viem"; import { privateKeyToAccount, generatePrivateKey } from "viem/accounts"; // Generate a new session key pair const sessionPrivateKey = generatePrivateKey(); const sessionSigner = privateKeyToAccount(sessionPrivateKey); export default function CreateSession() { const { data: agwClient } = useAbstractClient(); async function createSession() { if (!agwClient) return; const { session } = await agwClient.createSession({ session: { signer: sessionSigner.address, expiresAt: BigInt(Math.floor(Date.now() / 1000) + 60 * 60 * 24), feeLimit: { limitType: LimitType.Lifetime, limit: parseEther("1"), period: BigInt(0), }, callPolicies: [ { target: "0xC4822AbB9F05646A9Ce44EFa6dDcda0Bf45595AA", // NFT contract selector: toFunctionSelector("mint(address,uint256)"), valueLimit: { limitType: LimitType.Unlimited, limit: BigInt(0), period: BigInt(0), }, maxValuePerUse: BigInt(0), constraints: [], } ], transferPolicies: [], }, }); } } ``` ```tsx transfer-policies.ts // This example shows how to create a session key that can only transfer ETH to specific addresses. // It sets up two recipients with different limits: one with a daily allowance, // and another with a lifetime limit on total transfers. import { useAbstractClient } from "@abstract-foundation/agw-react"; import { LimitType } from "@abstract-foundation/agw-client/sessions"; import { parseEther } from "viem"; import { privateKeyToAccount, generatePrivateKey } from "viem/accounts"; // Generate a new session key pair const sessionPrivateKey = generatePrivateKey(); const sessionSigner = privateKeyToAccount(sessionPrivateKey); export default function CreateSession() { const { data: agwClient } = useAbstractClient(); async function createSession() { if (!agwClient) return; const { session } = await agwClient.createSession({ session: { signer: sessionSigner.address, expiresAt: BigInt(Math.floor(Date.now() / 1000) + 60 * 60 * 24 * 7), // 1 week feeLimit: { limitType: LimitType.Lifetime, limit: parseEther("0.1"), period: BigInt(0), }, callPolicies: [], transferPolicies: [ { target: "0x1234567890123456789012345678901234567890", // Allowed recipient 1 maxValuePerUse: parseEther("0.1"), // Max 0.1 ETH per transfer valueLimit: { limitType: LimitType.Allowance, limit: parseEther("1"), // Max 1 ETH per day period: BigInt(60 * 60 * 24), // 24 hours }, }, { target: "0x9876543210987654321098765432109876543210", // Allowed recipient 2 maxValuePerUse: parseEther("0.5"), // Max 0.5 ETH per transfer valueLimit: { limitType: LimitType.Lifetime, limit: parseEther("2"), // Max 2 ETH total period: BigInt(0), }, } ], }, }); } } ``` ## Parameters Configuration for the session key, including: The address that will be allowed to sign transactions (session public key). Unix timestamp when the session key expires. Maximum gas fees that can be spent using this session key. The type of limit to apply: * `LimitType.Unlimited` (0): No limit * `LimitType.Lifetime` (1): Total limit over the session lifetime * `LimitType.Allowance` (2): Limit per time period The maximum amount allowed. The time period in seconds for allowance limits. Set to 0 for Unlimited/Lifetime limits. Array of policies defining which contract functions can be called. The contract address that can be called. The function selector that can be called on the target contract. The limit on the amount of native tokens that can be sent with the call. Maximum value that can be sent in a single transaction. Array of constraints on function parameters. The index of the parameter to constrain. The type of constraint: * `Unconstrained` (0) * `Equal` (1) * `Greater` (2) * `Less` (3) * `GreaterEqual` (4) * `LessEqual` (5) * `NotEqual` (6) The reference value to compare against. The limit to apply to this parameter. Array of policies defining transfer limits for simple value transfers. The address that can receive transfers. Maximum value that can be sent in a single transfer. The total limit on transfers to this address. ## Returns The transaction hash if a transaction was needed to enable sessions. The created session configuration. # createSessionClient Source: https://docs.abs.xyz/abstract-global-wallet/agw-client/session-keys/createSessionClient Function to create a new SessionClient without an existing AbstractClient. The `createSessionClient` function creates a new `SessionClient` instance directly, without requiring an existing [AbstractClient](/abstract-global-wallet/agw-client/createAbstractClient). If you have an existing [AbstractClient](/abstract-global-wallet/agw-client/createAbstractClient), use the [toSessionClient](/abstract-global-wallet/agw-client/session-keys/toSessionClient) method instead. ## Usage ```tsx example.ts import { createSessionClient } from "@abstract-foundation/agw-client/sessions"; import { abstractTestnet } from "viem/chains"; import { http, parseAbi } from "viem"; import { privateKeyToAccount, generatePrivateKey } from "viem/accounts"; // The session signer (from createSession) const sessionPrivateKey = generatePrivateKey(); const sessionSigner = privateKeyToAccount(sessionPrivateKey); // Create a session client directly const sessionClient = createSessionClient({ account: "0x1234...", // The Abstract Global Wallet address chain: abstractTestnet, signer: sessionSigner, session: { // ... See createSession docs for session configuration options }, transport: http(), // Optional - defaults to http() }); // Use the session client to make transactions const hash = await sessionClient.writeContract({ address: "0xC4822AbB9F05646A9Ce44EFa6dDcda0Bf45595AA", abi: parseAbi(["function mint(address,uint256) external"]), functionName: "mint", args: [address, BigInt(1)], }); ``` ## Parameters The Abstract Global Wallet address or Account object that the session key will act on behalf of. The chain configuration object that supports EIP-712. The session key account that will be used to sign transactions. Must match the signer address in the session configuration. The session configuration created by [createSession](/abstract-global-wallet/agw-client/session-keys/createSession). The transport configuration for connecting to the network. Defaults to HTTP if not provided. ## Returns A new SessionClient instance that uses the session key for signing transactions. All transactions will be validated against the session's policies. # revokeSessions Source: https://docs.abs.xyz/abstract-global-wallet/agw-client/session-keys/revokeSessions Function to revoke session keys from the connected Abstract Global Wallet. The [AbstractClient](/abstract-global-wallet/agw-client/createAbstractClient) includes a `revokeSessions` method that can be used to revoke session keys from the connected Abstract Global Wallet. This allows you to invalidate existing session keys, preventing them from being used for future transactions. ## Usage Revoke session(s) by providing either: * The session configuration object(s) (see [parameters](#parameters)). * The session hash(es) returned by [getSessionHash()](https://github.com/Abstract-Foundation/agw-sdk/blob/ea8db618788c6e93100efae7f475da6f4f281aeb/packages/agw-client/src/sessions.ts#L213). ```tsx import { useAbstractClient } from "@abstract-foundation/agw-react"; export default function RevokeSessions() { const { data: agwClient } = useAbstractClient(); async function revokeSessions() { if (!agwClient) return; // Revoke a single session by passing the session configuration const { transactionHash } = await agwClient.revokeSessions({ session: existingSession, }); // Or - revoke multiple sessions at once const { transactionHash } = await agwClient.revokeSessions({ session: [existingSession1, existingSession2], }); // Or - revoke sessions using their creation transaction hashes const { transactionHash } = await agwClient.revokeSessions({ session: "0x1234...", }); // Or - revoke multiple sessions using their creation transaction hashes const { transactionHash } = await agwClient.revokeSessions({ session: ["0x1234...", "0x5678..."], }); // Or - revoke multiple sessions using both session configuration and creation transaction hashes in the same call const { transactionHash } = await agwClient.revokeSessions({ session: [existingSession, "0x1234..."], }); } } ``` ## Parameters The session(s) to revoke. Can be provided in three formats: * A single `SessionConfig` object * A single session key creation transaction hash from [createSession](/abstract-global-wallet/agw-client/session-keys/createSession). * An array of `SessionConfig` objects and/or session key creation transaction hashes. See [createSession](/abstract-global-wallet/agw-client/session-keys/createSession) for more information on the `SessionConfig` object. ## Returns The transaction hash of the revocation transaction. # toSessionClient Source: https://docs.abs.xyz/abstract-global-wallet/agw-client/session-keys/toSessionClient Function to create an AbstractClient using a session key. The `toSessionClient` function creates a new `SessionClient` instance that can submit transactions and perform actions (e.g. [writeContract](/abstract-global-wallet/agw-client/actions/writeContract)) from the Abstract Global wallet signed by a session key. If a transaction violates any of the session key’s policies, it will be rejected. ## Usage ```tsx import { useAbstractClient } from "@abstract-foundation/agw-react"; import { parseAbi } from "viem"; import { abstractTestnet } from "viem/chains"; import { useAccount } from "wagmi"; export default function Example() { const { address } = useAccount(); const { data: agwClient } = useAbstractClient(); async function sendTransactionWithSessionKey() { if (!agwClient || !address) return; // Use the existing session signer and session that you created with useCreateSession // Likely you want to store these inside a database or solution like AWS KMS and load them const sessionClient = agwClient.toSessionClient(sessionSigner, session); const hash = await sessionClient.writeContract({ abi: parseAbi(["function mint(address,uint256) external"]), account: sessionClient.account, chain: abstractTestnet, address: "0xC4822AbB9F05646A9Ce44EFa6dDcda0Bf45595AA", functionName: "mint", args: [address, BigInt(1)], }); } return ; } ``` ## Parameters The account that will be used to sign transactions. This must match the signer address specified in the session configuration. The session configuration created by [createSession](/abstract-global-wallet/agw-client/session-keys/createSession). ## Returns A new AbstractClient instance that uses the session key for signing transactions. All transactions will be validated against the session's policies. # transformEIP1193Provider Source: https://docs.abs.xyz/abstract-global-wallet/agw-client/transformEIP1193Provider Function to transform an EIP1193 provider into an Abstract Global Wallet client. The `transformEIP1193Provider` function transforms a standard [EIP1193 provider](https://eips.ethereum.org/EIPS/eip-1193) into an Abstract Global Wallet (AGW) compatible provider. This allows you to use existing wallet providers with Abstract Global Wallet. ## Import ```tsx import { transformEIP1193Provider } from "@abstract-foundation/agw-client"; ``` ## Usage ```tsx import { transformEIP1193Provider } from "@abstract-foundation/agw-client"; import { abstractTestnet } from "viem/chains"; import { getDefaultProvider } from "ethers"; // Assume we have an EIP1193 provider const originalProvider = getDefaultProvider(); const agwProvider = transformEIP1193Provider({ provider: originalProvider, chain: abstractTestnet, }); // Now you can use agwProvider as a drop-in replacement ``` ## Parameters An object containing the following properties: The original EIP1193 provider to be transformed. The blockchain network to connect to. An optional custom transport layer. If not provided, it will use the default transport based on the provider. ## Returns An `EIP1193Provider` instance with modified behavior for specific JSON-RPC methods to be compatible with the Abstract Global Wallet. ## How it works The `transformEIP1193Provider` function wraps the original provider and intercepts specific Ethereum JSON-RPC methods: 1. `eth_accounts`: Returns the smart account address along with the original signer address. 2. `eth_signTransaction` and `eth_sendTransaction`: * If the transaction is from the original signer, it passes through to the original provider. * If it's from the smart account, it uses the AGW client to handle the transaction. For all other methods, it passes the request through to the original provider. # getLinkedAccounts Source: https://docs.abs.xyz/abstract-global-wallet/agw-client/wallet-linking/getLinkedAccounts Function to get all Ethereum wallets linked to an Abstract Global Wallet. The [AbstractClient](/abstract-global-wallet/agw-client/createAbstractClient) includes a `getLinkedAccounts` method that can be used to retrieve all Ethereum Mainnet wallets that have been linked to an Abstract Global Wallet. ## Usage ```tsx import { useAbstractClient } from "@abstract-foundation/agw-react"; export default function CheckLinkedAccounts() { const { data: agwClient } = useAbstractClient(); async function checkLinkedAccounts() { if (!agwClient) return; // Get all linked Ethereum Mainnet wallets for an AGW const { linkedAccounts } = await agwClient.getLinkedAccounts({ agwAddress: "0x273B3527BF5b607dE86F504fED49e1582dD2a1C6", // The AGW to check }); console.log("Linked accounts:", linkedAccounts); } return ; } ``` ## Parameters The address of the Abstract Global Wallet to check for linked accounts. ## Returns An array of Ethereum wallet addresses that are linked to the AGW. # getLinkedAgw Source: https://docs.abs.xyz/abstract-global-wallet/agw-client/wallet-linking/getLinkedAgw Function to get the linked Abstract Global Wallet for an Ethereum Mainnet address. The `getLinkedAgw` function is available when extending a [Viem Client](https://viem.sh/docs/clients/custom.html) with `linkableWalletActions`. It can be used to check if an Ethereum Mainnet address has linked an Abstract Global Wallet. ## Usage ```tsx import { linkableWalletActions } from "@abstract-foundation/agw-client"; import { createWalletClient, custom } from "viem"; import { sepolia } from "viem/chains"; export default function CheckLinkedWallet() { async function checkLinkedWallet() { // Initialize a Viem Wallet client: (https://viem.sh/docs/clients/wallet) // And extend it with linkableWalletActions const client = createWalletClient({ chain: sepolia, transport: custom(window.ethereum!), }).extend(linkableWalletActions()); // Check if an address has a linked AGW const { agw } = await client.getLinkedAgw(); if (agw) { console.log("Linked AGW:", agw); } else { console.log("No linked AGW found"); } } return ; } ``` ## Parameters The Ethereum Mainnet address to check for a linked AGW. If not provided, defaults to the connected account's address. ## Returns The address of the linked Abstract Global Wallet, or `undefined` if no AGW is linked. # linkToAgw Source: https://docs.abs.xyz/abstract-global-wallet/agw-client/wallet-linking/linkToAgw Function to link an Ethereum Mainnet wallet to an Abstract Global Wallet. The [AbstractClient](/abstract-global-wallet/agw-client/createAbstractClient) includes a `linkToAgw` method that can be used to create a link between an Ethereum Mainnet wallet and an Abstract Global Wallet. ## Usage ```tsx import { linkableWalletActions } from "@abstract-foundation/agw-client"; import { createWalletClient, custom } from "viem"; import { sepolia, abstractTestnet } from "viem/chains"; export default function LinkWallet() { async function linkAgwWallet() { // Initialize a Viem Wallet client: (https://viem.sh/docs/clients/wallet) // And extend it with linkableWalletActions const client = createWalletClient({ chain: sepolia, transport: custom(window.ethereum!), }).extend(linkableWalletActions()); // Call linkToAgw with the AGW address const { l1TransactionHash, getL2TransactionHash } = await client.linkToAgw({ agwAddress: "0x...", // The AGW address to link to enabled: true, // Enable or disable the link l2Chain: abstractTestnet, }); // Get the L2 transaction hash once the L1 transaction is confirmed const l2Hash = await getL2TransactionHash(); } return ; } ``` ## Parameters The address of the Abstract Global Wallet to link to. Whether to enable or disable the link between the wallets. The Abstract chain to create the link on (e.g. `abstractTestnet`). The account to use for the transaction. ## Returns The transaction hash of the L1 transaction that initiated the link. A function that returns a Promise resolving to the L2 transaction hash once the L1 transaction is confirmed. # Wallet Linking Source: https://docs.abs.xyz/abstract-global-wallet/agw-client/wallet-linking/overview Link wallets from Ethereum Mainnet to the Abstract Global Wallet. You may want to allow users to perform actions with their Abstract Global Wallet (AGW) based on information from their Ethereum Mainnet wallet, for example to: * Check if a user is whitelisted for an NFT mint based on their Ethereum Mainnet wallet. * Read what NFTs or tokens the user holds in their Ethereum Mainnet wallet. For these use cases, Abstract provides the [DelegateRegistry](https://sepolia.abscan.org/address/0x0000000059A24EB229eED07Ac44229DB56C5d797#code#F1#L16) contract that allows users to create a *link* between their Ethereum Mainnet wallet and their AGW. This link is created by having users sign a transaction on Ethereum Mainnet that includes their Abstract Global Wallet address; creating a way for applications to read what wallets are linked to an AGW. The linking process is available in the SDK to enable you to perform the link in your application, however users can also perform the link directly on [Abstract’s Global Linking page](https://link.abs.xyz/). Link an Ethereum Mainnet wallet to your Abstract Global Wallet. Link a Sepolia Testnet wallet to your testnet Abstract Global Wallet. ## How It Works On Ethereum Mainnet, users submit a transaction that calls the [delegateAll](https://sepolia.abscan.org/address/0x0000000059A24EB229eED07Ac44229DB56C5d797#code#F1#L44) function on the [DelegateRegistry](https://sepolia.abscan.org/address/0x0000000059A24EB229eED07Ac44229DB56C5d797#code#F1#L16) contract to initialize a link between their Ethereum Mainnet wallet and their Abstract Global Wallet: Once submitted, the delegation information is bridged from Ethereum to Abstract via the [BridgeHub](https://sepolia.abscan.org/address/0x35A54c8C757806eB6820629bc82d90E056394C92) contract to become available on Abstract. You can trigger this flow in your application by using the [linkToAgw](/abstract-global-wallet/agw-client/wallet-linking/linkToAgw) function. To view the linked EOAs for an AGW and vice versa, the [ExclusiveDelegateResolver](https://sepolia.abscan.org/address/0x0000000078CC4Cc1C14E27c0fa35ED6E5E58825D#code#F1#L19) contract can be used, which contains the following functions to read delegation information: Given an EOA address as input, returns either: * ✅ If the EOA has an AGW linked: the AGW address. * ❌ If the EOA does not have an AGW linked: the EOA address. Use this to check if an EOA has an AGW linked, or to validate that an AGW is performing a transaction on behalf of a linked EOA ```solidity function exclusiveWalletByRights( address vault, // The EOA address bytes24 rights // The rights identifier to check ) returns (address) ``` Use the following `rights` value to check the AGW link: ```solidity bytes24 constant _AGW_LINK_RIGHTS = bytes24(keccak256("AGW_LINK")); ``` Given an AGW address as input, returns a list of L1 wallets that have linked to the AGW. Use this to check what EOAs have been linked to a specific AGW (can be multiple). ```solidity function delegatedWalletsByRights( address wallet, // The AGW to check delegations for bytes24 rights // The rights identifier to check ) returns (address[]) ``` Use the following `rights` value to check the AGW link: ```solidity bytes24 constant _AGW_LINK_RIGHTS = bytes24(keccak256("AGW_LINK")); ``` Given an NFT contract address and token ID as input, returns: * ✅ If the NFT owner has linked an AGW: the AGW address. * ❌ If the NFT owner has not linked an AGW: the NFT owner address. ```solidity function exclusiveOwnerByRights( address contractAddress, // The ERC721 contract address uint256 tokenId, // The token ID to check bytes24 rights // The rights identifier to check ) returns (address) ``` Use the following `rights` value to check the AGW link: ```solidity bytes24 constant _AGW_LINK_RIGHTS = bytes24(keccak256("AGW_LINK")); ``` This information can be read using the SDK methods; [getLinkedAgw](/abstract-global-wallet/agw-client/wallet-linking/getLinkedAgw) and [getLinkedAccounts](/abstract-global-wallet/agw-client/wallet-linking/getLinkedAccounts). # Reading Wallet Links in Solidity Source: https://docs.abs.xyz/abstract-global-wallet/agw-client/wallet-linking/reading-links-in-solidity How to read links between Ethereum wallets and Abstract Global Wallets in Solidity. The [ExclusiveDelegateResolver](https://sepolia.abscan.org/address/0x0000000078CC4Cc1C14E27c0fa35ED6E5E58825D#code#F1#L19) contract provides functions to read wallet links in your Solidity smart contracts. This allows you to build features like: * Checking if a user has linked their AGW before allowing them to mint an NFT * Allowing users to claim tokens based on NFTs they own in their Ethereum Mainnet wallet ## Reading Links First, define the rights identifier used for AGW links: ```solidity bytes24 constant _AGW_LINK_RIGHTS = bytes24(keccak256("AGW_LINK")); IExclusiveDelegateResolver public constant DELEGATE_RESOLVER = IExclusiveDelegateResolver(0x0000000078CC4Cc1C14E27c0fa35ED6E5E58825D); ``` Then use one of the following functions to read link information: ### Check if an EOA has linked an AGW Use `exclusiveWalletByRights` to check if an EOA has an AGW linked: ```solidity function checkLinkedAGW(address eoa) public view returns (address) { // Returns either: // - If EOA has linked an AGW: the AGW address // - If EOA has not linked an AGW: the EOA address return DELEGATE_RESOLVER.exclusiveWalletByRights(eoa, _AGW_LINK_RIGHTS); } ``` ### Check NFT owner's linked AGW Use `exclusiveOwnerByRights` to check if an NFT owner has linked an AGW: ```solidity function checkNFTOwnerAGW(address nftContract, uint256 tokenId) public view returns (address) { // Returns either: // - If NFT owner has linked an AGW: the AGW address // - If NFT owner has not linked an AGW: the NFT owner address return DELEGATE_RESOLVER.exclusiveOwnerByRights(nftContract, tokenId, _AGW_LINK_RIGHTS); } ``` # AbstractWalletProvider Source: https://docs.abs.xyz/abstract-global-wallet/agw-react/AbstractWalletProvider The AbstractWalletProvider component is a wrapper component that provides the Abstract Global Wallet context to your application, allowing you to use hooks and components. Wrap your application in the `AbstractWalletProvider` component to enable the use of the package's hooks and components throughout your application. [Learn more on the Native Integration guide](/abstract-global-wallet/agw-react/native-integration). ```tsx import { AbstractWalletProvider } from "@abstract-foundation/agw-react"; import { abstractTestnet, abstract } from "viem/chains"; // Use abstract for mainnet const App = () => { return ( {/* Your application components */} ); }; ``` ## Props The chain to connect to. Must be either `abstractTestnet` or `abstract` (for mainnet). The provider will throw an error if an unsupported chain is provided. Optional. A [Viem Transport](https://viem.sh/docs/clients/transports/http.html) instance to use if you want to connect to a custom RPC URL. If not provided, the default HTTP transport will be used. Optional. A [@tanstack/react-query QueryClient](https://tanstack.com/query/latest/docs/reference/QueryClient#queryclient) instance to use for data fetching. If not provided, a new QueryClient instance will be created with default settings. # useAbstractClient Source: https://docs.abs.xyz/abstract-global-wallet/agw-react/hooks/useAbstractClient Hook for creating and managing an Abstract client instance. Gets the [Wallet client](https://viem.sh/docs/clients/wallet) exposed by the [AbstractWalletProvider](/abstract-global-wallet/agw-react/AbstractWalletProvider) context. Use this client to perform actions from the connected Abstract Global Wallet, for example [deployContract](/abstract-global-wallet/agw-client/actions/deployContract), [sendTransaction](/abstract-global-wallet/agw-client/actions/sendTransaction), [writeContract](/abstract-global-wallet/agw-client/actions/writeContract), etc. ## Import ```tsx import { useAbstractClient } from "@abstract-foundation/agw-react"; ``` ## Usage ```tsx import { useAbstractClient } from "@abstract-foundation/agw-react"; export default function Example() { const { data: abstractClient, isLoading, error } = useAbstractClient(); // Use the client to perform actions such as sending transactions or deploying contracts async function submitTx() { if (!abstractClient) return; const hash = await abstractClient.sendTransaction({ to: "0x8e729E23CDc8bC21c37a73DA4bA9ebdddA3C8B6d", data: "0x69", }); } // ... rest of your component ... } ``` ## Returns Returns a `UseQueryResult`. The [AbstractClient](/abstract-global-wallet/agw-client/createAbstractClient) instance from the [AbstractWalletProvider](/abstract-global-wallet/agw-react/AbstractWalletProvider) context. The timestamp for when the query most recently returned the status as 'success'. The error object for the query, if an error was thrown. Defaults to null. The timestamp for when the query most recently returned the status as 'error'. The sum of all errors. The failure count for the query. Incremented every time the query fails. Reset to 0 when the query succeeds. The failure reason for the query retry. Reset to null when the query succeeds. * fetching: Is true whenever the queryFn is executing, which includes initial pending state as well as background refetches. - paused: The query wanted to fetch, but has been paused. - idle: The query is not fetching. See Network Mode for more information. Boolean variables derived from status. Will be true if the query has been fetched. Will be true if the query has been fetched after the component mounted. This property can be used to not show any previously cached data. Boolean variables derived from fetchStatus. Is `true` whenever the first fetch for a query is in-flight. Is the same as `isFetching && isPending`. Will be `true` if the query failed while fetching for the first time. Will be `true` if the data shown is the placeholder data. Will be `true` if the query failed while refetching. Is true whenever a background refetch is in-flight, which does not include initial `pending`. Is the same as `isFetching && !isPending`. Will be `true` if the data in the cache is invalidated or if the data is older than the given staleTime. A function to manually refetch the query. * `cancelRefetch`: When set to `true`, a currently running request will be canceled before a new request is made. When set to false, no refetch will be made if there is already a request running. Defaults to `true`. * `pending`: if there's no cached data and no query attempt was finished yet. * `error`: if the query attempt resulted in an error. The corresponding error property has the error received from the attempted fetch. * `success`: if the query has received a response with no errors and is ready to display its data. The corresponding data property on the query is the data received from the successful fetch or if the query's enabled property is set to false and has not been fetched yet, data is the first initialData supplied to the query on initialization. # useCreateSession Source: https://docs.abs.xyz/abstract-global-wallet/agw-react/hooks/useCreateSession Hook for creating a session key. Use the `useCreateSession` hook to create a session key for the connected Abstract Global Wallet. ## Import ```tsx import { useCreateSession } from "@abstract-foundation/agw-react"; ``` ## Usage ```tsx import { useCreateSession } from "@abstract-foundation/agw-react"; import { generatePrivateKey, privateKeyToAccount } from "viem/accounts"; import { LimitType } from "@abstract-foundation/agw-client/sessions"; import { toFunctionSelector, parseEther } from "viem"; export default function CreateSessionExample() { const { createSessionAsync } = useCreateSession(); async function handleCreateSession() { const sessionPrivateKey = generatePrivateKey(); const sessionSigner = privateKeyToAccount(sessionPrivateKey); const { session, transactionHash } = await createSessionAsync({ session: { signer: sessionSigner.address, expiresAt: BigInt(Math.floor(Date.now() / 1000) + 60 * 60 * 24), // 24 hours feeLimit: { limitType: LimitType.Lifetime, limit: parseEther("1"), // 1 ETH lifetime gas limit period: BigInt(0), }, callPolicies: [ { target: "0xC4822AbB9F05646A9Ce44EFa6dDcda0Bf45595AA", // Contract address selector: toFunctionSelector("mint(address,uint256)"), // Allowed function valueLimit: { limitType: LimitType.Unlimited, limit: BigInt(0), period: BigInt(0), }, maxValuePerUse: BigInt(0), constraints: [], } ], transferPolicies: [], } }); } return ; } ``` ## Returns Function to create a session key. Returns a Promise that resolves to the created session configuration. ```ts { transactionHash: Hash | undefined; // Transaction hash if deployment was needed session: SessionConfig; // The created session configuration } ``` Async mutation function to create a session key for `async` `await` syntax. Whether the session creation is in progress. Whether the session creation resulted in an error. Error object if the session creation failed. # useGlobalWalletSignerAccount Source: https://docs.abs.xyz/abstract-global-wallet/agw-react/hooks/useGlobalWalletSignerAccount Hook to get the approved signer of the connected Abstract Global Wallet. Use the `useGlobalWalletSignerAccount` hook to retrieve the [account](https://viem.sh/docs/ethers-migration#signers--accounts) approved to sign transactions for the connected Abstract Global Wallet. This is helpful if you need to access the underlying [EOA](https://ethereum.org/en/developers/docs/accounts/#types-of-account) approved to sign transactions for the Abstract Global Wallet smart contract. It uses the [useAccount](https://wagmi.sh/react/api/hooks/useAccount) hook from [wagmi](https://wagmi.sh/) under the hood. ## Import ```tsx import { useGlobalWalletSignerAccount } from "@abstract-foundation/agw-react"; ``` ## Usage ```tsx import { useGlobalWalletSignerAccount } from "@abstract-foundation/agw-react"; export default function App() { const { address, status } = useGlobalWalletSignerAccount(); if (status === "disconnected") return
Disconnected
; if (status === "connecting" || status === "reconnecting") { return
Connecting...
; } return (
Connected to EOA: {address} Status: {status}
); } ``` ## Returns Returns a `UseAccountReturnType`. The specific address of the approved signer account (selected using `useAccount`'s `addresses[1]`). An array of all addresses connected to the application. Information about the currently connected blockchain network. The ID of the current blockchain network. The connector instance used to manage the connection. Indicates if the account is currently connected. Indicates if the account is attempting to reconnect. Indicates if the account is in the process of connecting. Indicates if the account is disconnected. A string representing the connection status of the account to the application. * `'connecting'` attempting to establish connection. * `'reconnecting'` attempting to re-establish connection to one or more connectors. * `'connected'` at least one connector is connected. * `'disconnected'` no connection to any connector. # useGlobalWalletSignerClient Source: https://docs.abs.xyz/abstract-global-wallet/agw-react/hooks/useGlobalWalletSignerClient Hook to get a wallet client instance of the approved signer of the connected Abstract Global Wallet. Use the `useGlobalWalletSignerClient` hook to get a [wallet client](https://viem.sh/docs/clients/wallet) instance that can perform actions from the underlying [EOA](https://ethereum.org/en/developers/docs/accounts/#types-of-account) approved to sign transactions for the Abstract Global Wallet smart contract. This hook is different from [useAbstractClient](/abstract-global-wallet/agw-react/hooks/useAbstractClient), which performs actions (e.g. sending a transaction) from the Abstract Global Wallet smart contract itself, not the EOA approved to sign transactions for it. It uses wagmi’s [useWalletClient](https://wagmi.sh/react/api/hooks/useWalletClient) hook under the hood, returning a [wallet client](https://viem.sh/docs/clients/wallet) instance with the `account` set as the approved EOA of the Abstract Global Wallet. ## Import ```tsx import { useGlobalWalletSignerClient } from "@abstract-foundation/agw-react"; ``` ## Usage ```tsx import { useGlobalWalletSignerClient } from "@abstract-foundation/agw-react"; export default function App() { const { data: client, isLoading, error } = useGlobalWalletSignerClient(); // Use the client to perform actions such as sending transactions or deploying contracts async function submitTx() { if (!client) return; const hash = await client.sendTransaction({ to: "0x8e729E23CDc8bC21c37a73DA4bA9ebdddA3C8B6d", data: "0x69", }); } // ... rest of your component ... } ``` ## Returns Returns a `UseQueryResult`. See [wagmi's useWalletClient](https://wagmi.sh/react/api/hooks/useWalletClient) for more information. The wallet client instance connected to the approved signer of the connected Abstract Global Wallet. The timestamp for when the query most recently returned the status as 'success'. The error object for the query, if an error was thrown. Defaults to null. The timestamp for when the query most recently returned the status as 'error'. The sum of all errors. The failure count for the query. Incremented every time the query fails. Reset to 0 when the query succeeds. The failure reason for the query retry. Reset to null when the query succeeds. * fetching: Is true whenever the queryFn is executing, which includes initial pending state as well as background refetches. - paused: The query wanted to fetch, but has been paused. - idle: The query is not fetching. See Network Mode for more information. Boolean variables derived from status. Will be true if the query has been fetched. Will be true if the query has been fetched after the component mounted. This property can be used to not show any previously cached data. Boolean variables derived from fetchStatus. Is `true` whenever the first fetch for a query is in-flight. Is the same as `isFetching && isPending`. Will be `true` if the query failed while fetching for the first time. Will be `true` if the data shown is the placeholder data. Will be `true` if the query failed while refetching. Is true whenever a background refetch is in-flight, which does not include initial `pending`. Is the same as `isFetching && !isPending`. Will be `true` if the data in the cache is invalidated or if the data is older than the given staleTime. A function to manually refetch the query. * `cancelRefetch`: When set to `true`, a currently running request will be canceled before a new request is made. When set to false, no refetch will be made if there is already a request running. Defaults to `true`. * `pending`: if there's no cached data and no query attempt was finished yet. * `error`: if the query attempt resulted in an error. The corresponding error property has the error received from the attempted fetch. * `success`: if the query has received a response with no errors and is ready to display its data. The corresponding data property on the query is the data received from the successful fetch or if the query's enabled property is set to false and has not been fetched yet, data is the first initialData supplied to the query on initialization. # useLoginWithAbstract Source: https://docs.abs.xyz/abstract-global-wallet/agw-react/hooks/useLoginWithAbstract Hook for signing in and signing out users with Abstract Global Wallet. Use the `useLoginWithAbstract` hook to prompt users to sign up or sign into your application using Abstract Global Wallet and optionally sign out once connected. It uses the following hooks from [wagmi](https://wagmi.sh/) under the hood: * `login`: [useConnect](https://wagmi.sh/react/api/hooks/useConnect). * `logout`: [useDisconnect](https://wagmi.sh/react/api/hooks/useDisconnect). ## Import ```tsx import { useLoginWithAbstract } from "@abstract-foundation/agw-react"; ``` ## Usage ```tsx import { useLoginWithAbstract } from "@abstract-foundation/agw-react"; export default function App() { const { login, logout } = useLoginWithAbstract(); return ; } ``` ## Returns Opens the signup/login modal to prompt the user to connect to the application using Abstract Global Wallet. Disconnects the user's wallet from the application. ## Demo View the [live demo](https://create-abstract-app.vercel.app/) to see Abstract Global Wallet in action. If the user does not have an Abstract Global Wallet, they will be prompted to create one: Abstract Global Wallet with useLoginWithAbstract Light Abstract Global Wallet with useLoginWithAbstract Dark If the user already has an Abstract Global Wallet, they will be prompted to use it to sign in: Abstract Global Wallet with useLoginWithAbstract Light Abstract Global Wallet with useLoginWithAbstract Dark # useRevokeSessions Source: https://docs.abs.xyz/abstract-global-wallet/agw-react/hooks/useRevokeSessions Hook for revoking session keys. Use the `useRevokeSessions` hook to revoke session keys from the connected Abstract Global Wallet, preventing the session keys from being able to execute any further transactions. ## Import ```tsx import { useRevokeSessions } from "@abstract-foundation/agw-react"; ``` ## Usage ```tsx import { useRevokeSessions } from "@abstract-foundation/agw-react"; import type { SessionConfig } from "@abstract-foundation/agw-client/sessions"; export default function RevokeSessionExample() { const { revokeSessionsAsync } = useRevokeSessions(); async function handleRevokeSession() { // Revoke a single session using its configuration await revokeSessionsAsync({ sessions: existingSessionConfig, }); // Revoke a single session using its creation transaction hash await revokeSessionsAsync({ sessions: "0x1234...", }); // Revoke multiple sessions await revokeSessionsAsync({ sessions: [ existingSessionConfig, "0x1234...", anotherSessionConfig ], }); } return ; } ``` ## Returns Function to revoke session keys. Accepts a `RevokeSessionsArgs` object containing: The session(s) to revoke. Can be provided as an array of: * Session configuration objects * Transaction hashes of when the sessions were created * A mix of both session configs and transaction hashes Async function to revoke session keys. Takes the same parameters as `revokeSessions`. Whether the session revocation is in progress. Whether the session revocation resulted in an error. Error object if the session revocation failed. # useWriteContractSponsored Source: https://docs.abs.xyz/abstract-global-wallet/agw-react/hooks/useWriteContractSponsored Hook for interacting with smart contracts using paymasters to cover gas fees. Use the `useWriteContractSponsored` hook to initiate transactions on smart contracts with the transaction gas fees sponsored by a [paymaster](/how-abstract-works/native-account-abstraction/paymasters). It uses the [useWriteContract](https://wagmi.sh/react/api/hooks/useWriteContract) hook from [wagmi](https://wagmi.sh/) under the hood. ## Import ```tsx import { useWriteContractSponsored } from "@abstract-foundation/agw-react"; ``` ## Usage ```tsx import { useWriteContractSponsored } from "@abstract-foundation/agw-react"; import { getGeneralPaymasterInput } from "viem/zksync"; import type { Abi } from "viem"; const contractAbi: Abi = [ /* Your contract ABI here */ ]; export default function App() { const { writeContractSponsored, data, error, isSuccess, isPending } = useWriteContractSponsored(); const handleWriteContract = () => { writeContractSponsored({ abi: contractAbi, address: "0xC4822AbB9F05646A9Ce44EFa6dDcda0Bf45595AA", functionName: "mint", args: ["0x273B3527BF5b607dE86F504fED49e1582dD2a1C6", BigInt(1)], paymaster: "0x5407B5040dec3D339A9247f3654E59EEccbb6391", paymasterInput: getGeneralPaymasterInput({ innerInput: "0x", }), }); }; return (
{isSuccess &&
Transaction Hash: {data}
} {error &&
Error: {error.message}
}
); } ``` ## Returns Returns a `UseWriteContractSponsoredReturnType`. Synchronous function to submit a transaction to a smart contract with gas fees sponsored by a paymaster. Asynchronous function to submit a transaction to a smart contract with gas fees sponsored by a paymaster. The transaction hash of the sponsored transaction. The error if the transaction failed. Indicates if the transaction was successful. Indicates if the transaction is currently pending. Additional context information about the transaction. The number of times the transaction has failed. The reason for the transaction failure, if any. Indicates if the transaction resulted in an error. Indicates if the hook is in an idle state (no transaction has been initiated). Indicates if the transaction processing is paused. A function to clean the mutation internal state (i.e., it resets the mutation to its initial state). The current status of the transaction. * `'idle'` initial status prior to the mutation function executing. * `'pending'` if the mutation is currently executing. * `'error'` if the last mutation attempt resulted in an error. * `'success'` if the last mutation attempt was successful. The timestamp when the transaction was submitted. The submitted transaction details. The variables used for the contract write operation. # ConnectKit Source: https://docs.abs.xyz/abstract-global-wallet/agw-react/integrating-with-connectkit Learn how to integrate Abstract Global Wallet with ConnectKit. The `agw-react` package includes an option to include Abstract Global Wallet as a connection option in the ConnectKit `ConnectKitButton` component. Use our example repo to quickly get started with AGW and ConnectKit. ## Installation Install the required dependencies: ```bash npm install @abstract-foundation/agw-react @abstract-foundation/agw-client wagmi viem connectkit @tanstack/react-query @rainbow-me/rainbowkit ``` ## Usage ### 1. Configure the Providers Wrap your application in the required providers: ```tsx Providers import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { WagmiProvider } from "wagmi"; import { ConnectKitProvider } from "connectkit"; const queryClient = new QueryClient(); export default function AbstractWalletWrapper({ children, }: { children: React.ReactNode; }) { return ( {/* Your application components */} {children} ); } ``` ```tsx Wagmi Config import { createConfig, http } from "wagmi"; import { abstractTestnet, abstract } from "viem/chains"; // Use abstract for mainnet import { abstractWalletConnector } from "@abstract-foundation/agw-react/connectors"; export const config = createConfig({ connectors: [abstractWalletConnector()], chains: [abstractTestnet], transports: { [abstractTestnet.id]: http(), }, ssr: true, }); ``` ### 2. Render the ConnectKitButton Render the [ConnectKitButton](https://docs.family.co/connectkit/connect-button) component anywhere in your application: ```tsx import { ConnectKitButton } from "connectkit"; export default function Home() { return ; } ``` # Dynamic Source: https://docs.abs.xyz/abstract-global-wallet/agw-react/integrating-with-dynamic Learn how to integrate Abstract Global Wallet with Dynamic. The `agw-react` package includes an option to include Abstract Global Wallet as a connection option in the Dynamic `DynamicWidget` component. Use our example repo to quickly get started with AGW and Dynamic. ## Installation Install the required dependencies: ```bash npm install @abstract-foundation/agw-react @abstract-foundation/agw-client @dynamic-labs/sdk-react-core @dynamic-labs/ethereum @dynamic-labs-connectors/abstract-global-wallet-evm viem ``` ## Usage ### 1. Configure the DynamicContextProvider Wrap your application in the [DynamicContextProvider](https://docs.dynamic.xyz/react-sdk/components/dynamiccontextprovider) component: ```tsx Providers import { DynamicContextProvider } from "@dynamic-labs/sdk-react-core"; import { AbstractEvmWalletConnectors } from "@dynamic-labs-connectors/abstract-global-wallet-evm"; import { Chain } from "viem"; import { abstractTestnet, abstract } from "viem/chains"; // Use abstract for mainnet export default function AbstractWalletWrapper({ children, }: { children: React.ReactNode; }) { return ( {children} ); } ``` ```tsx Config import { EvmNetwork } from "@dynamic-labs/sdk-react-core"; import { Chain } from "viem"; import { abstractTestnet, abstract } from "viem/chains"; export function toDynamicChain(chain: Chain, iconUrl: string): EvmNetwork { return { ...chain, networkId: chain.id, chainId: chain.id, nativeCurrency: { ...chain.nativeCurrency, iconUrl: "https://app.dynamic.xyz/assets/networks/eth.svg", }, iconUrls: [iconUrl], blockExplorerUrls: [chain.blockExplorers?.default?.url], rpcUrls: [...chain.rpcUrls.default.http], } as EvmNetwork; } ``` **Next.js App Router:** If you are using [Next.js App Router](https://nextjs.org/docs), create a new component and add the `use client` directive at the top of your file ([see example](https://github.com/Abstract-Foundation/examples/blob/main/agw-dynamic-nextjs/src/components/NextAbstractWalletProvider.tsx)) and wrap your application in this component. ### 2. Render the DynamicWidget Render the [DynamicWidget](https://docs.dynamic.xyz/react-sdk/components/dynamicwidget) component anywhere in your application: ```tsx import { DynamicWidget } from "@dynamic-labs/sdk-react-core"; export default function Home() { return ; } ``` # Privy Source: https://docs.abs.xyz/abstract-global-wallet/agw-react/integrating-with-privy Learn how to integrate Abstract Global Wallet into an existing Privy application [Privy](https://docs.privy.io/guide/react/quickstart) powers the login screen and [EOA creation](/abstract-global-wallet/architecture#eoa-creation) of Abstract Global Wallet, meaning you can use Privy’s features and SDKs natively alongside AGW. The `agw-react` package provides an `AbstractPrivyProvider` component, which wraps your application with the [PrivyProvider](https://docs.privy.io/reference/sdk/react-auth/functions/PrivyProvider) as well as the Wagmi and TanStack Query providers; allowing you to use the features of each library with Abstract Global Wallet. Use our example repo to quickly get started with AGW and Privy. ## Installation Install the required dependencies: ```bash npm install @abstract-foundation/agw-react @abstract-foundation/agw-client wagmi viem @tanstack/react-query ``` ## Usage This section assumes you have already created an app on the [Privy dashboard](https://docs.privy.io/guide/react/quickstart). ### 1. Enable Abstract Integration From the [Privy dashboard](https://dashboard.privy.io/), navigate to **Ecosystem** > **Integrations**. Scroll down to find **Abstract** and toggle the switch to enable the integration. Privy Integration from Dashboard - enable Abstract ### 2. Configure the AbstractPrivyProvider Wrap your application in the `AbstractPrivyProvider` component, providing your Privy app ID as the `appId` prop. ```tsx {1,5,7} import { AbstractPrivyProvider } from "@abstract-foundation/agw-react/privy"; const App = () => { return ( {children} ); }; ``` **Next.js App Router:** If you are using [Next.js App Router](https://nextjs.org/docs), create a new component and add the `use client` directive at the top of your file ([see example](https://github.com/Abstract-Foundation/examples/blob/main/agw-privy-nextjs/src/components/NextAbstractWalletProvider.tsx)) and wrap your application in this component. ### 3. Login users Use the `useAbstractPrivyLogin` hook to prompt users to login with Abstract Global Wallet. ```tsx import { useAbstractPrivyLogin } from "@abstract-foundation/agw-react/privy"; const LoginButton = () => { const { login, link } = useAbstractPrivyLogin(); return ; }; ``` * The `login` function uses Privy's [loginWithCrossAppAccount](https://docs.privy.io/guide/react/cross-app/requester#login) function to authenticate users with their Abstract Global Wallet account. * The `link` function uses Privy's [linkCrossAppAccount](https://docs.privy.io/guide/react/cross-app/requester#linking) function to allow authenticated users to link their existing account to an Abstract Global Wallet. ### 4. Use hooks and functions Once the user has signed in, you can begin to use any of the `agw-react` hooks, such as [useWriteContractSponsored](/abstract-global-wallet/agw-react/hooks/useWriteContractSponsored) as well as all of the existing [wagmi hooks](https://wagmi.sh/react/api/hooks); such as [useAccount](https://wagmi.sh/react/api/hooks/useAccount), [useBalance](https://wagmi.sh/react/api/hooks/useBalance), etc. All transactions will be sent from the connected AGW smart contract wallet (i.e. the `tx.from` address will be the AGW smart contract wallet address). ```tsx import { useAccount, useSendTransaction } from "wagmi"; export default function Example() { const { address, status } = useAccount(); const { sendTransaction, isPending } = useSendTransaction(); return ( ); } ``` # RainbowKit Source: https://docs.abs.xyz/abstract-global-wallet/agw-react/integrating-with-rainbowkit Learn how to integrate Abstract Global Wallet with RainbowKit. The `agw-react` package includes an option to include Abstract Global Wallet as a connection option in your [RainbowKit ConnectButton](https://www.rainbowkit.com/docs/connect-button). Use our example repo to quickly get started with AGW and RainbowKit. ## Installation Install the required dependencies: ```bash npm install @abstract-foundation/agw-react @abstract-foundation/agw-client @rainbow-me/rainbowkit wagmi viem@2.x @tanstack/react-query ``` ## Import The `agw-react` package includes the `abstractWallet` connector you can use to add Abstract Global Wallet as a connection option in your RainbowKit [ConnectButton](https://www.rainbowkit.com/docs/connect-button). ```tsx import { abstractWallet } from "@abstract-foundation/agw-react/connectors"; ``` ## Usage ### 1. Configure the Providers Wrap your application in the following providers: * [WagmiProvider](https://wagmi.sh/react/api/WagmiProvider) from `wagmi`. * [QueryClientProvider](https://tanstack.com/query/latest/docs/framework/react/reference/QueryClientProvider) from `@tanstack/react-query`. * [RainbowKitProvider](https://www.rainbowkit.com/docs/custom-connect-button) from `@rainbow-me/rainbowkit`. ```tsx Providers import { RainbowKitProvider, darkTheme } from "@rainbow-me/rainbowkit"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { WagmiProvider } from "wagmi"; // + import config from your wagmi config const client = new QueryClient(); export default function AbstractWalletWrapper() { return ( {/* Your application components */} ); } ``` ```tsx RainbowKit Config import { connectorsForWallets } from "@rainbow-me/rainbowkit"; import { abstractWallet } from "@abstract-foundation/agw-react/connectors"; export const connectors = connectorsForWallets( [ { groupName: "Abstract", wallets: [abstractWallet], }, ], { appName: "Rainbowkit Test", projectId: "", appDescription: "", appIcon: "", appUrl: "", } ); ``` ```tsx Wagmi Config import { createConfig } from "wagmi"; import { abstractTestnet, abstract } from "wagmi/chains"; // Use abstract for mainnet import { createClient, http } from "viem"; import { eip712WalletActions } from "viem/zksync"; // + import connectors from your RainbowKit config export const config = createConfig({ connectors, chains: [abstractTestnet], client({ chain }) { return createClient({ chain, transport: http(), }).extend(eip712WalletActions()); }, ssr: true, }); ``` ### 2. Render the ConnectButton Render the `ConnectButton` from `@rainbow-me/rainbowkit` anywhere in your app. ```tsx import { ConnectButton } from "@rainbow-me/rainbowkit"; export default function Home() { return ; } ``` # Thirdweb Source: https://docs.abs.xyz/abstract-global-wallet/agw-react/integrating-with-thirdweb Learn how to integrate Abstract Global Wallet with Thirdweb. The `agw-react` package includes an option to include Abstract Global Wallet as a connection option in the thirdweb `ConnectButton` component. Use our example repo to quickly get started with AGW and thirdweb. ## Installation Install the required dependencies: ```bash npm install @abstract-foundation/agw-react @abstract-foundation/agw-client wagmi viem thirdweb ``` ## Usage ### 1. Configure the ThirdwebProvider Wrap your application in the [ThirdwebProvider](https://portal.thirdweb.com/react/v5/ThirdwebProvider) component. ```tsx {1,9,11} import { ThirdwebProvider } from "thirdweb/react"; export default function AbstractWalletWrapper({ children, }: { children: React.ReactNode; }) { return ( {/* Your application components */} ); } ``` **Next.js App Router:** If you are using [Next.js App Router](https://nextjs.org/docs), create a new component and add the `use client` directive at the top of your file ([see example](https://github.com/Abstract-Foundation/examples/blob/main/agw-thirdweb-nextjs/src/components/NextAbstractWalletProvider.tsx)) and wrap your application in this component ([see example](https://github.com/Abstract-Foundation/examples/blob/main/agw-thirdweb-nextjs/src/app/layout.tsx#L51)). ### 2. Render the ConnectButton Render the [ConnectButton](https://portal.thirdweb.com/react/v5/ConnectButton) component anywhere in your application, and include `abstractWallet` in the `wallets` prop. ```tsx import { abstractWallet } from "@abstract-foundation/agw-react/thirdweb"; import { createThirdwebClient } from "thirdweb"; import { abstractTestnet, abstract } from "thirdweb/chains"; // Use abstract for mainnet import { ConnectButton } from "thirdweb/react"; export default function Home() { const client = createThirdwebClient({ clientId: "your-thirdweb-client-id-here", }); return ( ); } ``` # Native Integration Source: https://docs.abs.xyz/abstract-global-wallet/agw-react/native-integration Learn how to integrate Abstract Global Wallet with React. Integrate AGW into an existing React application using the steps below, or [ watch the video tutorial](https://youtu.be/P5lvuBcmisU) for a step-by-step walkthrough. ### 1. Install Abstract Global Wallet Install the required dependencies: ```bash npm install @abstract-foundation/agw-react @abstract-foundation/agw-client wagmi viem@2.x @tanstack/react-query ``` ### 2. Setup the AbstractWalletProvider Wrap your application in the `AbstractWalletProvider` component to enable the use of the package's hooks and components throughout your application. ```tsx import { AbstractWalletProvider } from "@abstract-foundation/agw-react"; import { abstractTestnet, abstract } from "viem/chains"; // Use abstract for mainnet const App = () => { return ( {/* Your application components */} ); }; ``` **Next.js App Router:** If you are using [Next.js App Router](https://nextjs.org/docs), create a new component and add the `use client` directive at the top of your file ([see example](https://github.com/Abstract-Foundation/examples/blob/main/agw-nextjs/src/components/NextAbstractWalletProvider.tsx)) and wrap your application in this component ([see example](https://github.com/Abstract-Foundation/examples/blob/main/agw-nextjs/src/app/layout.tsx#L48-L54)). The `AbstractWalletProvider` wraps your application in both the [WagmiProvider](https://wagmi.sh/react/api/WagmiProvider) and [QueryClientProvider](https://tanstack.com/query/latest/docs/framework/react/reference/QueryClientProvider), meaning you can use the hooks and features of these libraries within your application. ### 3. Login with AGW With the provider setup, prompt users to sign in to your application with their Abstract Global Wallet using the [useLoginWithAbstract](/abstract-global-wallet/agw-react/hooks/useLoginWithAbstract) hook. ```tsx import { useLoginWithAbstract } from "@abstract-foundation/agw-react"; export default function SignIn() { // login function to prompt the user to sign in with AGW. const { login } = useLoginWithAbstract(); return ; } ``` ### 4. Use the Wallet With the AGW connected, prompt the user to approve sending transactions from their wallet. * Use the [Abstract Client](/abstract-global-wallet/agw-react/hooks/useAbstractClient) or Abstract hooks for: * Wallet actions. e.g. [sendTransaction](/abstract-global-wallet/agw-client/actions/sendTransaction), [deployContract](/abstract-global-wallet/agw-client/actions/deployContract), [writeContract](/abstract-global-wallet/agw-client/actions/writeContract) etc. * Smart contract wallet features. e.g. [gas-sponsored transactions](/abstract-global-wallet/agw-react/hooks/useWriteContractSponsored), [session keys](/abstract-global-wallet/agw-client/session-keys/overview), [transaction batches](/abstract-global-wallet/agw-client/actions/sendTransactionBatch). * Use [Wagmi](https://wagmi.sh/) hooks and [Viem](https://viem.sh/) functions for generic blockchain interactions, for example: * Reading data, e.g. Wagmi’s [useAccount](https://wagmi.sh/react/api/hooks/useAccount) and [useBalance](https://wagmi.sh/react/api/hooks/useBalance) hooks. * Writing data, e.g. Wagmi’s [useSignMessage](https://wagmi.sh/react/api/hooks/useSignMessage) and Viem’s [verifyMessage](https://viem.sh/docs/actions/public/verifyMessage.html). ```tsx Abstract Client import { useAbstractClient } from "@abstract-foundation/agw-react"; export default function SendTransactionButton() { // Option 1: Access and call methods directly const { data: client } = useAbstractClient(); async function sendTransaction() { if (!client) return; // Submits a transaction from the connected AGW smart contract wallet. const hash = await client.sendTransaction({ to: "0x273B3527BF5b607dE86F504fED49e1582dD2a1C6", data: "0x69", }); } return ; } ``` ```tsx Abstract Hooks import { useWriteContractSponsored } from "@abstract-foundation/agw-react"; import { parseAbi } from "viem"; import { getGeneralPaymasterInput } from "viem/zksync"; export default function SendTransaction() { const { writeContractSponsoredAsync } = useWriteContractSponsored(); async function sendSponsoredTransaction() { const hash = await writeContractSponsoredAsync({ abi: parseAbi(["function mint(address to, uint256 amount)"]), address: "0xC4822AbB9F05646A9Ce44EFa6dDcda0Bf45595AA", functionName: "mint", args: ["0x273B3527BF5b607dE86F504fED49e1582dD2a1C6", BigInt(1)], paymaster: "0x5407B5040dec3D339A9247f3654E59EEccbb6391", paymasterInput: getGeneralPaymasterInput({ innerInput: "0x", }), }); } return ( ); } ``` ```tsx Wagmi Hooks import { useAccount, useSendTransaction } from "wagmi"; export default function SendTransactionWithWagmi() { const { address, status } = useAccount(); const { sendTransaction, isPending } = useSendTransaction(); return ( ); } ``` # How It Works Source: https://docs.abs.xyz/abstract-global-wallet/architecture Learn more about how Abstract Global Wallet works under the hood. Abstract Global Wallet makes use of [native account abstraction](/how-abstract-works/native-account-abstraction), by creating [smart contract wallets](/how-abstract-works/native-account-abstraction/smart-contract-wallets) for users that have more security and flexibility than traditional EOAs. Users can connect their Abstract Global Wallet to an application by logging in with their email, social account, or existing wallet. Once connected, applications can begin prompting users to approve transactions, which are executed from the user's smart contract wallet. Try the live demo of Abstract Global Wallet to see it in action. ## How Abstract Global Wallet Works Each AGW account must have at least one signer that is authorized to sign transactions on behalf of the smart contract wallet. For this reason, each AGW account is generated in a two-step process: 1. **EOA Creation**: An EOA wallet is created under the hood as the user signs up with their email, social account, or other login methods. 2. **Smart Contract Wallet Creation**: the smart contract wallet is deployed and provided with the EOA address (from the previous step) as an approved signer. Once the smart contract is initialized, the user can freely add and remove signers to the wallets and make use of the [other features](#smart-contract-wallet-features) provided by the AGW. Abstract Global Wallet Architecture Light Abstract Global Wallet Architecture Dark ### EOA Creation First, the user authenticates with their email, social account, or other login method and an EOA wallet (public-private key pair) tied to this login method is created under the hood. This process is powered by [Privy Embedded Wallets](https://docs.privy.io/guide/react/wallets/embedded/creation#automatic). And occurs in a three step process: A random 128-bit value is generated using a [CSPRNG](https://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator). The 128-bit value is converted into a 12-word mnemonic phrase using [BIP-39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki). From this mnemonic phrase, a public-private key pair is derived. The private key is sharded (split) into 3 parts and stored in 3 different locations to ensure security and recovery mechanisms. #### Private Key Sharding The generated private key is split into 3 shards using [Shamir's Secret Sharing](https://en.wikipedia.org/wiki/Shamir%27s_Secret_Sharing) algorithm and stored in 3 different locations. **2 out of 3** shards are required to reconstruct the private key. The three shards are: 1. **Device Share**: This shard is stored on the user's device. In a browser environment, it is stored inside the local storage of the Privy iframe. 2. **Auth Share**: This shard is encrypted and stored on Privy’s servers. It is retrieved when the user logs in with their original login method. 3. **Recovery Share**: This shard is stored in a backup location of the user’s choice, typically a cloud storage account such as Google Drive or iCloud. #### How Shards are Combined To reconstruct the private key, the user must have access to **two out of three** shards. This can be a combination of any two shards, with the most common being the **Device Share** and **Auth Share**. * **Device Share** + **Auth Share**: This is the typical flow; the user authenticates with the Privy server using their original login method (e.g. social account) on their device and the auth share is decrypted. * **Device Share** + **Recovery Share**: If the Privy server is offline or the user has lost access to their original login method (e.g. they no longer have access to their social account), they can use the recovery share to reconstruct the private key. * **Auth Share** + **Recovery Share**: If the user wants to access their account from a new device, a new device share can be generated by combining the auth share and recovery share. ### Smart Contract Wallet Deployment Once an EOA wallet is generated, the public key is provided to a [smart contract wallet](/how-abstract-works/native-account-abstraction/smart-contract-wallets) deployment. The smart contract wallet is deployed and the EOA wallet is added as an authorized signer to the wallet during the initialization process. As all accounts on Abstract are smart contract accounts, (see [native account abstraction](/how-abstract-works/native-account-abstraction)), the smart contract wallet is treated as a first-class citizen when interacting with the Abstract ecosystem. The smart contract wallet that is deployed is a modified fork of [Clave](https://github.com/getclave/clave-contracts) customized to have an `secp256k1` signer by default to support the Privy Embedded Wallet *(as opposed to the default `secp256r1` signer in Clave)* as well as custom validation logic to support [EIP-712](https://eips.ethereum.org/EIPS/eip-712) signatures. #### Smart Contract Wallet Features The smart contract wallet includes many modules to extend the functionality of the wallet, including: * **Recovery Modules**: Allows the user to recover their account if they lose access to their login method via recovery methods including email or guardian recovery. * **Paymaster Support**: Transaction gas fees can be sponsored by [paymasters](/how-abstract-works/native-account-abstraction/paymasters). * **Multiple Signers**: Users can add multiple signers to the wallet to allow for multiple different accounts to sign transactions. * **P256/secp256r1 Support**: Users can add signers generated from [passkeys](https://fidoalliance.org/passkeys/) to authorize transactions. # Frequently Asked Questions Source: https://docs.abs.xyz/abstract-global-wallet/frequently-asked-questions Answers to common questions about Abstract Global Wallet. ### Who holds the private keys to the AGW? As described in the [how it works](/abstract-global-wallet/architecture) section, the private key of the EOA that is the approved signer of the AGW smart contract is generated and split into three shards. * **Device Share**: This shard is stored on the user’s device. In a browser environment, it is stored inside the local storage of the Privy iframe. * **Auth Share**: This shard is encrypted and stored on Privy’s servers. It is retrieved when the user logs in with their original login method. * **Recovery Share**: This shard is stored in a backup location of the user’s choice, typically a cloud storage account such as Google Drive or iCloud. ### Does the user need to create their AGW on the Abstract website? No, users don’t need to leave your application to create their AGW, any application that integrates the wallet connection flow supports both creating a new AGW and connecting an existing AGW. For example, the [live demo](https://create-abstract-app.vercel.app/) showcases how both users without an existing AGW can create one from within the application and existing AGW users can connect their AGW to the application and begin approving transactions. ### Who deploys the AGW smart contracts? A factory smart contract deploys each AGW smart contract. The generated EOA sends the transaction to deploy the AGW smart contract via the factory, and initializes the smart contract with itself as the approved signer. Using the [SDK](/abstract-global-wallet/getting-started), this transaction is sponsored by a [paymaster](/how-abstract-works/native-account-abstraction/paymasters), meaning users don’t need to load their EOA with any funds to deploy the AGW smart contract to get started. ### Does the AGW smart contract work on other chains? Abstract Global Wallet is built on top of [native account abstraction](/how-abstract-works/native-account-abstraction/overview); a feature unique to Abstract. While the smart contract code is EVM-compatible, the SDK is not chain-agnostic and only works on Abstract due to the technical differences between Abstract and other EVM-compatible chains. # Getting Started Source: https://docs.abs.xyz/abstract-global-wallet/getting-started Learn how to integrate Abstract Global Wallet into your application. ## New Projects To kickstart a new project with AGW configured, use our CLI tool: ```bash npx @abstract-foundation/create-abstract-app@latest my-app ``` ## Existing Projects Integrate Abstract Global Wallet into an existing project using one of our integration guides below: } > Add AGW as the native wallet connection option to your React application. } > Integrate AGW into an existing Privy application. } > Integrate AGW as a wallet connection option to an existing ConnectKit application. } > Integrate AGW as a wallet connection option to an existing Dynamic application. } > Integrate AGW as a wallet connection option to an existing RainbowKit application. } > Integrate AGW as a wallet connection option to an existing thirdweb application. # Abstract Global Wallet Source: https://docs.abs.xyz/abstract-global-wallet/overview Discover Abstract Global Wallet, the smart contract wallet powering the Abstract ecosystem. **Create a new application with Abstract Global Wallet configured:** ```bash npx @abstract-foundation/create-abstract-app@latest my-app ``` ## What is Abstract Global Wallet? Abstract Global Wallet (AGW) is a cross-application [smart contract wallet](/how-abstract-works/native-account-abstraction/smart-contract-wallets) that users can create to interact with any application built on Abstract, powered by [native account abstraction](/how-abstract-works/native-account-abstraction). AGW provides a seamless and secure way to onboard users, in which they sign up once using familiar login methods (such as email, social accounts, passkeys and more), and can then use this account to interact with *any* application on Abstract. Integrate Abstract Global Wallet into your application with our SDKs. Learn more about how Abstract Global Wallet works under the hood. **Check out the live demo to see Abstract Global Wallet in action:** Try the live demo of Abstract Global Wallet to see it in action. ## Packages Integrate Abstract Global Wallet (AGW) into your application using the packages below. 1. [agw-react](https://www.npmjs.com/package/@abstract-foundation/agw-react): React hooks and components to prompt users to login with AGW and approve transactions. Built on [Wagmi](https://github.com/wagmi-dev/wagmi). 2. [agw-client](https://www.npmjs.com/package/@abstract-foundation/agw-client): Wallet actions and utility functions that complement the `agw-react` package. Built on [Viem](https://github.com/wagmi-dev/viem). # Going to Production Source: https://docs.abs.xyz/abstract-global-wallet/session-keys/going-to-production Learn how to use session keys in production on Abstract Mainnet. While session keys unlock new ways to create engaging consumer experiences, improper or malicious implementations of session keys create new ways for bad actors to steal assets from users. Session keys are permissionless on **testnet**, however, **mainnet** enforces several security measures to protect users. This document outlines the security restrictions and best practices for using session keys. ## Session Key Policy Registry Session keys are restricted to a whitelist of allowed policies on Abstract Mainnet through the [Session Key Policy Registry contract](https://abscan.org/address/0xA146c7118A46b32aBD0e1ACA41DF4e61061b6b93#code), which manages a whitelist of approved session keys. Applications must pass a security review before being added to the registry to enable the use of session keys for their policies. ### Restricted Session Key Policies Session key policies that request `approve` and/or `setApprovalForAll` functions *must* be passed with additional `constraints` that restrict the approval to a specific contract address. For example, the following policy must include a `constraints` array that restricts the approval to a specific contract address, or will be rejected with "Unconstrained token approval/transfer destination in call policy." ```typescript { target: "0x...", selector: toFunctionSelector("approve(address, uint256)"), // Must include a constraints array that restricts the approval to a specific contract address constraints: [ { condition: ConstraintCondition.Equal, index: 0n, limit: LimitType.Unlimited, refValue: encodeAbiParameters( [{ type: "address" }], ["0x-your-contract-address"] ), }, ], } ``` ## Session Key Signer Accounts Session keys specify a **signer** account; an EOA that is permitted to perform the actions specified in the session configuration. Therefore, the private key of the signer(s) you create are **SENSITIVE VALUES**! Exposing the signer private key enables attackers to execute any of the actions specified in a session configuration for any AGW that has approved a session key with that signer’s address. ```typescript await agwClient.createSession({ session: { signer: sessionSigner.address, // <--- The session key signer account // ... }, }); ``` Below, we provide recommended approaches to implement secure session key signer storage. ### Privy Server Wallets [Privy Server Wallets](https://docs.privy.io/guide/server-wallets/) provide a secure way to create and store signer account(s) for session keys using trusted execution environments (TEEs); ensuring private keys can only ever be reassembled within a secure enclave and never exposed to perform any malicious actions. By using a Privy Server Wallet as the session key signer, attackers cannot compromise the TEE to access the signer account private key to perform any malicious actions. View the example repository for a session key signer implementation using Privy Server Wallets. ### Unique Signer Accounts per Config If you want to store session signer accounts on the client, such as in the browser’s [local storage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) or [IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API), you must create a new unique signer account for each session key to limit the impact of a compromised signer account. If an attacker gains access to a signer account by compromising the user’s client, generating unique signer accounts isolates the attack to a single Abstract Global Wallet. Browser storage methods are vulnerable to Cross-site scripting (XSS) attacks, which can expose the signer account private key to attackers. It is recommended to first **encrypt** the signer account private key before storing it on the client. It is **not acceptable** to use a single signer account stored on the client for all session keys. View the example repository for generating unique signer accounts and storing them encrypted in the browser's local storage. ## Risks of Using Session Keys Temporary keys enable transactions without owner signatures; this functionality introduces several legal risks that developers should be aware of, particularly around security and data management. These include: * If session keys are compromised, they can be used for unauthorized transactions, potentially leading to financial losses. * Failing to follow recommended practices, such as creating new keys per user or managing expiration, could result in security vulnerabilities. * Storing session keys, even when encrypted, risks data breaches. You should comply with applicable data protection laws. # Session keys Source: https://docs.abs.xyz/abstract-global-wallet/session-keys/overview Explore session keys, how to create them, and how to use them with the Abstract Global Wallet. Session keys are temporary keys that are approved to execute a pre-defined set of actions on behalf of an Abstract Global Wallet without requiring the owner to sign each transaction. They unlock seamless user experiences by executing transactions behind the scenes without interrupting the user with popups; powerful for games, mobile apps, and more. ## How session keys work Applications can prompt users to approve the creation of a session key for their Abstract Global Wallet. This session key specifies: * A scoped set of actions that the session key is approved to execute. * A specific EOA account, the **signer**, that is permitted to execute the scoped actions. If the user approves the session key creation, the **signer** account can submit any of the actions within the defined scope without requiring user confirmation; until the session key expires or is revoked.