Skip to content

Commit

Permalink
feat(aa-sdk): sdk light client can call the alchemy client
Browse files Browse the repository at this point in the history
  • Loading branch information
Blu-J committed Jan 7, 2025
1 parent dbf4db9 commit e7bcc56
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,21 @@ import {
erc7677Middleware,
LocalAccountSigner,
type BatchUserOperationCallData,
type SmartAccountClient,
type SmartAccountSigner,
type UserOperationCallData,
type UserOperationOverrides,
type UserOperationStruct,
} from "@aa-sdk/core";
import { custom, parseEther, type Address, publicActions } from "viem";
import {
custom,
parseEther,
type Address,
publicActions,
type Chain,
type Client,
type CustomTransport,
} from "viem";
import { setBalance } from "viem/actions";
import { resetBalance } from "~test/accounts.js";
import { accounts } from "~test/constants.js";
Expand All @@ -21,6 +30,15 @@ import { getMSCAUpgradeToData } from "../../msca/utils.js";
import type { LightAccountVersion } from "../types.js";
import { AccountVersionRegistry } from "../utils.js";
import { createLightAccountClient } from "./client.js";
import {
alchemy,
polygonMumbai,
alchemyEnhancedApiActions,
type AlchemyTransport,
type AlchemySmartAccountClient,
type AlchemyEnhancedApis,
} from "@account-kit/infra";
import { Alchemy, Network } from "alchemy-sdk";

const versions = Object.keys(
AccountVersionRegistry.LightAccount
Expand Down Expand Up @@ -387,4 +405,76 @@ describe("Light Account Tests", () => {
chain: instance.chain,
...(usePaymaster ? erc7677Middleware() : {}),
});

const givenAlchemyConnectedProvider = async ({
signer,
chain,
}: {
signer: SmartAccountSigner;
chain: Chain;
}) =>
createLightAccountClient({
transport: alchemy({
jwt: "test",
}),
chain,
signer,
accountAddress: "0x86f3B0211764971Ad0Fc8C8898d31f5d792faD84",
});
it("Should have some alchemy specific types", async () => {
const alchemy = new Alchemy({
network: Network.MATIC_MUMBAI,
apiKey: "test",
});
const chain = polygonMumbai;

const provider = (
await givenAlchemyConnectedProvider({ signer, chain })
).extend(alchemyEnhancedApiActions(alchemy));

assertType<Client<AlchemyTransport>>(provider);
assertType<AlchemySmartAccountClient>(provider);
assertType<SmartAccountClient>(provider);
assertType<AlchemyEnhancedApis>(provider);
assertType<AlchemyEnhancedApis>(
// @ts-expect-error
await givenAlchemyConnectedProvider({ signer, chain })
);
// @ts-expect-error
assertType<Client<CustomTransport>>(provider);
});
it("Should have some non-alchemy specific types", async () => {
const chain = polygonMumbai;

const signer: SmartAccountSigner = new LocalAccountSigner(
accounts.fundedAccountOwner
);
const provider = await givenConnectedProvider({
signer,
version: "v1.0.1",
});

assertType<SmartAccountClient>(provider);
assertType<Client<CustomTransport>>(provider);
assertType<AlchemyEnhancedApis>(
// @ts-expect-error
await givenAlchemyConnectedProvider({ signer, chain })
);
// @ts-expect-error
assertType<Client<AlchemyTransport>>(provider);
// @ts-expect-error
assertType<AlchemySmartAccountClient>(provider);
// @ts-expect-error
assertType<AlchemyEnhancedApis>(provider);

expect(() => {
const alchemy = new Alchemy({
network: Network.MATIC_MUMBAI,
apiKey: "test",
});

// @ts-expect-error
provider.extend(alchemyEnhancedApiActions(alchemy));
}).not.toBeFalsy();
});
});
48 changes: 43 additions & 5 deletions account-kit/smart-contracts/src/light-account/clients/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,17 @@ import {
lightAccountClientActions,
type LightAccountClientActions,
} from "../decorators/lightAccount.js";
import {
type AlchemySmartAccountClient,
type AlchemyTransport,
} from "@account-kit/infra";
import {
createLightAccountAlchemyClient,
type AlchemyLightAccountClientConfig,
} from "./alchemyClient.js";

export type CreateLightAccountClientParams<
TTransport extends Transport = Transport,
TTransport extends Transport | AlchemyTransport = Transport,
TChain extends Chain | undefined = Chain | undefined,
TSigner extends SmartAccountSigner = SmartAccountSigner
> = {
Expand All @@ -31,14 +39,28 @@ export type CreateLightAccountClientParams<
>;

export function createLightAccountClient<
TChain extends Chain | undefined = Chain | undefined,
TSigner extends SmartAccountSigner = SmartAccountSigner
>(
args: CreateLightAccountClientParams<Transport, TChain, TSigner>
params: AlchemyLightAccountClientConfig<TSigner> & {
transport: AlchemyTransport;
}
): Promise<
AlchemySmartAccountClient<
Chain | undefined,
LightAccount<TSigner>,
LightAccountClientActions<TSigner>
>
>;
export function createLightAccountClient<
TChain extends Chain | undefined = Chain | undefined,
TSigner extends SmartAccountSigner = SmartAccountSigner,
TTransport extends Transport = Transport
>(
args: CreateLightAccountClientParams<TTransport, TChain, TSigner>
): Promise<
SmartAccountClient<
CustomTransport,
Chain,
TChain,
LightAccount<TSigner>,
SmartAccountClientActions<Chain, SmartContractAccount> &
LightAccountClientActions<TSigner, LightAccount<TSigner>>
Expand All @@ -48,6 +70,8 @@ export function createLightAccountClient<
/**
* Creates a light account client using the provided parameters, including account information, transport mechanism, blockchain chain, and additional client configurations. This function first creates a light account and then uses it to create a smart account client, extending it with light account client actions.
*
* Also, we modified the return type to be the light account alchemy client if the transport is alchemy.
*
* @example
* ```ts
* import { createLightAccountClient } from "@account-kit/smart-contracts";
Expand All @@ -67,9 +91,16 @@ export function createLightAccountClient<
*/
export async function createLightAccountClient(
params: CreateLightAccountClientParams
): Promise<SmartAccountClient> {
): Promise<SmartAccountClient | AlchemySmartAccountClient> {
const { transport, chain } = params;

if (isAlchemyTransport(transport, chain)) {
return await createLightAccountAlchemyClient({
...params,
transport,
});
}

const lightAccount = await createLightAccount({
...params,
transport,
Expand All @@ -83,3 +114,10 @@ export async function createLightAccountClient(
account: lightAccount,
}).extend(lightAccountClientActions);
}

function isAlchemyTransport(
transport: Transport,
chain: Chain
): transport is AlchemyTransport {
return transport({ chain }).config.type === "alchemy";
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit e7bcc56

Please sign in to comment.