@particle-network/auth-connectors
Version:
540 lines (532 loc) • 16.8 kB
JavaScript
// src/store.ts
import { AuthType } from "@particle-network/auth-core";
import { AuthCoreContextProvider } from "@particle-network/authkit";
import {
ChainNotConfiguredError as ChainNotConfiguredError3,
createEmitter,
createWalletConnector,
isEVMChain as isEVMChain2,
isSolanaChain as isSolanaChain2
} from "@particle-network/connector-core";
import { createStore } from "zustand/vanilla";
// src/getClient.ts
import { createPublicClient, http } from "viem";
var clients = /* @__PURE__ */ new Map();
function getPublicClient(chain) {
{
const client2 = clients.get(chain.id);
if (client2)
return client2;
}
const client = createPublicClient({
chain,
transport: http()
});
clients.set(chain.id, client);
return client;
}
// src/getConnection.ts
import { Connection } from "@solana/web3.js";
var clients2 = /* @__PURE__ */ new Map();
function getConnection(chain, commitmentOrConfig) {
{
const client2 = clients2.get(chain.id);
if (client2)
return client2;
}
const client = new Connection(chain.rpcUrls.default.http[0], commitmentOrConfig);
clients2.set(chain.id, client);
return client;
}
// src/particleEvm.ts
import {
ChainNotConfiguredError,
ProviderNotFoundError,
SwitchChainError,
UserRejectedRequestError,
createConnector,
isEVMChain,
numberToHex
} from "@particle-network/connector-core";
particleEvm.type = "particleAuth";
function particleEvm() {
let accountsChanged;
let chainChanged;
let disconnect;
return createConnector((config) => ({
get icon() {
return "https://static.particle.network/logo-small.png";
},
get id() {
return "particleEVM";
},
get name() {
return "Particle Auth";
},
type: particleEvm.type,
async connect(options) {
var _a;
const { chainId, isReconnecting } = options;
const provider = await this.getProvider();
if (!provider)
throw new ProviderNotFoundError();
if (options.phone && !options.code) {
throw new Error("Paramers error, need code.");
}
if (options.email && !options.code) {
throw new Error("Paramers error, need code.");
}
if (options.provider && !options.thirdpartyCode) {
throw new Error("Paramers error, need thirdpartyCode.");
}
let accounts = [];
accounts = await this.getAccounts().catch(() => []);
try {
if (!(accounts == null ? void 0 : accounts.length) && !isReconnecting) {
accounts = await provider.connect({
...options,
chain: chainId ? config.chains.filter(isEVMChain).find((chain) => chain.id === chainId) : void 0
});
}
if (!accountsChanged) {
accountsChanged = this.onAccountsChanged.bind(this);
provider.on("accountsChanged", accountsChanged);
}
if (!chainChanged) {
chainChanged = this.onChainChanged.bind(this);
provider.on("chainChanged", chainChanged);
}
if (!disconnect) {
disconnect = this.onDisconnect.bind(this);
provider.on("disconnect", disconnect);
}
let currentChainId = await this.getChainId();
if (chainId && currentChainId !== chainId) {
const chain = await this.switchChain({ chainId }).catch((error) => {
if (error.code === UserRejectedRequestError.code)
throw error;
return { id: currentChainId };
});
currentChainId = (_a = chain == null ? void 0 : chain.id) != null ? _a : currentChainId;
}
return { accounts, chainId: currentChainId };
} catch (err) {
const error = err;
if (error.code === UserRejectedRequestError.code)
throw new UserRejectedRequestError(error);
throw error;
}
},
async disconnect() {
const provider = await this.getProvider();
if (!provider)
throw new ProviderNotFoundError();
if (chainChanged) {
provider.removeListener("chainChanged", chainChanged);
chainChanged = void 0;
}
if (disconnect) {
provider.removeListener("disconnect", disconnect);
disconnect = void 0;
}
await provider.disconnect();
},
async getAccounts() {
const provider = await this.getProvider();
if (!provider)
throw new ProviderNotFoundError();
const accounts = await provider.request({ method: "eth_accounts" });
return accounts;
},
async getChainId() {
const provider = await this.getProvider();
if (!provider)
throw new ProviderNotFoundError();
const hexChainId = await provider.request({ method: "eth_chainId" });
return Number(hexChainId);
},
async getProvider() {
var _a;
if (typeof window === "undefined")
return void 0;
const provider = (_a = window.particle) == null ? void 0 : _a.ethereum;
return provider;
},
async isAuthorized() {
try {
const provider = await this.getProvider();
if (!provider) {
throw new ProviderNotFoundError();
}
if (provider.isSocialConnecting) {
const timeout = 3e4;
await Promise.race([
...typeof window !== "undefined" ? [
new Promise(
(resolve) => window.addEventListener("particle:socialConnectCompleted", () => resolve(true), { once: true })
)
] : [],
new Promise((resolve) => setTimeout(() => resolve(true), timeout))
]);
}
const accounts = await this.getAccounts();
return !!accounts.length;
} catch {
return false;
}
},
async switchChain({ chainId }) {
const provider = await this.getProvider();
if (!provider)
throw new ProviderNotFoundError();
const chain = config.chains.filter(isEVMChain).find((x) => x.id === chainId);
if (!chain)
throw new SwitchChainError(new ChainNotConfiguredError());
try {
await Promise.all([
provider.request({
method: "wallet_switchEthereumChain",
params: [{ chainId: numberToHex(chainId) }]
}).then(async () => {
const currentChainId = await this.getChainId();
if (currentChainId === chainId)
config.emitter.emit("change", { chainId });
}),
new Promise(
(resolve) => config.emitter.once("change", ({ chainId: currentChainId }) => {
if (currentChainId === chainId)
resolve();
})
)
]);
return chain;
} catch (err) {
const error = err;
if (error.code === UserRejectedRequestError.code)
throw new UserRejectedRequestError(error);
throw new SwitchChainError(error);
}
},
async onAccountsChanged(accounts) {
if (accounts.length === 0)
this.onDisconnect();
else
config.emitter.emit("change", {
accounts
});
},
onChainChanged(chain) {
const chainId = Number(chain);
config.emitter.emit("change", { chainId });
},
async onDisconnect() {
const provider = await this.getProvider();
config.emitter.emit("disconnect");
if (provider) {
if (chainChanged) {
provider.removeListener("chainChanged", chainChanged);
chainChanged = void 0;
}
if (disconnect) {
provider.removeListener("disconnect", disconnect);
disconnect = void 0;
}
}
},
isInstalled() {
return true;
}
}));
}
// src/particleSolana.ts
import {
ChainNotConfiguredError as ChainNotConfiguredError2,
ProviderNotFoundError as ProviderNotFoundError2,
SwitchChainError as SwitchChainError2,
UserRejectedRequestError as UserRejectedRequestError2,
createConnector as createConnector2,
isSolanaChain
} from "@particle-network/connector-core";
particleSolana.type = "particleAuth";
function particleSolana() {
let accountsChanged;
let chainChanged;
let disconnect;
return createConnector2((config) => ({
get icon() {
return "https://static.particle.network/logo-small.png";
},
get id() {
return "particleSolana";
},
get name() {
return "Particle Auth";
},
type: particleSolana.type,
async connect(options) {
var _a;
const { chainId, isReconnecting } = options;
const provider = await this.getProvider();
if (!provider)
throw new ProviderNotFoundError2();
if (options.phone && !options.code) {
throw new Error("Paramers error, need code.");
}
if (options.email && !options.code) {
throw new Error("Paramers error, need code.");
}
if (options.provider && !options.thirdpartyCode) {
throw new Error("Paramers error, need thirdpartyCode.");
}
let accounts = [];
accounts = await this.getAccounts().catch(() => []);
try {
if (!isReconnecting) {
await provider.connect({
...options,
chain: chainId ? config.chains.filter(isSolanaChain).find((chain) => chain.id === chainId) : void 0
});
accounts = [provider.selectedAddress];
} else {
if (accounts.length && !provider.isConnected) {
await provider.connect();
}
}
if (!accountsChanged) {
accountsChanged = this.onAccountsChanged.bind(this);
provider.on("accountsChanged", accountsChanged);
}
if (!chainChanged) {
chainChanged = this.onChainChanged.bind(this);
provider.on("chainChanged", chainChanged);
}
if (!disconnect) {
disconnect = this.onDisconnect.bind(this);
provider.on("disconnect", disconnect);
}
let currentChainId = await this.getChainId();
if (chainId && currentChainId !== chainId) {
const chain = await this.switchChain({ chainId }).catch((error) => {
if (error.code === UserRejectedRequestError2.code)
throw error;
return { id: currentChainId };
});
currentChainId = (_a = chain == null ? void 0 : chain.id) != null ? _a : currentChainId;
}
return { accounts, chainId: currentChainId };
} catch (err) {
const error = err;
if (error.code === UserRejectedRequestError2.code)
throw new UserRejectedRequestError2(error);
throw error;
}
},
async disconnect() {
const provider = await this.getProvider();
if (!provider)
throw new ProviderNotFoundError2();
if (chainChanged) {
provider.removeListener("chainChanged", chainChanged);
chainChanged = void 0;
}
if (disconnect) {
provider.removeListener("disconnect", disconnect);
disconnect = void 0;
}
await provider.disconnect();
},
async getAccounts() {
const provider = await this.getProvider();
if (!provider)
throw new ProviderNotFoundError2();
if (provider.selectedAddress) {
return [provider.selectedAddress];
}
return [];
},
async getChainId() {
const provider = await this.getProvider();
if (!provider)
throw new ProviderNotFoundError2();
if (config.chains.find((chain) => chain.id === provider.chainId)) {
return provider.chainId;
}
const chainId = config.chains[0].id;
await this.switchChain({ chainId });
return chainId;
},
async getProvider() {
var _a;
if (typeof window === "undefined")
return void 0;
const provider = (_a = window.particle) == null ? void 0 : _a.solana;
return provider;
},
async isAuthorized() {
try {
const provider = await this.getProvider();
if (!provider) {
throw new ProviderNotFoundError2();
}
if (provider.isSocialConnecting) {
const timeout = 3e4;
await Promise.race([
...typeof window !== "undefined" ? [
new Promise(
(resolve) => window.addEventListener("particle:socialConnectCompleted", () => resolve(true), { once: true })
)
] : [],
new Promise((resolve) => setTimeout(() => resolve(true), timeout))
]);
}
const accounts = await this.getAccounts();
return !!accounts.length;
} catch {
return false;
}
},
async switchChain({ chainId }) {
const provider = await this.getProvider();
if (!provider)
throw new ProviderNotFoundError2();
const chain = config.chains.filter(isSolanaChain).find((x) => x.id === chainId);
if (!chain)
throw new SwitchChainError2(new ChainNotConfiguredError2());
try {
await provider.switchChain(chainId);
return chain;
} catch (err) {
const error = err;
if (error.code === UserRejectedRequestError2.code)
throw new UserRejectedRequestError2(error);
throw new SwitchChainError2(error);
}
},
async onAccountsChanged(accounts) {
if (accounts.length === 0)
this.onDisconnect();
else
config.emitter.emit("change", {
accounts
});
},
onChainChanged(chain) {
const chainId = Number(chain);
config.emitter.emit("change", { chainId });
},
async onDisconnect() {
const provider = await this.getProvider();
config.emitter.emit("disconnect");
if (provider) {
if (chainChanged) {
provider.removeListener("chainChanged", chainChanged);
chainChanged = void 0;
}
if (disconnect) {
provider.removeListener("disconnect", disconnect);
disconnect = void 0;
}
}
},
isInstalled() {
return true;
}
}));
}
// src/types.ts
import { getCloudflareTurnstileResponse, getConnectCaptcha, getLatestAuthType } from "@particle-network/auth-core";
var auth = {
getCloudflareTurnstileResponse,
getConnectCaptcha,
getLatestAuthType
};
// src/store.ts
authWalletConnectors.type = "particleAuth";
function authWalletConnectors(parameters = {}) {
const { authTypes, fiatCoin, promptSettingConfig, overrides, language } = parameters;
if (authTypes && authTypes.length === 0) {
throw new Error("authTypes cannot be empty.");
}
const supportAuthTypes = authTypes || Object.values(AuthType);
return createWalletConnector((options) => {
const { chains: _chains, storage, projectId, clientKey, appId } = options;
const chains = createStore(() => _chains);
function setup(connectorFn) {
var _a;
const emitter = createEmitter();
const result = connectorFn({ emitter, chains: _chains, storage });
const connector = {
...result,
emitter,
uid: emitter.uid,
chainType: result.id.toLowerCase().includes("evm") ? "evm" : "solana",
walletConnectorType: authWalletConnectors.type
};
(_a = connector.setup) == null ? void 0 : _a.call(connector);
return connector;
}
const storeData = [];
if (_chains.some(isEVMChain2)) {
storeData.push(particleEvm());
}
if (_chains.some(isSolanaChain2)) {
storeData.push(particleSolana());
}
const connectors = createStore(() => storeData.map(setup));
function getClient(chainId) {
const chain = chains.getState().find((chain2) => chain2.id === chainId);
if (!chain) {
throw new ChainNotConfiguredError3();
}
if (isEVMChain2(chain)) {
return getPublicClient(chain);
}
return getConnection(chain);
}
return {
get type() {
return authWalletConnectors.type;
},
get chains() {
return chains.getState();
},
get connectors() {
return connectors.getState();
},
store: connectors,
getClient,
supportAuthTypes,
authOptions: {
projectId,
clientKey,
appId,
authTypes: supportAuthTypes,
fiatCoin,
language,
promptSettingConfig,
supportEIP6963: false,
customStyle: {
zIndex: 21475e5,
...overrides == null ? void 0 : overrides.customStyle
},
wallet: false,
chains: _chains
},
AuthCoreContextProvider,
_internal: {
connectors: {
setup
}
},
auth
};
});
}
// src/version.ts
var version = "3.0.0-alpha.5";
export {
auth,
authWalletConnectors,
version
};
//# sourceMappingURL=index.js.map