@getpara/react-common 1.8.0 → 2.0.0-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/classes/ParaInternal.d.ts +16 -16
- package/dist/components/UserIdentifier.d.ts +4 -2
- package/dist/components/common.d.ts +3 -3
- package/dist/index.js +1279 -5
- package/dist/index.js.br +0 -0
- package/dist/index.js.gz +0 -0
- package/dist/types/externalWalletCommon.d.ts +79 -0
- package/dist/types/index.d.ts +3 -2
- package/dist/utils/index.d.ts +0 -1
- package/package.json +5 -6
- package/dist/chunk-IV3L3JVM.js +0 -46
- package/dist/classes/ParaInternal.js +0 -25
- package/dist/classes/index.js +0 -2
- package/dist/components/HeroSpinner.js +0 -55
- package/dist/components/KnownDevices.js +0 -60
- package/dist/components/MoonPayEmbed.js +0 -195
- package/dist/components/QRCode.js +0 -80
- package/dist/components/RampEmbed.js +0 -103
- package/dist/components/StripeEmbed.js +0 -138
- package/dist/components/UserIdentifier.js +0 -73
- package/dist/components/common.js +0 -54
- package/dist/components/index.js +0 -9
- package/dist/constants/aaguiMetadata.js +0 -145
- package/dist/hooks/index.js +0 -2
- package/dist/hooks/useCopyToClipboard.js +0 -36
- package/dist/package.json +0 -6
- package/dist/types/index.js +0 -1
- package/dist/utils/formatBiometricHints.js +0 -51
- package/dist/utils/formatPhoneNumber.d.ts +0 -1
- package/dist/utils/formatPhoneNumber.js +0 -25
- package/dist/utils/getBrowserName.js +0 -7
- package/dist/utils/getDeviceLogo.js +0 -36
- package/dist/utils/getDeviceModelName.js +0 -21
- package/dist/utils/getExternalWalletDisplayName.js +0 -22
- package/dist/utils/index.js +0 -113
- package/dist/utils/offRampSend.js +0 -71
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import {
|
|
3
|
-
__async
|
|
4
|
-
} from "../chunk-IV3L3JVM.js";
|
|
5
|
-
import { jsx } from "react/jsx-runtime";
|
|
6
|
-
import { useEffect, useRef } from "react";
|
|
7
|
-
import { RampInstantSDK } from "@ramp-network/ramp-instant-sdk";
|
|
8
|
-
import { Network, OnRampAsset, OnRampProvider, getPortalBaseURL } from "@getpara/web-sdk";
|
|
9
|
-
import {
|
|
10
|
-
getChainId,
|
|
11
|
-
getContractAddressFromAsset,
|
|
12
|
-
getCurrencyCodes,
|
|
13
|
-
reverseCurrencyLookup,
|
|
14
|
-
offRampSend
|
|
15
|
-
} from "../utils/index.js";
|
|
16
|
-
const TEST_MODE_FORBIDDEN = ["ETH_ETH", "ETH_USDC"];
|
|
17
|
-
const RampEmbed = ({
|
|
18
|
-
para,
|
|
19
|
-
appName,
|
|
20
|
-
onRampConfig,
|
|
21
|
-
onRampPurchase,
|
|
22
|
-
isEmbedded,
|
|
23
|
-
apiKey,
|
|
24
|
-
onClose,
|
|
25
|
-
setOnRampPurchase
|
|
26
|
-
}) => {
|
|
27
|
-
const { currencyCodes } = getCurrencyCodes(onRampConfig, {
|
|
28
|
-
provider: OnRampProvider.RAMP,
|
|
29
|
-
purchaseType: onRampPurchase.type,
|
|
30
|
-
walletType: onRampPurchase.walletType
|
|
31
|
-
});
|
|
32
|
-
const isMounted = useRef(false);
|
|
33
|
-
useEffect(() => {
|
|
34
|
-
if (!isMounted.current) {
|
|
35
|
-
try {
|
|
36
|
-
const widget = new RampInstantSDK({
|
|
37
|
-
hostAppName: appName,
|
|
38
|
-
swapAsset: currencyCodes.filter((code) => !onRampPurchase.testMode || !TEST_MODE_FORBIDDEN.includes(code)).join(","),
|
|
39
|
-
fiatValue: onRampPurchase.fiatQuantity,
|
|
40
|
-
fiatCurrency: onRampPurchase.fiat,
|
|
41
|
-
hostLogoUrl: `${getPortalBaseURL(para.ctx)}/wordmark_black.svg`,
|
|
42
|
-
hostApiKey: apiKey,
|
|
43
|
-
userAddress: onRampPurchase.address,
|
|
44
|
-
userEmailAddress: para.getEmail(),
|
|
45
|
-
url: (onRampPurchase == null ? void 0 : onRampPurchase.testMode) ? "https://app.demo.ramp.network" : "https://app.ramp.network",
|
|
46
|
-
enabledFlows: [onRampPurchase.type === "BUY" ? "ONRAMP" : "OFFRAMP"],
|
|
47
|
-
useSendCryptoCallback: true,
|
|
48
|
-
variant: "embedded-mobile",
|
|
49
|
-
containerNode: document.getElementById("ramp-container")
|
|
50
|
-
}).on("PURCHASE_CREATED", (e) => __async(void 0, null, function* () {
|
|
51
|
-
const p = e.payload.purchase;
|
|
52
|
-
const [network, asset] = onRampPurchase.testMode ? [Network.ETHEREUM, OnRampAsset.ETHEREUM] : reverseCurrencyLookup(onRampConfig.assetInfo, OnRampProvider.RAMP, p.asset.symbol) || [];
|
|
53
|
-
const updated = yield para.ctx.client.updateOnRampPurchase({
|
|
54
|
-
userId: para.getUserId(),
|
|
55
|
-
walletId: onRampPurchase.walletId,
|
|
56
|
-
externalWalletAddress: onRampPurchase.externalWalletAddress,
|
|
57
|
-
purchaseId: onRampPurchase.id,
|
|
58
|
-
updates: {
|
|
59
|
-
providerKey: p.id,
|
|
60
|
-
fiatQuantity: p.fiatValue,
|
|
61
|
-
fiat: p.fiatCurrency,
|
|
62
|
-
assetQuantity: p.cryptoAmount,
|
|
63
|
-
asset,
|
|
64
|
-
network
|
|
65
|
-
}
|
|
66
|
-
});
|
|
67
|
-
setOnRampPurchase(updated);
|
|
68
|
-
})).on("WIDGET_CLOSE", () => __async(void 0, null, function* () {
|
|
69
|
-
onClose == null ? void 0 : onClose();
|
|
70
|
-
if (!isEmbedded) {
|
|
71
|
-
setTimeout(() => {
|
|
72
|
-
if (typeof window !== "undefined") {
|
|
73
|
-
window.close();
|
|
74
|
-
}
|
|
75
|
-
}, 5e3);
|
|
76
|
-
}
|
|
77
|
-
})).onSendCrypto((assetInfo, amount, address) => __async(void 0, null, function* () {
|
|
78
|
-
try {
|
|
79
|
-
const [network, asset] = reverseCurrencyLookup(onRampConfig.assetInfo, OnRampProvider.RAMP, assetInfo.symbol);
|
|
80
|
-
const txHash = yield offRampSend(para, onRampPurchase, setOnRampPurchase, {
|
|
81
|
-
assetQuantity: amount,
|
|
82
|
-
destinationAddress: address,
|
|
83
|
-
contractAddress: getContractAddressFromAsset(network, asset),
|
|
84
|
-
chainId: getChainId(network),
|
|
85
|
-
testMode: onRampPurchase.testMode
|
|
86
|
-
});
|
|
87
|
-
return { txHash };
|
|
88
|
-
} catch (e) {
|
|
89
|
-
console.error(e);
|
|
90
|
-
}
|
|
91
|
-
}));
|
|
92
|
-
widget.show();
|
|
93
|
-
isMounted.current = true;
|
|
94
|
-
} catch (e) {
|
|
95
|
-
console.error(e);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}, []);
|
|
99
|
-
return /* @__PURE__ */ jsx("div", { id: "ramp-container", style: { minWidth: "320px", width: "100%", height: "767px" } });
|
|
100
|
-
};
|
|
101
|
-
export {
|
|
102
|
-
RampEmbed
|
|
103
|
-
};
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import {
|
|
3
|
-
__async
|
|
4
|
-
} from "../chunk-IV3L3JVM.js";
|
|
5
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
-
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
|
7
|
-
import { loadStripeOnramp } from "@stripe/crypto";
|
|
8
|
-
import { Network, OnRampAsset, OnRampProvider, OnRampPurchaseStatus } from "@getpara/web-sdk";
|
|
9
|
-
import { CpslSpinner } from "@getpara/react-components";
|
|
10
|
-
import { SpinnerContainer } from "./common.js";
|
|
11
|
-
import styled from "styled-components";
|
|
12
|
-
const STRIPE_PUBLISHABLE_KEY = "pk_live_51MvquNGrzDeP5yP9EgVSMBPQbrbg0oHDjPIIXypePd0jzOFjbadyfO7wBKLHhUtbKIUiEUVC3YYcTJyAmJ8xA7JE00T2UDfYKz";
|
|
13
|
-
const STRIPE_PUBLISHABLE_KEY_TEST = "pk_test_51Q2z5k2epVn9Kq0ZSbUzuetKb4azH6E6UPcvWmjRxvHmxLAJbIK0pwDbPQo63W9OyDng337ntNu3ZXx3AJ7MhFmR00XgfRmPgP";
|
|
14
|
-
const AssetCodes = {
|
|
15
|
-
eth: OnRampAsset.ETHEREUM,
|
|
16
|
-
matic: OnRampAsset.POLYGON,
|
|
17
|
-
sol: OnRampAsset.SOLANA,
|
|
18
|
-
usdc: OnRampAsset.USDC
|
|
19
|
-
};
|
|
20
|
-
const NetworkCodes = {
|
|
21
|
-
base: Network.BASE,
|
|
22
|
-
ethereum: Network.ETHEREUM,
|
|
23
|
-
polygon: Network.POLYGON,
|
|
24
|
-
solana: Network.SOLANA
|
|
25
|
-
};
|
|
26
|
-
const CryptoElementsContext = React.createContext(null);
|
|
27
|
-
CryptoElementsContext.displayName = "CryptoElementsContext";
|
|
28
|
-
const useOnrampSessionListener = (type, session, callback) => {
|
|
29
|
-
React.useEffect(() => {
|
|
30
|
-
if (session && callback) {
|
|
31
|
-
const listener = (e) => callback(e.payload);
|
|
32
|
-
session.addEventListener(type, listener);
|
|
33
|
-
return () => {
|
|
34
|
-
session.removeEventListener(type, listener);
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
return () => {
|
|
38
|
-
};
|
|
39
|
-
}, [session, callback, type]);
|
|
40
|
-
};
|
|
41
|
-
const StripeEmbed = ({ para, isDark, isEmbedded, onRampPurchase, setOnRampPurchase }) => {
|
|
42
|
-
const [isReady, setIsReady] = useState(false);
|
|
43
|
-
const isStripeEmbed = useMemo(() => onRampPurchase.provider === OnRampProvider.STRIPE, [onRampPurchase]);
|
|
44
|
-
const clientSecret = useMemo(
|
|
45
|
-
() => (onRampPurchase == null ? void 0 : onRampPurchase.provider) === OnRampProvider.STRIPE ? onRampPurchase == null ? void 0 : onRampPurchase.providerKey : void 0,
|
|
46
|
-
[onRampPurchase == null ? void 0 : onRampPurchase.provider, onRampPurchase == null ? void 0 : onRampPurchase.providerKey]
|
|
47
|
-
);
|
|
48
|
-
const [stripeOnRamp, setStripeOnRamp] = useState();
|
|
49
|
-
const onrampElementRef = React.useRef(null);
|
|
50
|
-
const [session, setSession] = React.useState();
|
|
51
|
-
useEffect(() => {
|
|
52
|
-
const containerRef = onrampElementRef.current;
|
|
53
|
-
if (containerRef) {
|
|
54
|
-
containerRef.innerHTML = "";
|
|
55
|
-
if (clientSecret && stripeOnRamp) {
|
|
56
|
-
setSession(
|
|
57
|
-
stripeOnRamp.createSession({
|
|
58
|
-
clientSecret,
|
|
59
|
-
appearance: { theme: isDark ? "dark" : "light" }
|
|
60
|
-
}).mount(containerRef)
|
|
61
|
-
);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}, [clientSecret, stripeOnRamp]);
|
|
65
|
-
useEffect(() => {
|
|
66
|
-
loadStripeOnramp((onRampPurchase == null ? void 0 : onRampPurchase.testMode) ? STRIPE_PUBLISHABLE_KEY_TEST : STRIPE_PUBLISHABLE_KEY).then(setStripeOnRamp);
|
|
67
|
-
}, []);
|
|
68
|
-
const onReady = useCallback(() => {
|
|
69
|
-
setIsReady(true);
|
|
70
|
-
}, []);
|
|
71
|
-
const onSessionChange = useCallback(
|
|
72
|
-
(_0) => __async(void 0, [_0], function* ({ session: session2 }) {
|
|
73
|
-
if (!isStripeEmbed) {
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
switch (session2.status) {
|
|
77
|
-
case "fulfillment_processing":
|
|
78
|
-
case "fulfillment_complete":
|
|
79
|
-
const updatedPurchase = yield para.ctx.client.updateOnRampPurchase({
|
|
80
|
-
userId: para.getUserId(),
|
|
81
|
-
walletId: onRampPurchase.walletId,
|
|
82
|
-
externalWalletAddress: onRampPurchase.externalWalletAddress,
|
|
83
|
-
purchaseId: onRampPurchase.id,
|
|
84
|
-
updates: {
|
|
85
|
-
status: OnRampPurchaseStatus.FINISHED,
|
|
86
|
-
fiatQuantity: session2.quote.source_amount,
|
|
87
|
-
fiat: session2.quote.source_currency.asset_code,
|
|
88
|
-
network: NetworkCodes[session2.quote.destination_currency.currency_network],
|
|
89
|
-
asset: AssetCodes[session2.quote.destination_currency.asset_code],
|
|
90
|
-
assetQuantity: session2.quote.destination_amount,
|
|
91
|
-
providerKey: null
|
|
92
|
-
}
|
|
93
|
-
});
|
|
94
|
-
setOnRampPurchase(updatedPurchase);
|
|
95
|
-
if (!isEmbedded) {
|
|
96
|
-
setTimeout(() => {
|
|
97
|
-
if (typeof window !== "undefined") {
|
|
98
|
-
window.close();
|
|
99
|
-
}
|
|
100
|
-
}, 5e3);
|
|
101
|
-
}
|
|
102
|
-
break;
|
|
103
|
-
default:
|
|
104
|
-
break;
|
|
105
|
-
}
|
|
106
|
-
}),
|
|
107
|
-
[isStripeEmbed]
|
|
108
|
-
);
|
|
109
|
-
useOnrampSessionListener("onramp_ui_loaded", session, onReady);
|
|
110
|
-
useOnrampSessionListener("onramp_session_updated", session, onSessionChange);
|
|
111
|
-
return /* @__PURE__ */ jsxs(OuterContainer, { children: [
|
|
112
|
-
/* @__PURE__ */ jsx(Container, { isReady, ref: onrampElementRef }),
|
|
113
|
-
!isReady && /* @__PURE__ */ jsx(SpinnerContainer, { style: { width: "100%", height: "100%", flex: 1 }, children: /* @__PURE__ */ jsx(CpslSpinner, { size: 100 }) })
|
|
114
|
-
] });
|
|
115
|
-
};
|
|
116
|
-
const OuterContainer = styled.div`
|
|
117
|
-
height: 100%;
|
|
118
|
-
width: 100%;
|
|
119
|
-
display: flex;
|
|
120
|
-
flex: 1;
|
|
121
|
-
align-items: center;
|
|
122
|
-
justify-content: center;
|
|
123
|
-
`;
|
|
124
|
-
const Container = styled.div`
|
|
125
|
-
height: 100%;
|
|
126
|
-
width: 100%;
|
|
127
|
-
display: ${({ isReady }) => isReady ? "flex" : "none"};
|
|
128
|
-
justify-content: center;
|
|
129
|
-
|
|
130
|
-
& > iframe {
|
|
131
|
-
height: 100%;
|
|
132
|
-
}
|
|
133
|
-
`;
|
|
134
|
-
export {
|
|
135
|
-
STRIPE_PUBLISHABLE_KEY,
|
|
136
|
-
STRIPE_PUBLISHABLE_KEY_TEST,
|
|
137
|
-
StripeEmbed
|
|
138
|
-
};
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import "../chunk-IV3L3JVM.js";
|
|
3
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
-
import { CpslAvatar, CpslIcon, CpslText } from "@getpara/react-components";
|
|
5
|
-
import styled from "styled-components";
|
|
6
|
-
import { formatPhoneNumber } from "../utils/formatPhoneNumber.js";
|
|
7
|
-
function defaultDisplayName({ authType, identifier }) {
|
|
8
|
-
switch (authType) {
|
|
9
|
-
case "email":
|
|
10
|
-
return identifier.toLowerCase();
|
|
11
|
-
case "phone":
|
|
12
|
-
return formatPhoneNumber(identifier);
|
|
13
|
-
case "farcaster":
|
|
14
|
-
return `@${identifier}`;
|
|
15
|
-
case "telegram":
|
|
16
|
-
return `Telegram User @${identifier}`;
|
|
17
|
-
default:
|
|
18
|
-
return null;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
const UserIdentifier = ({ identifier, authType, displayName, pfpUrl }) => {
|
|
22
|
-
const shouldHideAvatar = authType === "externalWallet";
|
|
23
|
-
let icon;
|
|
24
|
-
switch (authType) {
|
|
25
|
-
case "email":
|
|
26
|
-
icon = "mail";
|
|
27
|
-
break;
|
|
28
|
-
case "phone":
|
|
29
|
-
icon = "phone";
|
|
30
|
-
break;
|
|
31
|
-
case "farcaster":
|
|
32
|
-
icon = "farcasterBrand";
|
|
33
|
-
break;
|
|
34
|
-
case "telegram":
|
|
35
|
-
icon = "telegramBrand";
|
|
36
|
-
break;
|
|
37
|
-
}
|
|
38
|
-
return /* @__PURE__ */ jsxs(Container, { children: [
|
|
39
|
-
!shouldHideAvatar && /* @__PURE__ */ jsx(IconContainer, { children: pfpUrl ? /* @__PURE__ */ jsx(Avatar, { src: pfpUrl, size: "20px" }) : /* @__PURE__ */ jsx(Icon, { icon, size: authType === "telegram" ? "20px" : "13px" }) }),
|
|
40
|
-
/* @__PURE__ */ jsx(IdentifierText, { variant: "bodyS", weight: "medium", children: displayName || defaultDisplayName({ authType, identifier }) })
|
|
41
|
-
] });
|
|
42
|
-
};
|
|
43
|
-
const Container = styled.div`
|
|
44
|
-
padding: 8px 12px 8px 8px;
|
|
45
|
-
border-radius: 1000px;
|
|
46
|
-
background-color: var(--cpsl-color-background-4);
|
|
47
|
-
display: flex;
|
|
48
|
-
align-items: center;
|
|
49
|
-
justify-content: flex-start;
|
|
50
|
-
gap: 4px;
|
|
51
|
-
`;
|
|
52
|
-
const IdentifierText = styled(CpslText)`
|
|
53
|
-
--color-override: var(--cpsl-color-background-96);
|
|
54
|
-
`;
|
|
55
|
-
const IconContainer = styled.div`
|
|
56
|
-
display: flex;
|
|
57
|
-
background: var(--cpsl-color-background-0);
|
|
58
|
-
align-items: center;
|
|
59
|
-
justify-content: center;
|
|
60
|
-
border-radius: 1000px;
|
|
61
|
-
width: 20px;
|
|
62
|
-
height: 20px;
|
|
63
|
-
`;
|
|
64
|
-
const Icon = styled(CpslIcon)`
|
|
65
|
-
--icon-color: var(--cpsl-color-text-primary);
|
|
66
|
-
`;
|
|
67
|
-
const Avatar = styled(CpslAvatar)`
|
|
68
|
-
--container-border-width: 0;
|
|
69
|
-
--container-padding: 0;
|
|
70
|
-
`;
|
|
71
|
-
export {
|
|
72
|
-
UserIdentifier
|
|
73
|
-
};
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import "../chunk-IV3L3JVM.js";
|
|
3
|
-
import { CpslButton, CpslInput, CpslText } from "@getpara/react-components";
|
|
4
|
-
import styled from "styled-components";
|
|
5
|
-
const SpinnerContainer = styled.div`
|
|
6
|
-
display: flex;
|
|
7
|
-
align-items: center;
|
|
8
|
-
justify-content: center;
|
|
9
|
-
`;
|
|
10
|
-
const CenteredColumnContainer = styled.div`
|
|
11
|
-
width: 100%;
|
|
12
|
-
height: 100%;
|
|
13
|
-
align-self: center;
|
|
14
|
-
display: flex;
|
|
15
|
-
flex-direction: column;
|
|
16
|
-
align-items: center;
|
|
17
|
-
gap: 8px;
|
|
18
|
-
`;
|
|
19
|
-
const FilledDisabledInput = styled(CpslInput)`
|
|
20
|
-
--container-border-color: var(--cpsl-color-input-border-placeholder);
|
|
21
|
-
--container-background-color: var(--cpsl-color-background-0);
|
|
22
|
-
--input-background-color: transparent;
|
|
23
|
-
--input-font-weight: 500;
|
|
24
|
-
--input-color: var(--cpsl-color-text-secondary) !important;
|
|
25
|
-
`;
|
|
26
|
-
const FullWidthFilledDisabledInput = styled(FilledDisabledInput)`
|
|
27
|
-
width: 100%;
|
|
28
|
-
`;
|
|
29
|
-
const CenteredText = styled(CpslText)`
|
|
30
|
-
width: 100%;
|
|
31
|
-
text-align: center;
|
|
32
|
-
`;
|
|
33
|
-
const HeaderButton = styled(CpslButton)`
|
|
34
|
-
flex: 0;
|
|
35
|
-
--button-padding-top: 2px;
|
|
36
|
-
--button-padding-bottom: 2px;
|
|
37
|
-
--button-padding-start: 2px;
|
|
38
|
-
--button-padding-end: 2px;
|
|
39
|
-
--button-border-radius: 1000px;
|
|
40
|
-
--button-background-color: var(--cpsl-color-background-4);
|
|
41
|
-
|
|
42
|
-
cpsl-icon {
|
|
43
|
-
--height: 20px;
|
|
44
|
-
--width: 20px;
|
|
45
|
-
}
|
|
46
|
-
`;
|
|
47
|
-
export {
|
|
48
|
-
CenteredColumnContainer,
|
|
49
|
-
CenteredText,
|
|
50
|
-
FilledDisabledInput,
|
|
51
|
-
FullWidthFilledDisabledInput,
|
|
52
|
-
HeaderButton,
|
|
53
|
-
SpinnerContainer
|
|
54
|
-
};
|
package/dist/components/index.js
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
export * from "./MoonPayEmbed.js";
|
|
3
|
-
export * from "./RampEmbed.js";
|
|
4
|
-
export * from "./StripeEmbed.js";
|
|
5
|
-
export * from "./common.js";
|
|
6
|
-
export * from "./HeroSpinner.js";
|
|
7
|
-
export * from "./KnownDevices.js";
|
|
8
|
-
export * from "./QRCode.js";
|
|
9
|
-
export * from "./UserIdentifier.js";
|