Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions account-kit/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import type {
RNSignerClient,
} from "@account-kit/react-native-signer";
import type { Connection as SolanaWeb3Connection } from "@solana/web3.js";
import type { PolicyToken } from "@account-kit/infra";

export type SupportedAccountTypes =
| "MultiOwnerLightAccount"
| "LightAccount"
Expand Down Expand Up @@ -73,6 +75,7 @@ export type Connection = {
transport: AlchemyTransportConfig;
chain: Chain;
policyId?: string | string[];
policyToken?: PolicyToken;
};

type RpcConnectionConfig =
Expand All @@ -90,6 +93,7 @@ type RpcConnectionConfig =
// When providing multiple chains and no default transport, the signer connection is required
signerConnection?: ConnectionConfig;
policyId?: never;
policyToken?: never;
}
| {
chain: Chain;
Expand All @@ -103,12 +107,14 @@ type RpcConnectionConfig =
// When providing multiple chains, then the signer connection is required
signerConnection: ConnectionConfig;
policyId?: never;
policyToken?: never;
}
| {
transport: AlchemyTransport;
chain: Chain;
solana?: SolanaConnection;
policyId?: string | string[];
policyToken?: PolicyToken;
signerConnection?: ConnectionConfig;
chains?: never;
};
Expand Down
2 changes: 1 addition & 1 deletion account-kit/infra/src/actions/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export type RequestGasAndPaymasterAndDataRequest = [
erc20Context?: {
tokenAddress: Address;
permit?: Hex;
maxTokenAmount?: BigInt;
maxTokenAmount?: number;
};
dummySignature: Hex;
userOperation: UserOperationRequest;
Expand Down
11 changes: 3 additions & 8 deletions account-kit/infra/src/client/smartAccountClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
type SmartContractAccountWithSigner,
type UserOperationContext,
} from "@aa-sdk/core";
import { type Address, type Chain } from "viem";
import { type Chain } from "viem";
import {
alchemy,
convertHeadersToObject,
Expand All @@ -28,6 +28,7 @@ import {
} from "./decorators/smartAccount.js";
import type { AlchemyRpcSchema } from "./types.js";
import { headersUpdate } from "../alchemyTrackerHeaders.js";
import type { PolicyToken } from "../middleware/gasManager.js";

export function getSignerTypeHeader<
TAccount extends SmartContractAccountWithSigner,
Expand All @@ -48,13 +49,7 @@ export type AlchemySmartAccountClientConfig<
account?: account;
useSimulation?: boolean;
policyId?: string | string[];
policyToken?: {
address: Address;
maxTokenAmount: bigint;
approvalMode?: "NONE" | "PERMIT";
erc20Name?: string;
version?: string;
};
policyToken?: PolicyToken;
} & Pick<
SmartAccountClientConfig<AlchemyTransport, chain, account, context>,
| "customMiddleware"
Expand Down
1 change: 1 addition & 0 deletions account-kit/infra/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export * from "./alchemyTrackerHeaders.js";
export {
alchemyGasManagerMiddleware,
alchemyGasAndPaymasterAndDataMiddleware,
type PolicyToken,
} from "./middleware/gasManager.js";
export { alchemyUserOperationSimulator } from "./middleware/userOperationSimulator.js";
export type * from "./schema.js";
32 changes: 17 additions & 15 deletions account-kit/infra/src/middleware/gasManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import type { AlchemySmartAccountClient } from "../client/smartAccountClient.js"
import type { AlchemyTransport } from "../alchemyTransport.js";
import { alchemyFeeEstimator } from "./feeEstimator.js";
import type { RequestGasAndPaymasterAndDataRequest } from "../actions/types.js";

import {
PermitTypes,
EIP7597Abis,
Expand All @@ -47,10 +48,20 @@ type Context = {
policyId: string | string[];
erc20Context?: {
tokenAddress: Address;
maxTokenAmount?: BigInt;
maxTokenAmount?: number;
permit?: Hex;
};
};

export type PolicyToken = {
address: Address;
maxTokenAmount: number;
paymasterAddress?: Address;
approvalMode?: "NONE" | "PERMIT";
erc20Name?: string;
version?: string;
};

/**
* Paymaster middleware factory that uses Alchemy's Gas Manager for sponsoring
* transactions. Adheres to the ERC-7677 standardized communication protocol.
Expand Down Expand Up @@ -127,15 +138,6 @@ interface AlchemyGasAndPaymasterAndDataMiddlewareParams {
feeEstimatorOverride?: ClientMiddlewareFn;
}

export type PolicyToken = {
address: Address;
maxTokenAmount: bigint;
paymasterAddress?: Address;
approvalMode?: "NONE" | "PERMIT";
erc20Name?: string;
version?: string;
};

/**
* Paymaster middleware factory that uses Alchemy's Gas Manager for sponsoring
* transactions. Uses Alchemy's custom `alchemy_requestGasAndPaymasterAndData`
Expand Down Expand Up @@ -379,7 +381,7 @@ const generateSignedPermit = async <TAccount extends SmartContractAccount>(
account: TAccount,
policyToken: {
address: Address;
maxTokenAmount: bigint;
maxTokenAmount: number;
paymasterAddress?: Address;
approvalMode?: "NONE" | "PERMIT";
erc20Name?: string;
Expand Down Expand Up @@ -423,8 +425,8 @@ const generateSignedPermit = async <TAccount extends SmartContractAccount>(
}

const decimals =
10n ** (decimalsResponse.data ? BigInt(decimalsResponse.data) : 18n);
const maxAmountToken = policyToken.maxTokenAmount * decimals;
10 ** (decimalsResponse.data ? Number(decimalsResponse.data) : 18);
const maxRawAmountToken = BigInt(policyToken.maxTokenAmount * decimals);
const nonce = BigInt(nonceResponse.data);

const paymasterAddress =
Expand All @@ -449,7 +451,7 @@ const generateSignedPermit = async <TAccount extends SmartContractAccount>(
message: {
owner: account.address,
spender: paymasterAddress,
value: maxAmountToken,
value: maxRawAmountToken,
nonce: nonce,
deadline,
} satisfies PermitMessage,
Expand All @@ -458,6 +460,6 @@ const generateSignedPermit = async <TAccount extends SmartContractAccount>(
const signedPermit = await account.signTypedData(typedPermitData);
return encodeAbiParameters(
[{ type: "uint256" }, { type: "uint256" }, { type: "bytes" }],
[maxAmountToken, deadline, signedPermit],
[maxRawAmountToken, deadline, signedPermit],
);
};
2 changes: 1 addition & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ To add new images:
SDK References are automatically generated from relevant projects within the monorepo via the `docs-gen` package. Both the markdown files and the sidebar structure in `docs/docs.yml` are generated and should **not** be edited manually. In the root, to generate references from code you can run:

```shell
yarn fern-gen
yarn fern:gen
```

### Injected Code Snippets
Expand Down
2 changes: 1 addition & 1 deletion docs/specs/openrpc/_shared_wallets/components.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ components:
description: "Erc20 contract address"
maxTokenAmount:
$ref: "#/components/schemas/positiveDecimal"
description: "Maximum allowed amount of value in USD"
description: "Maximum allowed amount of value in token"
permit:
$ref: "#/components/schemas/bytes"
description: "A 7597 typed permit"
Expand Down
4 changes: 2 additions & 2 deletions examples/ui-demo/src/components/modals/Erc20/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ const erc20Abi = parseAbi([
const nftAbi = parseAbi(["function mintTo(address to)"]);

// Amount of USDC to approve for gas payment (e.g., 100 USDC, 100 * 10^6)
export const USDC_GAS_APPROVAL_AMOUNT = BigInt(100_000_000);
export const USDC_GAS_APPROVAL_AMOUNT = 100_000_000;
const NFT_MINT_PRICE = BigInt(1_000_000); // 1 USDC for mint price (1 * 10^6)

export async function getNftMintBatchUOs(accountAddress: Address) {
// 1. Approve the Alchemy Paymaster to spend USDC for gas
const approveGasSponsorshipCallData = encodeFunctionData({
abi: erc20Abi,
functionName: "approve",
args: [ALCHEMY_PAYMASTER_ADDRESS, USDC_GAS_APPROVAL_AMOUNT],
args: [ALCHEMY_PAYMASTER_ADDRESS, BigInt(USDC_GAS_APPROVAL_AMOUNT)],
});

// 2. Approve the NFT contract to spend USDC for the mint price
Expand Down
16 changes: 8 additions & 8 deletions examples/ui-demo/src/hooks/useModularAccountV2Client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,21 @@ import { Chain, Hex, Address, PrivateKeyAccount } from "viem";
import { LocalAccountSigner } from "@aa-sdk/core";
import { privateKeyToAccount } from "viem/accounts";

interface PolicyToken {
address: Address;
maxTokenAmount: bigint;
approvalMode?: "PERMIT" | "NONE";
erc20Name?: string;
version?: string;
}

type Client = ModularAccountV2Client<
AlchemySigner | LocalAccountSigner<PrivateKeyAccount>
> &
InstallValidationActions<
ModularAccountV2<AlchemySigner | LocalAccountSigner<PrivateKeyAccount>>
>;

interface PolicyToken {
address: Address;
maxTokenAmount: number;
approvalMode?: "PERMIT" | "NONE";
erc20Name?: string;
version?: string;
}

// Hook that creates an MAv2 client that can be used for things that
// @account-kit/react doesn't yet support, such as session keys.
export const useModularAccountV2Client = ({
Expand Down
Loading