@funkit/wagmi-tools
Version:
Funkit Wagmi Tools
216 lines (215 loc) • 7.29 kB
JavaScript
// src/connector/funkitWagmiConnectorWallet.ts
import { FUNKIT_CONNECT_SUPPORTED_CHAINS_INFO_LIST } from "@funkit/chains";
import {
AddressZero,
Auth,
FunWallet,
configureEnvironment,
getEnvOptions
} from "@funkit/core";
import {
ChainNotConfiguredError,
createConnector,
normalizeChainId
} from "@wagmi/core";
import {
SwitchChainError,
UserRejectedRequestError,
numberToHex
} from "viem";
var ERROR_PREFIX = "FunkitWagmiConnectorError";
var ConnectorEvent = {
change: "change",
disconnect: "disconnect",
error: "error",
message: "message",
accountsChanged: "accountsChanged",
chainChanged: "chainChanged"
};
funkitWagmiConnectorWallet.type = "funkitWagmiConnectorWallet";
function funkitWagmiConnectorWallet() {
let _privyProvider;
let _fwIndex;
let _fwAuth = null;
let _funWallet = null;
return createConnector(
({ chains = FUNKIT_CONNECT_SUPPORTED_CHAINS_INFO_LIST, emitter }) => ({
id: "funkitConnector",
name: "Funkit Connector",
type: funkitWagmiConnectorWallet.type,
/**===============================
* Custom Funkit Connector Methods
*================================*/
getFunWallet() {
return _funWallet;
},
getAuth() {
return _fwAuth;
},
getInternalConfigs() {
return {
_privyProvider,
_fwIndex
};
},
async beforeConnect({
provider,
index
}) {
if (!provider) {
throw new Error(
`${ERROR_PREFIX}:beforeConnect - Missing provider param`
);
}
if (index == null || typeof index !== "number") {
throw new Error(`${ERROR_PREFIX}:beforeConnect - Invalid index param`);
}
_privyProvider = provider;
_fwIndex = index;
},
/**=========================
* Wagmi Connector Methods
*=========================*/
// Optional function for running when the connector is first created
async setup() {
return;
},
// Function for connecting the connector.
async connect({ chainId }) {
const provider = await this.getProvider();
if (!provider) {
throw new Error(
`${ERROR_PREFIX}: Ensure beforeConnect() is called before connect()`
);
}
provider.on(ConnectorEvent.accountsChanged, this.onAccountsChanged);
provider.on(ConnectorEvent.disconnect, this.onDisconnect);
provider.on(ConnectorEvent.chainChanged, this.onChainChanged);
emitter.emit(ConnectorEvent.message, { type: "connecting" });
_fwAuth = new Auth({ provider });
const walletUniqueId = await _fwAuth.getWalletUniqueId(_fwIndex);
const userId = await _fwAuth.getUserId();
_funWallet = new FunWallet({
users: [{ userId }],
uniqueId: walletUniqueId
});
const [newAccountAddress, curChainId] = await Promise.all([
_funWallet.getAddress(),
this.getChainId()
]);
let currentChainId = curChainId;
if (chainId && currentChainId !== chainId) {
const chain = await this.switchChain?.({ chainId }).catch((error) => {
if (error.code === UserRejectedRequestError.code) throw error;
return { id: currentChainId };
});
currentChainId = chain?.id ?? currentChainId;
}
return {
accounts: [newAccountAddress],
chainId: currentChainId
};
},
// Function for disconnecting the connector.
async disconnect() {
const provider = await this.getProvider();
provider.removeListener(
ConnectorEvent.accountsChanged,
this.onAccountsChanged
);
provider.removeListener(
ConnectorEvent.disconnect,
this.onDisconnect.bind(this)
);
provider.removeListener(ConnectorEvent.chainChanged, this.onDisconnect);
_funWallet = null;
_fwAuth = null;
},
// Function that returns the connected accounts for the connector.
async getAccounts() {
if (_funWallet == null) {
return [AddressZero];
}
return [await _funWallet.getAddress()];
},
// Function that returns the connected chain ID for the connector.
async getChainId() {
const provider = await this.getProvider();
const chainId = provider.chainId ?? await provider?.request({ method: "eth_chainId" });
return normalizeChainId(chainId);
},
// Function that returns the underlying provider interface for internal use throughout the connector.
async getProvider() {
return _privyProvider;
},
// Function that returns whether the connector has connected previously and is still authorized.
async isAuthorized() {
try {
const accounts = await this.getAccounts();
return _funWallet != null && _fwAuth != null && !!accounts.length;
} catch {
return false;
}
},
// Optional function for switching the connector's active chain
async switchChain({
chainId
}) {
try {
const newChain = chains.find((chain) => chain?.id === chainId);
if (!newChain)
throw new SwitchChainError(new ChainNotConfiguredError());
const curEnv = getEnvOptions();
await configureEnvironment({
...curEnv,
chain: chainId
});
const provider = await this.getProvider();
const chainIdHex = numberToHex(newChain.id);
await provider.request({
method: "wallet_switchEthereumChain",
params: [{ chainId: chainIdHex }]
});
_fwAuth = new Auth({ provider });
const walletUniqueId = await _fwAuth.getWalletUniqueId(_fwIndex);
const userId = await _fwAuth.getUserId();
_funWallet = new FunWallet({
users: [{ userId }],
uniqueId: walletUniqueId
});
emitter.emit(ConnectorEvent.change, {
chainId: newChain.id,
accounts: await this.getAccounts()
});
return newChain;
} catch (err) {
console.error(`${ERROR_PREFIX}: Failed to switch chain`, err);
throw err;
}
},
/**=========================
* Wagmi Connector Events
*=========================*/
// Function for subscribing to account changes internally in the connector.
onAccountsChanged() {
emitter.emit(ConnectorEvent.disconnect);
},
// Function for subscribing to chain changes internally in the connector.
onChainChanged(chainId) {
const normalizedChainId = normalizeChainId(chainId);
emitter.emit(ConnectorEvent.change, { chainId: normalizedChainId });
},
// Function for subscribing to disconnection events internally in the connector.
onDisconnect(error) {
if (error) {
console.error(`${ERROR_PREFIX}: Error during disconnection`, error);
}
emitter.emit(ConnectorEvent.disconnect);
}
})
);
}
export {
funkitWagmiConnectorWallet
};
//# sourceMappingURL=index.js.map