@abstract-foundation/web3-react-agw
Version:
Abstract Global Wallet for web3-react
137 lines • 5.55 kB
JavaScript
import { transformEIP1193Provider } from '@abstract-foundation/agw-client';
import { Connector } from '@web3-react/types';
import {} from 'viem';
import { abstract, abstractTestnet } from 'viem/chains';
const AGW_APP_ID = 'cm04asygd041fmry9zmcyn5o5';
const VALID_CHAINS = {
[abstractTestnet.id]: abstractTestnet,
[abstract.id]: abstract,
};
function parseChainId(chainId) {
return typeof chainId === 'string' ? Number.parseInt(chainId, 16) : chainId;
}
export class AbstractGlobalWallet extends Connector {
constructor({ actions, onError }) {
super(actions, onError);
Object.defineProperty(this, "eagerConnection", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
}
async isomorphicInitialize() {
if (this.eagerConnection)
return;
return (this.eagerConnection = import('@privy-io/cross-app-connect').then(async ({ toPrivyWalletProvider }) => {
const originalProvider = toPrivyWalletProvider({
providerAppId: AGW_APP_ID,
chains: [abstractTestnet],
});
const agwProvider = transformEIP1193Provider({
provider: originalProvider,
chain: abstractTestnet,
});
if (agwProvider) {
this.provider = agwProvider;
this.provider.on('connect', ({ chainId }) => {
this.actions.update({ chainId: parseChainId(chainId) });
});
this.provider.on('disconnect', (error) => {
this.actions.resetState();
this.onError?.(error);
});
this.provider.on('chainChanged', (chainId) => {
this.actions.update({ chainId: parseChainId(chainId) });
});
this.provider.on('accountsChanged', (accounts) => {
this.actions.update({ accounts });
});
}
}));
}
/** {@inheritdoc Connector.connectEagerly} */
async connectEagerly() {
const cancelActivation = this.actions.startActivation();
try {
await this.isomorphicInitialize();
if (!this.provider)
return cancelActivation();
// Wallets may resolve eth_chainId and hang on eth_accounts pending user interaction, which may include changing
// chains; they should be requested serially, with accounts first, so that the chainId can settle.
const accounts = (await this.provider.request({
method: 'eth_accounts',
}));
if (!accounts.length)
throw new Error('No accounts returned');
const chainId = (await this.provider.request({
method: 'eth_chainId',
}));
this.actions.update({
chainId: parseChainId(chainId),
accounts,
});
}
catch (error) {
cancelActivation();
throw error;
}
}
/** {@inheritdoc Connector.activate} */
async activate(desiredChainIdOrChainParameters) {
const desiredChainId = typeof desiredChainIdOrChainParameters === 'number'
? desiredChainIdOrChainParameters
: desiredChainIdOrChainParameters?.chainId;
const cancelActivation = this.actions.startActivation();
try {
await this.isomorphicInitialize();
if (!this.provider)
throw new Error('No AGW provider');
await this.provider.request({ method: 'wallet_requestPermissions' });
// Wallets may resolve eth_chainId and hang on eth_accounts pending user interaction, which may include changing
// chains; they should be requested serially, with accounts first, so that the chainId can settle.
const accounts = (await this.provider.request({
method: 'eth_accounts',
}));
if (!accounts.length)
throw new Error('No accounts returned');
const chainId = (await this.provider.request({
method: 'eth_chainId',
}));
const receivedChainId = parseChainId(chainId);
if (!desiredChainId || desiredChainId === receivedChainId)
return this.actions.update({
chainId: receivedChainId,
accounts,
});
// if we're here, we can try to switch networks
const desiredChain = VALID_CHAINS[desiredChainId];
if (desiredChain) {
const desiredChainIdHex = `0x${desiredChainId.toString(16)}`;
await this.provider.request({
method: 'wallet_switchEthereumChain',
params: [{ chainId: desiredChainIdHex }],
});
await this.activate(desiredChainId);
}
else {
throw new Error('Invalid chain');
}
}
catch (error) {
cancelActivation();
throw error;
}
}
/** {@inheritdoc Connector.deactivate} */
async deactivate() {
if (!this.provider)
return;
await this.provider.request({
method: 'wallet_revokePermissions',
params: [{ eth_accounts: {} }],
});
this.actions.resetState();
}
}
//# sourceMappingURL=index.js.map