diff --git a/package.json b/package.json index faafbcae..ab4b3b45 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "license": "Apache-2.0", "dependencies": { "@creativecommons/cc-assets": "^0.1.0", - "@logion/client": "^0.45.0-2", + "@logion/client": "^0.45.0-7", "@logion/client-browser": "^0.3.5", "@logion/crossmint": "^0.1.32", "@logion/extension": "^0.8.1-1", diff --git a/src/__mocks__/@logion/client.ts b/src/__mocks__/@logion/client.ts index 4e4c5373..7ab47c6d 100644 --- a/src/__mocks__/@logion/client.ts +++ b/src/__mocks__/@logion/client.ts @@ -16,6 +16,7 @@ import { LocsState, HashOrContent, ClosedLoc, + ClosedIdentityLoc, ReadOnlyLocState, PendingRequest, } from '../LogionClientMock'; @@ -39,6 +40,7 @@ export { LocsState, HashOrContent, ClosedLoc, + ClosedIdentityLoc, ReadOnlyLocState, isTokenCompatibleWith, LegalOfficerClass, diff --git a/src/__mocks__/LogionClientMock.ts b/src/__mocks__/LogionClientMock.ts index 1fd01590..8039dad5 100644 --- a/src/__mocks__/LogionClientMock.ts +++ b/src/__mocks__/LogionClientMock.ts @@ -146,6 +146,15 @@ export class ClosedLoc extends LocRequestState { }; } +export class ClosedIdentityLoc extends LocRequestState { + + legalOfficer: { + requestVote: any, + } = { + requestVote: jest.fn(), + }; +} + export class EditableRequest extends LocRequestState { addMetadata: jest.Mock> | undefined; deleteMetadata: jest.Mock> | undefined; diff --git a/src/components/toggle/Checkbox.tsx b/src/components/toggle/Checkbox.tsx index 9835e15b..08b6d6e3 100644 --- a/src/components/toggle/Checkbox.tsx +++ b/src/components/toggle/Checkbox.tsx @@ -1,8 +1,9 @@ import './Checkbox.css'; import './Toggle.css'; +import './Eye.css'; import { customClassName } from "../../common/types/Helpers"; -export type Skin = "Checkbox" | "Toggle white" | "Toggle black"; +export type Skin = "Checkbox" | "Toggle white" | "Toggle black" | "Eye"; export interface Props { checked: boolean; diff --git a/src/components/toggle/Eye.css b/src/components/toggle/Eye.css new file mode 100644 index 00000000..ba05d608 --- /dev/null +++ b/src/components/toggle/Eye.css @@ -0,0 +1,34 @@ +.Eye { + content: " "; + position: relative; + height: 37px; + width: 50px; +} + +.Eye.clickable { + cursor: pointer; +} + +.Eye.checked:after { + background-image: url("../../img/eye.svg"); +} +.Eye:not(.checked):after { + background-image: url("../../img/eye-closed.svg"); +} + +.Eye:after { + content: " "; + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 100%; + background-repeat: no-repeat; + background-position: center; +} + +.Eye.disabled, +.Eye.clickable.disabled { + cursor: default; + opacity: 0.5; +} diff --git a/src/img/eye-closed.svg b/src/img/eye-closed.svg new file mode 100644 index 00000000..2c826d1e --- /dev/null +++ b/src/img/eye-closed.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/img/eye.svg b/src/img/eye.svg new file mode 100644 index 00000000..d7de87cc --- /dev/null +++ b/src/img/eye.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/loc/CertificateAndDetailsButtons.tsx b/src/loc/CertificateAndDetailsButtons.tsx index 307fba05..e169fad4 100644 --- a/src/loc/CertificateAndDetailsButtons.tsx +++ b/src/loc/CertificateAndDetailsButtons.tsx @@ -27,6 +27,7 @@ import ViewQrCodeButton from './ViewQrCodeButton'; import ViewCertificateButton from './ViewCertificateButton'; import InvitedContributorsButton from "./invited-contributor/InvitedContributorsButton"; import { CollectionLimits, DEFAULT_LIMITS } from "./CollectionLimitsForm"; +import SecretsButton from "./secrets/SecretsButton"; export interface Props { loc: LocData; @@ -87,7 +88,7 @@ export default function CertificateAndDetailsButtons(props: Props) { { loc.locType === 'Identity' && props.viewer === 'LegalOfficer' && !isLogionIdentityLoc({ ...loc, requesterAddress: loc.requesterAccountId?.address }) && loc.requesterAccountId?.type === "Polkadot" && loc.status ==='CLOSED' && !props.isReadOnly && } { loc.locType === 'Identity' && !isLogionIdentityLoc({ ...loc, requesterAddress: loc.requesterAccountId?.address }) && props.viewer === 'LegalOfficer' && loc.status === "CLOSED" && hasVoteFeature && !loc.voteId && !props.isReadOnly && } - + { loc.locType === 'Identity' && props.viewer === 'User' && loc.status === "CLOSED" && } { loc.locType === 'Collection' && props.viewer === 'LegalOfficer' && } { loc.locType !== 'Collection' && props.viewer === 'LegalOfficer' && !props.isReadOnly && } diff --git a/src/loc/RequestVoteButton.test.tsx b/src/loc/RequestVoteButton.test.tsx index 9ad3bce3..b295e499 100644 --- a/src/loc/RequestVoteButton.test.tsx +++ b/src/loc/RequestVoteButton.test.tsx @@ -1,7 +1,7 @@ import { render, screen, waitFor } from "@testing-library/react"; import { clickByName } from "src/tests"; import RequestVoteButton from "./RequestVoteButton"; -import { ClosedLoc } from "src/__mocks__/@logion/client"; +import { ClosedIdentityLoc } from "src/__mocks__/@logion/client"; import { setLocState } from "./__mocks__/LocContextMock"; import { FAILED_SUBMISSION, NO_SUBMISSION, SUCCESSFUL_SUBMISSION, setExtrinsicSubmissionState } from "src/logion-chain/__mocks__/LogionChainMock"; import { expectSubmitting } from "src/test/Util"; @@ -12,7 +12,7 @@ jest.mock("../logion-chain"); describe("RequestVoteButton", () => { it("submits vote", async () => { - const locState = new ClosedLoc(); + const locState = new ClosedIdentityLoc(); setLocState(locState); locState.legalOfficer.requestVote = async (params: any) => { return VOTE_ID; @@ -25,7 +25,7 @@ describe("RequestVoteButton", () => { }); it("successfully creates a vote", async () => { - const locState = new ClosedLoc(); + const locState = new ClosedIdentityLoc(); setLocState(locState); locState.legalOfficer.requestVote = async (params: any) => { return VOTE_ID; @@ -39,7 +39,7 @@ describe("RequestVoteButton", () => { }); it("shows error on failure", async () => { - const locState = new ClosedLoc(); + const locState = new ClosedIdentityLoc(); setLocState(locState); locState.legalOfficer.requestVote = async () => {}; setExtrinsicSubmissionState(FAILED_SUBMISSION); diff --git a/src/loc/RequestVoteButton.tsx b/src/loc/RequestVoteButton.tsx index 16e40420..fbe0bd9b 100644 --- a/src/loc/RequestVoteButton.tsx +++ b/src/loc/RequestVoteButton.tsx @@ -1,4 +1,4 @@ -import { ClosedLoc } from "@logion/client"; +import { ClosedIdentityLoc } from "@logion/client"; import { useCallback, useState } from "react"; import ClientExtrinsicSubmitter, { Call, CallCallback } from "src/ClientExtrinsicSubmitter"; import Button from "src/common/Button"; @@ -18,7 +18,7 @@ export default function RequestVoteButton() { const [ submissionFailed, setSubmissionFailed ] = useState(false); const requestVoteCallback = useCallback(async (callback: CallCallback) => { - if(signer && (locState instanceof ClosedLoc)) { + if(signer && (locState instanceof ClosedIdentityLoc)) { const requestedVoteId = await locState.legalOfficer.requestVote({ callback, signer, diff --git a/src/loc/TestData.ts b/src/loc/TestData.ts index 42873768..a11088fb 100644 --- a/src/loc/TestData.ts +++ b/src/loc/TestData.ts @@ -48,6 +48,7 @@ export function buildLocRequest(locId: UUID, loc: LegalOfficerCase): LocData { legalFee: loc.legalFee, collectionItemFee: loc.collectionItemFee, tokensRecordFee: loc.tokensRecordFee, - } + }, + secrets: [], }; } diff --git a/src/loc/__snapshots__/ContextualizedLocDetails.test.tsx.snap b/src/loc/__snapshots__/ContextualizedLocDetails.test.tsx.snap index c7a25d40..e4573af7 100644 --- a/src/loc/__snapshots__/ContextualizedLocDetails.test.tsx.snap +++ b/src/loc/__snapshots__/ContextualizedLocDetails.test.tsx.snap @@ -60,6 +60,7 @@ exports[`ContextualizedLocDetails renders 1`] = ` }, }, "requesterLocId": undefined, + "secrets": Array [], "status": "OPEN", "verifiedIssuer": false, } @@ -124,6 +125,7 @@ exports[`ContextualizedLocDetails renders 1`] = ` }, }, "requesterLocId": undefined, + "secrets": Array [], "status": "OPEN", "verifiedIssuer": false, } @@ -199,6 +201,7 @@ exports[`ContextualizedLocDetails renders 1`] = ` }, }, "requesterLocId": undefined, + "secrets": Array [], "status": "OPEN", "verifiedIssuer": false, } @@ -271,6 +274,7 @@ exports[`ContextualizedLocDetails renders 1`] = ` }, }, "requesterLocId": undefined, + "secrets": Array [], "status": "OPEN", "verifiedIssuer": false, } @@ -336,6 +340,7 @@ exports[`ContextualizedLocDetails renders 1`] = ` }, }, "requesterLocId": undefined, + "secrets": Array [], "status": "OPEN", "verifiedIssuer": false, } @@ -401,6 +406,7 @@ exports[`ContextualizedLocDetails renders 1`] = ` }, }, "requesterLocId": undefined, + "secrets": Array [], "status": "OPEN", "verifiedIssuer": false, } @@ -473,6 +479,7 @@ exports[`ContextualizedLocDetails renders 1`] = ` }, }, "requesterLocId": undefined, + "secrets": Array [], "status": "OPEN", "verifiedIssuer": false, } diff --git a/src/loc/__snapshots__/UserContextualizedLocDetails.test.tsx.snap b/src/loc/__snapshots__/UserContextualizedLocDetails.test.tsx.snap index 3495aa93..a491bf81 100644 --- a/src/loc/__snapshots__/UserContextualizedLocDetails.test.tsx.snap +++ b/src/loc/__snapshots__/UserContextualizedLocDetails.test.tsx.snap @@ -61,6 +61,7 @@ exports[`UserContextualizedLocDetails renders for requester 1`] = ` }, }, "requesterLocId": undefined, + "secrets": Array [], "status": "OPEN", "verifiedIssuer": false, } @@ -160,6 +161,7 @@ exports[`UserContextualizedLocDetails renders for requester 1`] = ` }, }, "requesterLocId": undefined, + "secrets": Array [], "status": "OPEN", "verifiedIssuer": false, } @@ -229,6 +231,7 @@ exports[`UserContextualizedLocDetails renders for requester 1`] = ` }, }, "requesterLocId": undefined, + "secrets": Array [], "status": "OPEN", "verifiedIssuer": false, } @@ -295,6 +298,7 @@ exports[`UserContextualizedLocDetails renders for requester 1`] = ` }, }, "requesterLocId": undefined, + "secrets": Array [], "status": "OPEN", "verifiedIssuer": false, } @@ -361,6 +365,7 @@ exports[`UserContextualizedLocDetails renders for requester 1`] = ` }, }, "requesterLocId": undefined, + "secrets": Array [], "status": "OPEN", "verifiedIssuer": false, } @@ -426,6 +431,7 @@ exports[`UserContextualizedLocDetails renders for requester 1`] = ` }, }, "requesterLocId": undefined, + "secrets": Array [], "status": "OPEN", "verifiedIssuer": false, } @@ -501,6 +507,7 @@ exports[`UserContextualizedLocDetails renders for verified issuer 1`] = ` }, }, "requesterLocId": undefined, + "secrets": Array [], "status": "OPEN", "verifiedIssuer": false, } @@ -601,6 +608,7 @@ exports[`UserContextualizedLocDetails renders for verified issuer 1`] = ` }, }, "requesterLocId": undefined, + "secrets": Array [], "status": "OPEN", "verifiedIssuer": false, } @@ -670,6 +678,7 @@ exports[`UserContextualizedLocDetails renders for verified issuer 1`] = ` }, }, "requesterLocId": undefined, + "secrets": Array [], "status": "OPEN", "verifiedIssuer": false, } @@ -736,6 +745,7 @@ exports[`UserContextualizedLocDetails renders for verified issuer 1`] = ` }, }, "requesterLocId": undefined, + "secrets": Array [], "status": "OPEN", "verifiedIssuer": false, } @@ -802,6 +812,7 @@ exports[`UserContextualizedLocDetails renders for verified issuer 1`] = ` }, }, "requesterLocId": undefined, + "secrets": Array [], "status": "OPEN", "verifiedIssuer": false, } @@ -867,6 +878,7 @@ exports[`UserContextualizedLocDetails renders for verified issuer 1`] = ` }, }, "requesterLocId": undefined, + "secrets": Array [], "status": "OPEN", "verifiedIssuer": false, } diff --git a/src/loc/issuer/Nominate.tsx b/src/loc/issuer/Nominate.tsx index 6e8867e7..04c0fac2 100644 --- a/src/loc/issuer/Nominate.tsx +++ b/src/loc/issuer/Nominate.tsx @@ -5,7 +5,7 @@ import Icon from "../../common/Icon"; import Dialog from "../../common/Dialog"; import { useLocContext } from "../LocContext"; import { CallCallback, useLogionChain } from "../../logion-chain"; -import { ClosedLoc } from "@logion/client"; +import { ClosedIdentityLoc } from "@logion/client"; import './Nominate.css'; import ExtrinsicSubmissionStateView from "src/ExtrinsicSubmissionStateView"; @@ -26,7 +26,7 @@ export default function Nominate() { const changeIssuer = useCallback(async () => { setStatus('Confirming'); const call = async (callback: CallCallback) => mutateLocState(async current => { - if(signer && current instanceof ClosedLoc) { + if(signer && current instanceof ClosedIdentityLoc) { if(isIssuer) { return current.legalOfficer.dismissIssuer({ signer, @@ -36,7 +36,7 @@ export default function Nominate() { return current.legalOfficer.nominateIssuer({ signer, callback, - }); + }); } } else { return current; diff --git a/src/loc/secrets/AddSecretDialog.tsx b/src/loc/secrets/AddSecretDialog.tsx new file mode 100644 index 00000000..8dc82679 --- /dev/null +++ b/src/loc/secrets/AddSecretDialog.tsx @@ -0,0 +1,99 @@ +import { Secret } from "@logion/client"; +import Dialog from "../../common/Dialog"; +import { useCallback } from "react"; +import { useForm, Controller } from "react-hook-form"; +import FormGroup from "../../common/FormGroup"; +import { Form } from "react-bootstrap"; +import { useCommonContext } from "../../common/CommonContext"; + +export interface Props { + show: boolean; + onAddSecret: (secret: Secret) => void; + onCancel: () => void; +} + +export default function AddSecretDialog(props: Props) { + + const { colorTheme } = useCommonContext(); + const { handleSubmit, control, formState: { errors }, reset } = useForm(); + + const cancel = useCallback(() => { + props.onCancel(); + reset(); + }, [ props, reset ]) + + const submit = useCallback((secret: Secret) => { + props.onAddSecret(secret); + reset(); + }, [ props, reset ]) + + return ( + +

Add a Recoverable Secret

+ ( + + ) } /> + + } + colors={ colorTheme.dialog } + /> + ( + + ) } /> + + } + colors={ colorTheme.dialog } + /> +
+ ) +} diff --git a/src/loc/secrets/RemoveSecretDialog.css b/src/loc/secrets/RemoveSecretDialog.css new file mode 100644 index 00000000..abafc53c --- /dev/null +++ b/src/loc/secrets/RemoveSecretDialog.css @@ -0,0 +1,3 @@ +.RemoveSecretDialog img { + margin-bottom: 20px; +} diff --git a/src/loc/secrets/RemoveSecretDialog.tsx b/src/loc/secrets/RemoveSecretDialog.tsx new file mode 100644 index 00000000..405bbb3c --- /dev/null +++ b/src/loc/secrets/RemoveSecretDialog.tsx @@ -0,0 +1,40 @@ +import { Secret } from "@logion/client"; +import Dialog from "../../common/Dialog"; +import Icon from "../../common/Icon"; +import ViewableSecret from "./ViewableSecret"; +import "./RemoveSecretDialog.css" + +export interface Props { + secret: Secret | undefined; + onRemoveSecret: (secret: Secret) => void; + onCancel: () => void; +} + +export default function RemoveSecretDialog(props: Props) { + return ( + props.onRemoveSecret(props.secret!), + } + ] } + > + +

You are about to remove the secret { props.secret?.name }:

+

It will be impossible to recover it after, so make your own backup of the value:

+ +
+ ) +} diff --git a/src/loc/secrets/SecretsButton.tsx b/src/loc/secrets/SecretsButton.tsx new file mode 100644 index 00000000..019235d2 --- /dev/null +++ b/src/loc/secrets/SecretsButton.tsx @@ -0,0 +1,18 @@ +import Button from "../../common/Button"; +import { useNavigate } from "react-router-dom"; +import { secretsPath } from "../../wallet-user/UserPaths"; +import { useLocContext } from "../LocContext"; + +export default function SecretsButton() { + const { loc } = useLocContext(); + const navigate = useNavigate(); + if (loc === null) { + return null; + } + + return ( + + ) +} diff --git a/src/loc/secrets/SecretsPane.tsx b/src/loc/secrets/SecretsPane.tsx new file mode 100644 index 00000000..418aab4a --- /dev/null +++ b/src/loc/secrets/SecretsPane.tsx @@ -0,0 +1,86 @@ +import { useLocContext } from "../LocContext"; +import LocPane from "../LocPane"; +import Frame from "../../common/Frame"; +import { locDetailsPath as userLocDetailsPath } from "../../wallet-user/UserPaths"; +import { UserLocContextProvider } from "../UserLocContext"; +import { UUID } from "@logion/node-api"; +import { useParams } from "react-router-dom"; +import Button from "../../common/Button"; +import Icon from "../../common/Icon"; +import { useState, useCallback } from "react"; +import AddSecretDialog from "./AddSecretDialog"; +import { Secret, ClosedIdentityLoc } from "@logion/client"; +import SecretsTable from "./SecretsTable"; +import RemoveSecretDialog from "./RemoveSecretDialog"; + +function UserSecretsPane() { + const { loc, locState, backPath, mutateLocState } = useLocContext(); + const [ showAddDialog, setShowAddDialog ] = useState(false); + const [ secretToRemove, setSecretToRemove ] = useState(); + + const addSecret = useCallback(async (secret: Secret) => { + await mutateLocState(async current => { + if (current instanceof ClosedIdentityLoc) { + return await current.addSecret(secret); + } else { + return current; + } + }) + setShowAddDialog(false); + }, [ mutateLocState ]) + + const removeSecret = useCallback(async (secret: Secret) => { + await mutateLocState(async current => { + if (current instanceof ClosedIdentityLoc) { + return await current.removeSecret(secret.name); + } else { + return current; + } + }) + setSecretToRemove(undefined); + }, [ mutateLocState ]) + + return ( + + + + + setShowAddDialog(false) } + /> + setSecretToRemove(undefined) } + /> + + + ) +} + +export default function SecretsPane() { + const locId = new UUID(useParams<"locId">().locId); + + return ( + + + + ); +} diff --git a/src/loc/secrets/SecretsTable.tsx b/src/loc/secrets/SecretsTable.tsx new file mode 100644 index 00000000..b8f56d65 --- /dev/null +++ b/src/loc/secrets/SecretsTable.tsx @@ -0,0 +1,46 @@ +import Table, { EmptyTableMessage, Cell, ActionCell } from "../../common/Table"; +import { Secret } from "@logion/client"; +import Button from "react-bootstrap/Button"; +import Icon from "../../common/Icon"; +import ViewableSecret from "./ViewableSecret"; + +export interface Properties { + secrets: Secret[]; + onRemoveSecret: (secret: Secret) => void; +} + +export default function SecretsTable(props: Properties) { + + return ( + <> + + }, + { + header: "Value", + render: secret => + }, + { + header: "", + width: "70px", + render: secret => + + + + }, + ] } + renderEmpty={ () => No secret to display } + /> + + ) +} diff --git a/src/loc/secrets/ViewableSecret.css b/src/loc/secrets/ViewableSecret.css new file mode 100644 index 00000000..512b4d51 --- /dev/null +++ b/src/loc/secrets/ViewableSecret.css @@ -0,0 +1,5 @@ +.ViewableSecret { + display: flex; + justify-content: center; + line-height: 40px; +} diff --git a/src/loc/secrets/ViewableSecret.tsx b/src/loc/secrets/ViewableSecret.tsx new file mode 100644 index 00000000..9fb59bc9 --- /dev/null +++ b/src/loc/secrets/ViewableSecret.tsx @@ -0,0 +1,18 @@ +import { useState } from "react"; +import Checkbox from "../../components/toggle/Checkbox"; +import "./ViewableSecret.css"; + +export interface Props { + value: string; +} + +export default function ViewableSecret(props: Props) { + const [ hidden, setHidden ] = useState(true); + return ( +
+ { !hidden && { props.value } } + { hidden && ****** } +
+ ) +} diff --git a/src/wallet-user/UserPaths.tsx b/src/wallet-user/UserPaths.tsx index 5c7f0ffc..22053248 100644 --- a/src/wallet-user/UserPaths.tsx +++ b/src/wallet-user/UserPaths.tsx @@ -117,3 +117,10 @@ export function invitedContributorsPath(locId: UUID) { .replace(":locId", locId.toString()); } +export const SECRETS_RELATIVE_PATH = LOC_DETAILS_RELATIVE_PATH + '/secrets'; +export function secretsPath(locId: UUID) { + return USER_PATH + SECRETS_RELATIVE_PATH + .replace(":locType", "identity") + .replace(":locId", locId.toString()); +} + diff --git a/src/wallet-user/UserRouter.tsx b/src/wallet-user/UserRouter.tsx index e72a96a8..9431c1e4 100644 --- a/src/wallet-user/UserRouter.tsx +++ b/src/wallet-user/UserRouter.tsx @@ -25,7 +25,8 @@ import { ISSUER_TOKENS_RECORD_RELATIVE_PATH, TOKENS_RECORD_DOCUMENT_CLAIM_HISTORY_RELATIVE_PATH, ISSUER_TOKENS_RECORD_DOCUMENT_CLAIM_HISTORY_RELATIVE_PATH, - INVITED_CONTRIBUTORS_RELATIVE_PATH + INVITED_CONTRIBUTORS_RELATIVE_PATH, + SECRETS_RELATIVE_PATH } from "./UserPaths"; import Settings from "../settings/Settings"; import Transactions from "../common/Transactions"; @@ -47,6 +48,7 @@ import { UserInvitedContributorsPane } from "../loc/invited-contributor/InvitedC import LocsDashboard from 'src/loc/dashboard/LocsDashboard'; import LocRequestButton from "../components/locrequest/LocRequestButton"; import DataLocRequest from "../loc/DataLocRequest"; +import SecretsPane from "../loc/secrets/SecretsPane"; export default function UserRouter() { const { accounts } = useLogionChain(); @@ -173,6 +175,7 @@ export default function UserRouter() { } /> } /> }/> + }/> ); } diff --git a/src/wallet-user/__snapshots__/UserRouter.test.tsx.snap b/src/wallet-user/__snapshots__/UserRouter.test.tsx.snap index b4b2a479..da1a8262 100644 --- a/src/wallet-user/__snapshots__/UserRouter.test.tsx.snap +++ b/src/wallet-user/__snapshots__/UserRouter.test.tsx.snap @@ -262,5 +262,9 @@ exports[`renders 1`] = ` } path="/loc/:locType/:locId/invited-contributors" /> + } + path="/loc/:locType/:locId/secrets" + /> `; diff --git a/yarn.lock b/yarn.lock index eb3a397a..7c047f2c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3216,15 +3216,15 @@ __metadata: languageName: node linkType: hard -"@logion/client@npm:^0.45.0-2": - version: 0.45.0-2 - resolution: "@logion/client@npm:0.45.0-2" +"@logion/client@npm:^0.45.0-7": + version: 0.45.0-7 + resolution: "@logion/client@npm:0.45.0-7" dependencies: "@logion/node-api": ^0.30.0 axios: ^1.6.7 luxon: ^3.4.4 mime-db: ^1.52.0 - checksum: 6550c4a5649a58834a9743e4115b32b8de7996f31134c63a687e13b9066b27179ad65b3d80f5eb954693a0a35832aac8d77e1bfa5176f78ff85d6224f4c5007f + checksum: 37679a03af0afa468e6378c430fb31923397c268f94f8a4edaeece8d65fc38e0871dda9f19b96faf05d6be4c423ab9f2c5ce5573af1ca7e76e645eb5832c93a0 languageName: node linkType: hard @@ -12106,7 +12106,7 @@ __metadata: "@babel/preset-react": ^7.23.3 "@babel/preset-typescript": ^7.23.3 "@creativecommons/cc-assets": ^0.1.0 - "@logion/client": ^0.45.0-2 + "@logion/client": ^0.45.0-7 "@logion/client-browser": ^0.3.5 "@logion/crossmint": ^0.1.32 "@logion/extension": ^0.8.1-1