UNPKG

ic-auth

Version:

A simple, modular package for integrating Internet Computer authentication providers into your app.

233 lines (232 loc) 9.38 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CreateAnonAgent = exports.CreateActor = exports.IdentityLogin = exports.NFIDLogin = exports.PlugLogin = exports.StoicLogin = void 0; const principal_1 = require("@dfinity/principal"); const agent_1 = require("@dfinity/agent"); const auth_client_1 = require("@dfinity/auth-client"); //@ts-ignore const ic_stoic_identity_1 = require("ic-stoic-identity"); // Helpers const shouldFetchRootKey = (host) => { return !(host.includes('ic0.app') || host.includes('icp0.io')); }; // A simple Stoic login flow with simplified return data. // Todo: Stoic is giving a cookies error, need to wait for a response from the stoic team. /** * Authenticate the user with the Stoic Wallet provider and return a connected UserObject. * * This flow checks if Stoic is already connected, otherwise prompts the user to connect. * If successful, it creates a new Agent tied to the identity and returns the principal and agent. * * @param host - The IC replica host to connect to (e.g., local or mainnet). * @returns A Promise resolving to a UserObject containing principal, agent, and provider info. * @throws If Stoic identity cannot be loaded or connection fails. * * @todo Stoic is currently known to throw a cookie-related error in some browsers. * This may be fixed in a later version. */ const StoicLogin = async (host) => { // Checks to see if stoic is already connected or not, then prompts. let identity = await ic_stoic_identity_1.StoicIdentity.load(); if (!identity) { identity = await ic_stoic_identity_1.StoicIdentity.connect(); } if (!identity) { throw new Error("Stoic Identity not found or connection failed."); } const agent = await agent_1.HttpAgent.create({ identity: identity, host: host, shouldFetchRootKey: shouldFetchRootKey(host) }); const principal = identity.getPrincipal().toText(); const returnObject = { principal: principal, agent: agent, provider: "Stoic" }; console.log("Connected!"); console.log(returnObject); return returnObject; }; exports.StoicLogin = StoicLogin; // Full featured Plug wallet login with simplified return data. /** * Logs in with Plug Wallet and returns the authenticated user's agent and information. * * @param whitelist - An array of canister IDs the app will access using Plug Wallet. * @param host - The URL of the Internet Computer replica to connect to. * Use "https://icp0.io" or "https://ic0.app" for mainnet or "http://127.0.0.1:<YourDFXPort>" for local development. * @returns A Promise that resolves to a UserObject containing the agent, principal, and provider name. */ const PlugLogin = async (whitelist, host) => { const isConnected = await window.ic.plug.isConnected(); if (isConnected) { await window.ic.plug.createAgent({ whitelist, host }); const agent = window.ic.plug.agent; const principal = (await agent.getPrincipal()).toText(); const returnObject = { principal: principal, agent: agent, provider: "Plug" }; console.log("Connected!"); console.log(returnObject); return returnObject; } else { await window.ic.plug.requestConnect({ whitelist, host }); const agent = window.ic.plug.agent; const principal = (await agent.getPrincipal()).toText(); const returnObject = { principal: principal, agent: agent, provider: "Plug" }; console.log("Connected!"); console.log(returnObject); return returnObject; } }; exports.PlugLogin = PlugLogin; // A full featured NFID login flow with modern agent and simplified return data. /** * Authenticate the user using NFID and return a connected UserObject. * * This flow uses DFINITY's AuthClient with NFID as the identity provider. * It constructs the NFID authorization URL with application name and logo, * creates a modern Agent tied to the authenticated identity, and resolves the user details. * * @param host - The IC replica host to connect to (mainnet or local). * @returns A Promise resolving to a UserObject containing principal, agent, and provider info. * @throws If creating the AuthClient or login flow fails. */ const NFIDLogin = async (host) => { return new Promise(async (resolve, reject) => { const appName = "wallet-testing"; const appLogo = "https://nfid.one/icons/favicon-96x96.png"; const authUrl = `https://nfid.one/authenticate/?applicationName=${appName}&applicationLogo=${appLogo}#authorize`; let userObject = { principal: "Not Connected.", agent: undefined, provider: "N/A", }; try { const authClient = await auth_client_1.AuthClient.create(); await authClient.login({ identityProvider: authUrl, onSuccess: async () => { const identity = authClient.getIdentity(); const agent = await agent_1.HttpAgent.create({ identity, host, shouldFetchRootKey: shouldFetchRootKey(host), }); userObject = { principal: principal_1.Principal.from(identity.getPrincipal()).toText(), agent, provider: "NFID", }; console.log("Connected!"); console.log(userObject); resolve(userObject); }, onError: (error) => { console.error("NFID Login Failed:", error); reject(error); }, }); } catch (error) { console.error("Error creating AuthClient:", error); reject(error); } }); }; exports.NFIDLogin = NFIDLogin; // A fully featured Internet Identity login flow with simplified return data. /** * Authenticate the user using Internet Identity and return a connected UserObject. * * This flow uses DFINITY's AuthClient to open the Internet Identity login, * creates an Agent with the returned identity, and resolves the user details. * It handles both mainnet and local environments by conditionally fetching the root key. * * @param host - The IC replica host to connect to (mainnet or local). * @returns A Promise resolving to a UserObject containing principal, agent, and provider info. * @throws If creating the AuthClient or login flow fails. */ const IdentityLogin = async (host) => { return new Promise(async (resolve, reject) => { let identity; let userObject = { principal: "Not Connected.", agent: undefined, provider: "N/A", }; try { const authClient = await auth_client_1.AuthClient.create(); await authClient.login({ identityProvider: "https://identity.ic0.app", onSuccess: async () => { identity = authClient.getIdentity(); const agent = await agent_1.HttpAgent.create({ identity: identity, host: host, shouldFetchRootKey: shouldFetchRootKey(host), }); userObject = { principal: principal_1.Principal.from(identity.getPrincipal()).toText(), agent: agent, provider: "Internet Identity", }; console.log("Connected!"); console.log(userObject); resolve(userObject); }, onError: async (error) => { userObject = { principal: "Not Connected.", agent: undefined, provider: "N/A", }; console.log("Error Logging In"); reject(error); }, }); } catch (error) { console.error("Error creating AuthClient:", error); reject(error); } }); }; exports.IdentityLogin = IdentityLogin; /** * Create an actor for any canister using a provided agent. * @param agent - The authenticated or anonymous Agent instance. * @param idl - The IDL factory for the target canister. * @param canisterId - The canister ID to connect to. * @returns A typed Actor subclass for the canister. */ const CreateActor = async (agent, idl, canisterId) => { const actor = agent_1.Actor.createActor(idl, { agent, canisterId, }); return actor; }; exports.CreateActor = CreateActor; /** * Create an anonymous agent for public queries or read-only calls. * @param host - Optional IC replica host (defaults to mainnet). * @returns An Agent instance with no identity attached. */ const CreateAnonAgent = async (host) => { const agent = await agent_1.HttpAgent.create({ host, shouldFetchRootKey: shouldFetchRootKey(host), }); return agent; }; exports.CreateAnonAgent = CreateAnonAgent;