Skip to content

Commit

Permalink
✨ alchemy: auto reconnect
Browse files Browse the repository at this point in the history
  • Loading branch information
cruzdanilo committed Nov 23, 2023
1 parent f3367f5 commit 8cf4293
Showing 1 changed file with 45 additions and 22 deletions.
67 changes: 45 additions & 22 deletions utils/alchemyConnector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,23 @@ export default function alchemyConnector() {
let turnkeyClient: TurnkeyClient | undefined;
let alchemyProvider: AlchemyProvider | undefined;

return createConnector<AlchemyProvider, { getTurnkeyClient: () => TurnkeyClient }>((config) => ({
return createConnector<
AlchemyProvider,
{
loadStore: () => Promise<{ signWith?: string; subOrganizationId?: string }>;
getAccount: (signWith: string, subOrganizationId: string) => Promise<LightSmartContractAccount>;
getTurnkeyClient: () => TurnkeyClient;
}
>((config) => ({
id: "alchemy",
name: "Alchemy",
async setup() {
if (typeof window === "undefined") return;
const store = await this.loadStore();
if (!store.signWith || !store.subOrganizationId) return;
account = await this.getAccount(store.signWith, store.subOrganizationId);
config.emitter.emit("connect", { accounts: [await account.getAddress()], chainId: chain.id });
},
async connect({ chainId } = {}) {
if (chainId && chainId !== chain.id) throw new SwitchChainError(new ChainNotConfiguredError());
const provider = await this.getProvider();
Expand All @@ -38,9 +52,7 @@ export default function alchemyConnector() {
let signWith: string;
let subOrganizationId: string;
try {
const json = await AsyncStorage.getItem("account.store");
if (!json) throw new Error("no store");
const store = JSON.parse(json) as { signWith?: string; subOrganizationId?: string };
const store = await this.loadStore();
if (!store.signWith || !store.subOrganizationId) throw new Error("no account");
signWith = store.signWith;
subOrganizationId = store.subOrganizationId;
Expand All @@ -59,26 +71,10 @@ export default function alchemyConnector() {
if (!walletAccount) throw new Error("no ethereum account");
signWith = walletAccount.address;
subOrganizationId = organizationId;
AsyncStorage.setItem("account.store", JSON.stringify({ signWith, subOrganizationId })).catch(handleError);
}

const owner = new LocalAccountSigner(
await createAccount({
client: this.getTurnkeyClient(),
organizationId: subOrganizationId,
ethereumAddress: signWith,
signWith,
}),
);
account = provider.connect(
(rpcClient) =>
new LightSmartContractAccount({
factoryAddress: getDefaultLightAccountFactoryAddress(chain),
rpcClient,
chain,
owner,
}),
).account;
provider.withAlchemyGasManager({ policyId: alchemyGasPolicyId });
account = await this.getAccount(signWith, subOrganizationId);
return { accounts: [getAddress(await account.getAddress())], chainId: chain.id };
},
disconnect() {
Expand Down Expand Up @@ -122,6 +118,33 @@ export default function alchemyConnector() {
alchemyProvider?.removeListener("disconnect", this.onDisconnect);
handleError(error);
},
async loadStore() {
const json = await AsyncStorage.getItem("account.store");
if (!json) return { signWith: undefined, subOrganizationId: undefined };
return JSON.parse(json) as { signWith?: string; subOrganizationId?: string };
},
async getAccount(signWith: string, subOrganizationId: string) {
const provider = await this.getProvider();
const owner = new LocalAccountSigner(
await createAccount({
client: this.getTurnkeyClient(),
organizationId: subOrganizationId,
ethereumAddress: signWith,
signWith,
}),
);
account = provider.connect(
(rpcClient) =>
new LightSmartContractAccount({
factoryAddress: getDefaultLightAccountFactoryAddress(chain),
rpcClient,
chain,
owner,
}),
).account;
provider.withAlchemyGasManager({ policyId: alchemyGasPolicyId });
return account;
},
getTurnkeyClient() {
turnkeyClient ??= new TurnkeyClient({ baseUrl: "https://api.turnkey.com" }, new WebauthnStamper({ rpId }));
return turnkeyClient;
Expand Down

0 comments on commit 8cf4293

Please sign in to comment.