expo-ii-integration
Version:
Expo library to enable smartphone native applications to invoke Internet Identity through a web application
571 lines (570 loc) • 16.9 kB
JavaScript
var ce = Object.defineProperty;
var ue = (n, r, o) => r in n ? ce(n, r, { enumerable: !0, configurable: !0, writable: !0, value: o }) : n[r] = o;
var T = (n, r, o) => ue(n, typeof r != "symbol" ? r + "" : r, o);
import le, { createContext as fe, useContext as de, useState as $, useEffect as z } from "react";
import * as me from "expo-linking";
import { router as ye } from "expo-router";
import { Ed25519KeyIdentity as F, DelegationChain as X } from "@dfinity/identity";
import { StringValueStorageWrapper as G } from "expo-storage-universal";
import { AnonymousIdentity as ve, toHex as Ee } from "@dfinity/agent";
import { buildIdentity as B, isAuthenticationExpiredError as pe } from "expo-icp-frontend-helpers";
import { connectToApp as he, handleURL as ge, dismissBrowser as we } from "expo-icp-app-connect";
var Y = { exports: {} }, S = {};
/**
* @license React
* react-jsx-runtime.production.js
*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
var K;
function be() {
if (K) return S;
K = 1;
var n = Symbol.for("react.transitional.element"), r = Symbol.for("react.fragment");
function o(a, s, c) {
var f = null;
if (c !== void 0 && (f = "" + c), s.key !== void 0 && (f = "" + s.key), "key" in s) {
c = {};
for (var m in s)
m !== "key" && (c[m] = s[m]);
} else c = s;
return s = c.ref, {
$$typeof: n,
type: a,
key: f,
ref: s !== void 0 ? s : null,
props: c
};
}
return S.Fragment = r, S.jsx = o, S.jsxs = o, S;
}
var A = {};
/**
* @license React
* react-jsx-runtime.development.js
*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
var q;
function Re() {
return q || (q = 1, process.env.NODE_ENV !== "production" && function() {
function n(e) {
if (e == null) return null;
if (typeof e == "function")
return e.$$typeof === ae ? null : e.displayName || e.name || null;
if (typeof e == "string") return e;
switch (e) {
case g:
return "Fragment";
case w:
return "Profiler";
case _:
return "StrictMode";
case re:
return "Suspense";
case te:
return "SuspenseList";
case oe:
return "Activity";
}
if (typeof e == "object")
switch (typeof e.tag == "number" && console.error(
"Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."
), e.$$typeof) {
case k:
return "Portal";
case Q:
return (e.displayName || "Context") + ".Provider";
case Z:
return (e._context.displayName || "Context") + ".Consumer";
case ee:
var t = e.render;
return e = e.displayName, e || (e = t.displayName || t.name || "", e = e !== "" ? "ForwardRef(" + e + ")" : "ForwardRef"), e;
case ne:
return t = e.displayName || null, t !== null ? t : n(e.type) || "Memo";
case D:
t = e._payload, e = e._init;
try {
return n(e(t));
} catch {
}
}
return null;
}
function r(e) {
return "" + e;
}
function o(e) {
try {
r(e);
var t = !1;
} catch {
t = !0;
}
if (t) {
t = console;
var i = t.error, u = typeof Symbol == "function" && Symbol.toStringTag && e[Symbol.toStringTag] || e.constructor.name || "Object";
return i.call(
t,
"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",
u
), r(e);
}
}
function a(e) {
if (e === g) return "<>";
if (typeof e == "object" && e !== null && e.$$typeof === D)
return "<...>";
try {
var t = n(e);
return t ? "<" + t + ">" : "<...>";
} catch {
return "<...>";
}
}
function s() {
var e = P.A;
return e === null ? null : e.getOwner();
}
function c() {
return Error("react-stack-top-frame");
}
function f(e) {
if (L.call(e, "key")) {
var t = Object.getOwnPropertyDescriptor(e, "key").get;
if (t && t.isReactWarning) return !1;
}
return e.key !== void 0;
}
function m(e, t) {
function i() {
W || (W = !0, console.error(
"%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",
t
));
}
i.isReactWarning = !0, Object.defineProperty(e, "key", {
get: i,
configurable: !0
});
}
function p() {
var e = n(this.type);
return J[e] || (J[e] = !0, console.error(
"Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release."
)), e = this.props.ref, e !== void 0 ? e : null;
}
function v(e, t, i, u, E, d, N, j) {
return i = d.ref, e = {
$$typeof: h,
type: e,
key: t,
props: d,
_owner: E
}, (i !== void 0 ? i : null) !== null ? Object.defineProperty(e, "ref", {
enumerable: !1,
get: p
}) : Object.defineProperty(e, "ref", { enumerable: !1, value: null }), e._store = {}, Object.defineProperty(e._store, "validated", {
configurable: !1,
enumerable: !1,
writable: !0,
value: 0
}), Object.defineProperty(e, "_debugInfo", {
configurable: !1,
enumerable: !1,
writable: !0,
value: null
}), Object.defineProperty(e, "_debugStack", {
configurable: !1,
enumerable: !1,
writable: !0,
value: N
}), Object.defineProperty(e, "_debugTask", {
configurable: !1,
enumerable: !1,
writable: !0,
value: j
}), Object.freeze && (Object.freeze(e.props), Object.freeze(e)), e;
}
function O(e, t, i, u, E, d, N, j) {
var l = t.children;
if (l !== void 0)
if (u)
if (se(l)) {
for (u = 0; u < l.length; u++)
b(l[u]);
Object.freeze && Object.freeze(l);
} else
console.error(
"React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead."
);
else b(l);
if (L.call(t, "key")) {
l = n(e);
var R = Object.keys(t).filter(function(ie) {
return ie !== "key";
});
u = 0 < R.length ? "{key: someKey, " + R.join(": ..., ") + ": ...}" : "{key: someKey}", V[l + u] || (R = 0 < R.length ? "{" + R.join(": ..., ") + ": ...}" : "{}", console.error(
`A props object containing a "key" prop is being spread into JSX:
let props = %s;
<%s {...props} />
React keys must be passed directly to JSX without using spread:
let props = %s;
<%s key={someKey} {...props} />`,
u,
l,
R,
l
), V[l + u] = !0);
}
if (l = null, i !== void 0 && (o(i), l = "" + i), f(t) && (o(t.key), l = "" + t.key), "key" in t) {
i = {};
for (var C in t)
C !== "key" && (i[C] = t[C]);
} else i = t;
return l && m(
i,
typeof e == "function" ? e.displayName || e.name || "Unknown" : e
), v(
e,
l,
d,
E,
s(),
i,
N,
j
);
}
function b(e) {
typeof e == "object" && e !== null && e.$$typeof === h && e._store && (e._store.validated = 1);
}
var y = le, h = Symbol.for("react.transitional.element"), k = Symbol.for("react.portal"), g = Symbol.for("react.fragment"), _ = Symbol.for("react.strict_mode"), w = Symbol.for("react.profiler"), Z = Symbol.for("react.consumer"), Q = Symbol.for("react.context"), ee = Symbol.for("react.forward_ref"), re = Symbol.for("react.suspense"), te = Symbol.for("react.suspense_list"), ne = Symbol.for("react.memo"), D = Symbol.for("react.lazy"), oe = Symbol.for("react.activity"), ae = Symbol.for("react.client.reference"), P = y.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, L = Object.prototype.hasOwnProperty, se = Array.isArray, x = console.createTask ? console.createTask : function() {
return null;
};
y = {
"react-stack-bottom-frame": function(e) {
return e();
}
};
var W, J = {}, U = y["react-stack-bottom-frame"].bind(
y,
c
)(), M = x(a(c)), V = {};
A.Fragment = g, A.jsx = function(e, t, i, u, E) {
var d = 1e4 > P.recentlyCreatedOwnerStacks++;
return O(
e,
t,
i,
!1,
u,
E,
d ? Error("react-stack-top-frame") : U,
d ? x(a(e)) : M
);
}, A.jsxs = function(e, t, i, u, E) {
var d = 1e4 > P.recentlyCreatedOwnerStacks++;
return O(
e,
t,
i,
!0,
u,
E,
d ? Error("react-stack-top-frame") : U,
d ? x(a(e)) : M
);
};
}()), A;
}
process.env.NODE_ENV === "production" ? Y.exports = be() : Y.exports = Re();
var ke = Y.exports;
const H = fe(
void 0
), We = () => {
const n = de(H);
if (n === void 0)
throw new Error(
"useIIIntegrationContext must be used within an IIIntegrationProvider"
);
return n;
}, Je = ({
children: n,
value: r
}) => /* @__PURE__ */ ke.jsx(H.Provider, { value: r, children: n }), _e = async ({
appKeyStorage: n,
delegationStorage: r,
onSuccess: o,
onError: a,
onFinally: s
}) => {
try {
const c = await n.find(), f = await r.find();
c && f && o();
} catch (c) {
a(c);
} finally {
s();
}
};
class Te {
/**
* Creates a new instance of Ed25519KeyIdentityValueStorageWrapper.
* @param storage - The storage implementation to use for persistence
* @param key - The key under which the Ed25519KeyIdentity will be stored
*/
constructor(r, o) {
T(this, "storage");
T(this, "key");
this.storage = r, this.key = o;
}
/**
* Attempts to find and retrieve an Ed25519KeyIdentity from storage.
* @returns A Promise that resolves to the found Ed25519KeyIdentity or undefined if not found
*/
async find() {
const r = await this.storage.find(this.key);
if (r)
return F.fromJSON(r);
}
/**
* Retrieves an Ed25519KeyIdentity from storage, throwing an error if not found.
* @returns A Promise that resolves to the found Ed25519KeyIdentity
* @throws {Error} If no Ed25519KeyIdentity is found for the configured key
*/
async retrieve() {
const r = await this.find();
if (!r)
throw new Error(`No value found for key ${this.key}`);
return r;
}
/**
* Saves an Ed25519KeyIdentity to storage.
* @param value - The Ed25519KeyIdentity to save
* @returns A Promise that resolves when the save operation is complete
*/
async save(r) {
return this.storage.save(this.key, JSON.stringify(r.toJSON()));
}
/**
* Removes the stored Ed25519KeyIdentity from storage.
* @returns A Promise that resolves when the removal operation is complete
*/
async remove() {
return this.storage.remove(this.key);
}
}
class Se {
/**
* Creates a new instance of DelegationChainValueStorageWrapper.
* @param storage - The storage implementation to use for persistence
* @param key - The key under which the DelegationChain will be stored
*/
constructor(r, o) {
T(this, "storage");
T(this, "key");
this.storage = r, this.key = o;
}
/**
* Attempts to find and retrieve a DelegationChain from storage.
* If the stored delegation chain is invalid, it will be automatically removed from storage.
* @returns A Promise that resolves to the found DelegationChain or undefined if not found or invalid
*/
async find() {
const r = await this.storage.find(this.key);
if (r)
return X.fromJSON(r);
}
/**
* Retrieves a DelegationChain from storage, throwing an error if not found or invalid.
* @returns A Promise that resolves to the found and valid DelegationChain
* @throws {Error} If no valid DelegationChain is found for the configured key
*/
async retrieve() {
const r = await this.find();
if (!r)
throw new Error(`No value found for key ${this.key}`);
return r;
}
/**
* Saves a DelegationChain to storage.
* @param value - The DelegationChain to save
* @returns A Promise that resolves when the save operation is complete
*/
async save(r) {
return this.storage.save(this.key, JSON.stringify(r.toJSON()));
}
/**
* Removes the stored DelegationChain from storage.
* @returns A Promise that resolves when the removal operation is complete
*/
async remove() {
return this.storage.remove(this.key);
}
}
const Ae = async ({
appKeyStorage: n,
delegationStorage: r
}) => {
const o = await n.find(), a = await r.find();
if (o && a)
try {
return await B({
appKey: o,
delegationChain: a
});
} catch (s) {
throw pe(s) && await r.remove(), s;
}
else if (!o) {
const s = F.generate();
await n.save(s), await r.remove();
}
}, Oe = async ({
appKeyStorage: n,
delegationStorage: r,
onError: o
}) => {
try {
const a = await Ae({
appKeyStorage: n,
delegationStorage: r
});
return a || new ve();
} catch (a) {
throw console.error("Get identity failed:", a), o(a), a;
}
}, Ie = async ({
iiIntegrationUrl: n,
deepLinkType: r,
redirectPath: o,
appKeyStorage: a,
redirectPathStorage: s,
sessionIdStorage: c,
cryptoModule: f,
openBrowserOptions: m = {}
}) => {
const p = await F.generate();
await a.save(p);
const v = Ee(p.getPublicKey().toDer());
console.log("login redirectPath", o), await he({
url: n,
params: {
pubkey: v,
deepLinkType: r,
pathname: "/"
},
redirectPath: o,
redirectPathStorage: s,
sessionIdStorage: c,
cryptoModule: f,
openBrowserOptions: m
});
}, Pe = async ({
delegationStorage: n,
onFinally: r
}) => {
try {
await n.remove();
} finally {
r();
}
}, xe = async ({
delegation: n,
delegationStorage: r,
appKeyStorage: o
}) => {
const a = X.fromJSON(n), s = await o.retrieve(), c = await B({
appKey: s,
delegationChain: a
});
return await r.save(a), c;
}, I = "expo-ii-integration", Ue = ({
iiIntegrationUrl: n,
deepLinkType: r,
secureStorage: o,
regularStorage: a,
cryptoModule: s
}) => {
const c = me.useURL(), [f, m] = $(!1), [p, v] = $(!1), [O, b] = $(void 0), y = new Te(
o,
`${I}.appKey`
), h = new Se(
a,
`${I}.delegation`
), k = new G(
a,
`${I}.redirectPath`
), g = new G(
a,
`${I}.sessionId`
);
return z(() => {
f || _e({
appKeyStorage: y,
delegationStorage: h,
onSuccess: () => {
v(!0);
},
onError: b,
onFinally: () => m(!0)
});
}, []), z(() => {
p || !c || ge({
url: new URL(c),
sessionIdStorage: g,
onSuccess: async ({ delegation: _ }) => {
await xe({
delegation: _,
delegationStorage: h,
appKeyStorage: y
}), console.log("Authenticated from delegation"), v(!0), await g.remove();
const w = await k.find();
w && (console.log("Redirecting to", w), await k.remove(), ye.replace(w)), we();
},
onError: b
// onFinally: async () => {
// await sessionIdStorage.remove();
// await redirectPathStorage.remove();
// },
});
}, [c]), {
isAuthReady: f,
isAuthenticated: p,
getIdentity: () => Oe({
appKeyStorage: y,
delegationStorage: h,
onError: () => v(!1)
}),
login: ({ redirectPath: _, openBrowserOptions: w } = {}) => Ie({
iiIntegrationUrl: n,
deepLinkType: r,
appKeyStorage: y,
redirectPath: _,
redirectPathStorage: k,
sessionIdStorage: g,
cryptoModule: s,
openBrowserOptions: w
}),
logout: () => Pe({
delegationStorage: h,
onFinally: () => v(!1)
}),
authError: O,
clearAuthError: () => b(void 0)
};
};
export {
Se as DelegationChainValueStorageWrapper,
Te as Ed25519KeyIdentityValueStorageWrapper,
Je as IIIntegrationProvider,
Ue as useIIIntegration,
We as useIIIntegrationContext
};