ii-integration-helpers
Version:
A TypeScript library that provides helper functions for implementing the Proxy Web App component of Internet Identity (II) integration for mobile applications.
151 lines (150 loc) • 3.86 kB
JavaScript
import { fromHex as y } from "@dfinity/agent";
import { Ed25519PublicKey as m, DelegationChain as g, ECDSAKeyIdentity as E } from "@dfinity/identity";
import { buildDeepLink as S, updateParams as w } from "expo-icp-frontend-helpers";
import { parseDeepLinkConnectionParams as I, buildInternetIdentityURL as b } from "expo-icp-app-connect-helpers";
import { AuthClient as f } from "@dfinity/auth-client";
const D = (t) => m.fromDer(y(t)), L = (t) => JSON.stringify(t.toJSON()), P = ({
middleDelegationIdentity: t,
appPublicKey: e,
expiration: n
}) => g.create(
t,
e,
n,
{
previous: t.getDelegation()
}
), B = ({
localIPAddress: t,
dfxNetwork: e,
internetIdentityCanisterId: n,
frontendCanisterId: o,
expoScheme: r
}) => {
const { pubkey: i, deepLinkType: a, sessionId: c, pathname: l } = I(
window.location.search,
"pubkey"
), s = D(i), d = b({
localIPAddress: t,
dfxNetwork: e,
targetCanisterId: n
}), p = S({
deepLinkType: a,
localIPAddress: t,
dfxNetwork: e,
frontendCanisterId: o,
expoScheme: r,
pathname: l
});
return {
appPublicKey: s,
internetIdentityURL: d,
deepLink: p,
sessionId: c
};
}, h = ({
delegationChain: t,
sessionId: e
}) => {
const n = L(t), o = new URLSearchParams();
return w(o, {
delegation: n,
sessionId: e
}), o.toString();
}, C = {
/** Error message for login process failures */
LOGIN_PROCESS: "Failed to complete login process"
}, O = "ii-login-button", R = "back-to-app-button", _ = (t, e) => `Internet Identity ${t}: ${e instanceof Error ? e.message : String(e)}`, k = ({
deepLink: t,
delegationChain: e,
sessionId: n,
iiLoginButton: o,
backToAppButton: r
}) => {
const i = h({
delegationChain: e,
sessionId: n
});
o.style.display = "none", r.style.display = "block", r.addEventListener("click", () => {
r.textContent = "Processing...", r.style.opacity = "0.7", r.style.cursor = "wait", window.open(`${t.toString()}#${i}`, "_self");
});
}, G = () => {
const t = document.getElementById(
O
), e = document.getElementById(
R
);
if (!t || !e)
throw new Error("Required buttons not found");
return { iiLoginButton: t, backToAppButton: e };
}, U = async ({
internetIdentityURL: t
}) => {
const e = await E.generate(), n = await f.create({ identity: e });
return async () => new Promise((o, r) => {
n.login({
identityProvider: t.toString(),
onSuccess: () => {
const i = n.getIdentity();
o(i);
},
onError: (i) => {
r(new Error(i || "Unknown error"));
}
});
});
}, u = (t) => {
const e = document.querySelector("#error");
if (!e) {
console.error("Error element not found");
return;
}
e.textContent = t, e.style.display = t ? "block" : "none";
}, T = async ({
iiLoginButton: t,
backToAppButton: e,
deepLink: n,
sessionId: o,
appPublicKey: r,
internetIdentityURL: i,
ttlMs: a
}) => {
const c = await U({
internetIdentityURL: i
});
t.addEventListener("click", async (l) => {
l.preventDefault(), u("");
try {
const s = await c(), d = await P({
middleDelegationIdentity: s,
appPublicKey: r,
expiration: new Date(Date.now() + a)
});
k({
deepLink: n,
sessionId: o,
delegationChain: d,
iiLoginButton: t,
backToAppButton: e
});
} catch (s) {
u(_(C.LOGIN_PROCESS, s));
}
});
};
export {
R as BACK_TO_APP_BUTTON_ID,
C as ERROR_MESSAGES,
O as LOGIN_BUTTON_ID,
D as buildAppPublicKey,
L as buildDelegationString,
P as buildMiddleToAppDelegationChain,
B as buildParams,
h as buildURIFragment,
_ as formatError,
k as handleAppDelegation,
G as prepareButtons,
U as prepareLogin,
u as renderError,
T as setupLoginButtonHandler
};