diff --git a/packages/hedera-identify-snap/package.json b/packages/hedera-identify-snap/package.json index 8840ccd9..e2631444 100644 --- a/packages/hedera-identify-snap/package.json +++ b/packages/hedera-identify-snap/package.json @@ -26,30 +26,8 @@ "start": "yarn workspaces foreach --parallel --interlaced --verbose run start", "test": "yarn workspaces foreach --parallel --interlaced --verbose run test" }, - "devDependencies": { - "@metamask/eslint-config": "^11.1.0", - "@metamask/eslint-config-jest": "^11.1.0", - "@metamask/eslint-config-nodejs": "^11.1.0", - "@metamask/eslint-config-typescript": "^11.1.0", - "@typescript-eslint/eslint-plugin": "^5.57.1", - "@typescript-eslint/parser": "^5.57.1", - "eslint": "^8.38.0", - "eslint-config-prettier": "^9.0.0", - "eslint-plugin-import": "^2.28.1", - "eslint-plugin-jest": "^27.4.0", - "eslint-plugin-jsdoc": "^46.8.1", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-prettier": "^4.2.1", - "prettier": "^3.0.3", - "prettier-plugin-packagejson": "^2.4.5", - "typescript": "^5.2.2" - }, "packageManager": "yarn@3.2.1", "engines": { "node": ">=18.13.0" - }, - "dependencies": { - "@yarnpkg/plugin-workspace-tools": "^4.1.0", - "protobufjs": "^7.4.0" } } diff --git a/packages/hedera-identify-snap/packages/site/src/components/cards/CreateNewHederaAccount.tsx b/packages/hedera-identify-snap/packages/site/src/components/cards/CreateNewHederaAccount.tsx deleted file mode 100644 index 224c1709..00000000 --- a/packages/hedera-identify-snap/packages/site/src/components/cards/CreateNewHederaAccount.tsx +++ /dev/null @@ -1,178 +0,0 @@ -/*- - * - * Hedera Identify Snap - * - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -import { FC, useContext, useRef, useState } from 'react'; -import { - MetaMaskContext, - MetamaskActions, -} from '../../contexts/MetamaskContext'; -import useModal from '../../hooks/useModal'; -import { HederaMirrorInfo } from '../../types/hedera'; -import { - createNewHederaAccount, - getCurrentMetamaskAccount, - getCurrentNetwork, - shouldDisplayReconnectButton, -} from '../../utils'; -import { Card, SendHelloButton } from '../base'; -import ExternalAccount, { - GetExternalAccountRef, -} from '../sections/ExternalAccount'; - -type Props = { - setMetamaskAddress: React.Dispatch>; - setCurrentChainId: React.Dispatch>; -}; - -const CreateNewHederaAccount: FC = ({ - setMetamaskAddress, - setCurrentChainId, -}) => { - const [state, dispatch] = useContext(MetaMaskContext); - const [newAccountPublickey, setNewAccountPublickey] = useState( - '302d300706052b8104000a032200034920445ae433dbfa7b11da73305566f143bfdff959779ac8a005b13a875460f2', - ); - const [newAccountEvmAddress, setNewAccountEvmAddress] = useState( - '0x9dA3b1ACFec871e668B51828faedB607e37609F9', - ); - const [hbarAmountToSend, setHbarAmountToSend] = useState(0); - const [loading, setLoading] = useState(false); - - const { showModal } = useModal(); - - const externalAccountRef = useRef(null); - - const handleCreateNewHederaAccount = async () => { - setLoading(true); - try { - const metamaskAddress = await getCurrentMetamaskAccount(); - setMetamaskAddress(metamaskAddress); - setCurrentChainId(await getCurrentNetwork()); - - const externalAccountParams = - externalAccountRef.current?.handleGetAccountParams(); - - if (hbarAmountToSend > 0) { - // If you want to create a hbar account for a public key, just uncomment the line 'newAccountPublickey' - const newHederaAccountInfo = (await createNewHederaAccount( - metamaskAddress, - { - hbarAmountToSend, - newAccountEvmAddress, - // newAccountPublickey, - }, - externalAccountParams, - )) as HederaMirrorInfo; - console.log( - `Your hedera account info: ${JSON.stringify( - newHederaAccountInfo, - null, - 4, - )}`, - ); - let title = 'Hedera Account Info'; - if (newHederaAccountInfo.newlyCreated) { - title = `Newly created ${title}`; - } else { - console.log( - "No hbars were sent to the new account because a hedera account already exists on the ledger. We're just returing the info by quering hedera mirror node", - ); - } - showModal({ - title, - content: JSON.stringify(newHederaAccountInfo, null, 4), - }); - } else { - showModal({ - title: 'Error while creating a new hedera account', - content: 'The amount of hbars must be greater than 0', - }); - } - setHbarAmountToSend(0); - } catch (e) { - console.error(e); - dispatch({ type: MetamaskActions.SetError, payload: e }); - } - setLoading(false); - }; - - return ( - - - {/* If you want to create a hbar account for a public key, just - uncomment the below lines */} - {/* */} - -
- - - ), - button: ( - - ), - }} - disabled={!state.installedSnap} - fullWidth={ - state.isFlask && - Boolean(state.installedSnap) && - !shouldDisplayReconnectButton(state.installedSnap) - } - /> - ); -}; - -export { CreateNewHederaAccount }; diff --git a/packages/hedera-identify-snap/packages/site/src/components/cards/GetAccountInfo.tsx b/packages/hedera-identify-snap/packages/site/src/components/cards/GetAccountInfo.tsx index d2db8047..1069e68d 100644 --- a/packages/hedera-identify-snap/packages/site/src/components/cards/GetAccountInfo.tsx +++ b/packages/hedera-identify-snap/packages/site/src/components/cards/GetAccountInfo.tsx @@ -25,7 +25,6 @@ import { } from '../../contexts/MetamaskContext'; import useModal from '../../hooks/useModal'; import { - PublicAccountInfo, getAccountInfo, getCurrentMetamaskAccount, getCurrentNetwork, @@ -35,6 +34,7 @@ import { Card, SendHelloButton } from '../base'; import ExternalAccount, { GetExternalAccountRef, } from '../sections/ExternalAccount'; +import { PublicAccountInfo } from '../../types/snap'; type Props = { setMetamaskAddress: React.Dispatch>; diff --git a/packages/hedera-identify-snap/packages/site/src/components/cards/SwitchDIDMethod.tsx b/packages/hedera-identify-snap/packages/site/src/components/cards/SwitchDIDMethod.tsx new file mode 100644 index 00000000..1c08dc2e --- /dev/null +++ b/packages/hedera-identify-snap/packages/site/src/components/cards/SwitchDIDMethod.tsx @@ -0,0 +1,119 @@ +/*- + * + * Hedera Identify Snap + * + * Copyright (C) 2024 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import { FC, useContext, useState } from 'react'; +import Form from 'react-bootstrap/esm/Form'; +import { + MetaMaskContext, + MetamaskActions, +} from '../../contexts/MetamaskContext'; +import { + getCurrentMetamaskAccount, + getCurrentNetwork, + shouldDisplayReconnectButton, + switchDIDMethod, +} from '../../utils'; +import { Card, SendHelloButton } from '../base'; + +type Props = { + setMetamaskAddress: React.Dispatch>; + setCurrentChainId: React.Dispatch>; +}; + +const SwitchDIDMethod: FC = ({ + setMetamaskAddress, + setCurrentChainId, +}) => { + const [state, dispatch] = useContext(MetaMaskContext); + const [didMethod, setDidMethod] = useState('did:pkh'); // Default method is 'did:pkh' + const [loading, setLoading] = useState(false); + + const handleswitchDIDMethodClick = async () => { + setLoading(true); + try { + const metamaskAddress = await getCurrentMetamaskAccount(); + setMetamaskAddress(metamaskAddress); + setCurrentChainId(await getCurrentNetwork()); + + const switched = await switchDIDMethod(metamaskAddress, didMethod); + console.log(`DID Method switched : ${switched}`); + } catch (e) { + console.error(e); + dispatch({ type: MetamaskActions.SetError, payload: e }); + } + setLoading(false); + }; + + return ( + + setDidMethod(e.target.value)} + style={{ marginBottom: 8 }} + /> + setDidMethod(e.target.value)} + style={{ marginBottom: 8 }} + /> + setDidMethod(e.target.value)} + style={{ marginBottom: 8 }} + /> + + ), + button: ( + + ), + }} + disabled={!state.installedSnap} + fullWidth={ + state.isFlask && + Boolean(state.installedSnap) && + !shouldDisplayReconnectButton(state.installedSnap) + } + /> + ); +}; + +export { SwitchDIDMethod }; diff --git a/packages/hedera-identify-snap/packages/site/src/components/cards/index.ts b/packages/hedera-identify-snap/packages/site/src/components/cards/index.ts index 82723452..af21f59e 100644 --- a/packages/hedera-identify-snap/packages/site/src/components/cards/index.ts +++ b/packages/hedera-identify-snap/packages/site/src/components/cards/index.ts @@ -20,7 +20,6 @@ export { ConfigureGoogleAccount } from './ConfigureGoogleAccount'; export { ConnectIdentitySnap } from './ConnectIdentitySnap'; -export { CreateNewHederaAccount } from './CreateNewHederaAccount'; export { CreateVC } from './CreateVC'; export { DeleteAllVCs } from './DeleteAllVCs'; export { GetAccountInfo } from './GetAccountInfo'; diff --git a/packages/hedera-identify-snap/packages/site/src/pages/index.tsx b/packages/hedera-identify-snap/packages/site/src/pages/index.tsx index 0c626467..67f62571 100644 --- a/packages/hedera-identify-snap/packages/site/src/pages/index.tsx +++ b/packages/hedera-identify-snap/packages/site/src/pages/index.tsx @@ -27,7 +27,6 @@ import { Card, InstallFlaskButton } from '../components/base'; import { ConfigureGoogleAccount, ConnectIdentitySnap, - CreateNewHederaAccount, CreateVC, DeleteAllVCs, GetAccountInfo, @@ -52,9 +51,10 @@ import { Span, } from '../config/styles'; import { MetaMaskContext, MetamaskActions } from '../contexts/MetamaskContext'; -import { HederaAccountParams, PublicAccountInfo } from '../types/snap'; +import { PublicAccountInfo } from '../types/snap'; import { connectSnap, getCurrentNetwork, getSnap } from '../utils'; import { getNetwork, validHederaChainID } from '../utils/hedera'; +import { SwitchDIDMethod } from '../components/cards/SwitchDIDMethod'; const Index = () => { const [state, dispatch] = useContext(MetaMaskContext); @@ -113,23 +113,18 @@ const Index = () => { {isHederaNetwork ? accountInfo && ( <> -
- Hedera Account ID:{' '} - { - (accountInfo?.extraData as HederaAccountParams) - ?.accountId - } -
+
Hedera Account ID: {accountInfo?.accountID}
Did Method: {accountInfo?.method}
Did: {accountInfo?.did}
-
EVM Address: {accountInfo?.evmAddress}
+
Metamask Address: {accountInfo?.metamaskAddress}
+
Snap Address: {accountInfo?.snapAddress}
) : accountInfo && ( <>
Did Method: {accountInfo?.method}
Did: {accountInfo?.did}
-
EVM Address: {accountInfo?.evmAddress}
+
EVM Address: {accountInfo?.metamaskAddress}
)} @@ -160,17 +155,15 @@ const Index = () => { setCurrentChainId={setCurrentChainId} /> - {isHederaNetwork && ( - - )} - + + { }; /** - * Invoke the "getAccountInfo" method from the snap. + * Invoke the "switchDIDMethod" method from the snap. */ - -export const getAccountInfo = async ( +export const switchDIDMethod = async ( metamaskAddress: string, - externalAccountparams?: ExternalAccountParams, + didMethod: string, ) => { return await window.ethereum.request({ method: 'wallet_invokeSnap', params: { snapId: defaultSnapId, request: { - method: 'getAccountInfo', - params: { metamaskAddress, ...externalAccountparams }, + method: 'switchDIDMethod', + params: { metamaskAddress, didMethod }, }, }, }); }; /** - * Invoke "createNewHederaAccount" method from the snap + * Invoke the "getAccountInfo" method from the snap. */ - -export const createNewHederaAccount = async ( +export const getAccountInfo = async ( metamaskAddress: string, - { - hbarAmountToSend, - newAccountPublickey = '', - newAccountEvmAddress = '', - }: CreateNewHederaAccountRequestParams, externalAccountparams?: ExternalAccountParams, ) => { - if (newAccountPublickey) { - return await window.ethereum.request({ - method: 'wallet_invokeSnap', - params: { - snapId: defaultSnapId, - request: { - method: 'createNewHederaAccount', - params: { - metamaskAddress, - hbarAmountToSend, - newAccountPublickey, - ...externalAccountparams, - }, - }, - }, - }); - } return await window.ethereum.request({ method: 'wallet_invokeSnap', params: { snapId: defaultSnapId, request: { - method: 'createNewHederaAccount', - params: { - metamaskAddress, - hbarAmountToSend, - newAccountEvmAddress, - ...externalAccountparams, - }, + method: 'getAccountInfo', + params: { metamaskAddress, ...externalAccountparams }, }, }, }); @@ -201,7 +169,6 @@ export const createNewHederaAccount = async ( /** * Invoke the "resolveDID" method from the snap. */ - export const resolveDID = async ( metamaskAddress: string, did?: string, diff --git a/packages/hedera-identify-snap/packages/snap/README.md b/packages/hedera-identify-snap/packages/snap/README.md index cb5b13de..e8cce866 100644 --- a/packages/hedera-identify-snap/packages/snap/README.md +++ b/packages/hedera-identify-snap/packages/snap/README.md @@ -91,7 +91,6 @@ process; see those repositories for more information about how they work. - Babel is used for transpiling TypeScript to JavaScript, so when building with the CLI, `transpilationMode` must be set to `localOnly` (default) or `localAndDeps`. - For the global `wallet` type to work, you have to add the following to your `tsconfig.json`: - ```json { "files": ["./node_modules/@metamask/snap-types/global.d.ts"] diff --git a/packages/hedera-identify-snap/packages/snap/images/icon.svg b/packages/hedera-identify-snap/packages/snap/images/icon.svg index 3326c6d4..4eee4e63 100755 --- a/packages/hedera-identify-snap/packages/snap/images/icon.svg +++ b/packages/hedera-identify-snap/packages/snap/images/icon.svg @@ -1,25 +1 @@ - - - - - - - - - - - + \ No newline at end of file diff --git a/packages/hedera-identify-snap/packages/snap/package.json b/packages/hedera-identify-snap/packages/snap/package.json index 92adc293..ec84edc1 100644 --- a/packages/hedera-identify-snap/packages/snap/package.json +++ b/packages/hedera-identify-snap/packages/snap/package.json @@ -5,6 +5,8 @@ "keywords": [ "MetaMask", "Snaps", + "Hedera Hashgraph", + "HBAR", "Identity", "VC", "Verifiable Credential", @@ -58,10 +60,8 @@ "@metamask/providers": "^17.2.0", "@metamask/rpc-errors": "^6.3.1", "@metamask/snaps-sdk": "^6.3.0", - "@metamask/snaps-ui": "^3.1.0", "@veramo/core": "5.1.2", "@veramo/credential-eip712": "^6.0.0", - "@veramo/credential-ld": "5.1.2", "@veramo/credential-w3c": "5.1.2", "@veramo/did-jwt": "5.1.2", "@veramo/did-manager": "5.1.2", @@ -70,14 +70,15 @@ "@veramo/key-manager": "5.1.2", "@veramo/kms-local": "5.1.2", "@veramo/message-handler": "5.1.2", - "@veramo/selective-disclosure": "5.1.2", "bignumber.js": "^9.1.2", "caip": "^1.1.1", "did-jwt-vc": "^3.1.3", "did-resolver": "^4.1.0", "ethers": "^6.13.2", + "js-sha256": "^0.11.0", "jsonpath": "^1.1.1", "lodash": "^4.17.21", + "secp256k1": "^5.0.0", "uuid": "^10.0.0" }, "devDependencies": { @@ -93,6 +94,7 @@ "@types/jest": "^29.5.12", "@types/jsonpath": "^0.2.4", "@types/lodash.clonedeep": "^4.5.9", + "@types/secp256k1": "^4.0.6", "@types/uuid": "^10.0.0", "@typescript-eslint/eslint-plugin": "5.62.0", "@typescript-eslint/parser": "5.62.0", diff --git a/packages/hedera-identify-snap/packages/snap/snap.manifest.json b/packages/hedera-identify-snap/packages/snap/snap.manifest.json index 5eb8d1f3..70cb97a0 100644 --- a/packages/hedera-identify-snap/packages/snap/snap.manifest.json +++ b/packages/hedera-identify-snap/packages/snap/snap.manifest.json @@ -7,7 +7,7 @@ "url": "git+https://github.com/hashgraph/hedera-metamask-snaps.git" }, "source": { - "shasum": "KKHT+Asb4aIVAUtmMGvhd4YOL9j/dyuBleGXdi/b1gs=", + "shasum": "DHyq8nTsEjIkJc/37mafBVLK/Sy8kxGsHx/1RKzDiU4=", "location": { "npm": { "filePath": "dist/bundle.js", diff --git a/packages/hedera-identify-snap/packages/snap/src/components/common.tsx b/packages/hedera-identify-snap/packages/snap/src/components/common.tsx new file mode 100644 index 00000000..b71052b8 --- /dev/null +++ b/packages/hedera-identify-snap/packages/snap/src/components/common.tsx @@ -0,0 +1,66 @@ +/*- + * + * Hedera Wallet Snap + * + * Copyright (C) 2024 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import type { SnapComponent } from '@metamask/snaps-sdk/jsx'; +import { + Address as MetamaskAddress, + Bold as MetamaskBold, + Box as MetamaskBox, + Copyable as MetamaskCopyable, + Divider as MetamaskDivider, + Heading as MetamaskHeading, + Link as MetamaskLink, + Row as MetamaskRow, + Text as MetamaskText, +} from '@metamask/snaps-sdk/jsx'; + +export const Box = MetamaskBox as any; +export const Heading = MetamaskHeading as any; +export const Divider = MetamaskDivider as any; +export const Row = MetamaskRow as any; +export const Text = MetamaskText as any; +export const Copyable = MetamaskCopyable as any; +export const Address = MetamaskAddress as any; +export const Link = MetamaskLink as any; +export const Bold = MetamaskBold as any; + +export type CommonProps = { + origin: string; + network: string; + mirrorNodeUrl: string; + [key: string]: any; +}; + +const MetamaskUI: SnapComponent = ({ origin, network }) => { + return ( + + Request + + {origin} + + + {network} + + + + ); +}; + +export const CommonUI = MetamaskUI as any; diff --git a/packages/hedera-identify-snap/packages/snap/src/components/hello.tsx b/packages/hedera-identify-snap/packages/snap/src/components/hello.tsx new file mode 100644 index 00000000..4ba1d24e --- /dev/null +++ b/packages/hedera-identify-snap/packages/snap/src/components/hello.tsx @@ -0,0 +1,38 @@ +/*- + * + * Hedera Wallet Snap + * + * Copyright (C) 2024 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import type { SnapComponent } from '@metamask/snaps-sdk/jsx'; +import { Box, CommonUI, Heading, Row, Text, type CommonProps } from './common'; + +const MetamaskUI: SnapComponent = ({ origin, network }) => { + return ( + + + Hello!! + + + You are seeing this because you interacted with the 'hello' method + + + + ); +}; + +export const HelloUI = MetamaskUI as any; diff --git a/packages/hedera-identify-snap/packages/snap/src/components/showAccountPrivateKey.tsx b/packages/hedera-identify-snap/packages/snap/src/components/showAccountPrivateKey.tsx new file mode 100644 index 00000000..414042c1 --- /dev/null +++ b/packages/hedera-identify-snap/packages/snap/src/components/showAccountPrivateKey.tsx @@ -0,0 +1,85 @@ +/*- + * + * Hedera Wallet Snap + * + * Copyright (C) 2024 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import type { SnapComponent } from '@metamask/snaps-sdk/jsx'; +import { + Address, + Box, + CommonUI, + Copyable, + Heading, + Row, + Text, + type CommonProps, +} from './common'; + +type Props = CommonProps & { + privateKey: string; + publicKey: string; + accountID: string; + evmAddress: string; +}; + +const MetamaskUI: SnapComponent = ({ + origin, + network, + mirrorNodeUrl, + privateKey, + publicKey, + accountID, + evmAddress, +}) => { + return ( + + + Show Account Private Key + + Account ID + + + +
+ + + Public Key + + + + + Never disclose this key. Anyone with your private keys can steal any + assets held in your account + + + + Private Key + + + + ); +}; + +export const ShowAccountPrivateKeyUI = MetamaskUI as any; diff --git a/packages/hedera-identify-snap/packages/snap/src/constants/index.ts b/packages/hedera-identify-snap/packages/snap/src/constants/index.ts new file mode 100644 index 00000000..1c871549 --- /dev/null +++ b/packages/hedera-identify-snap/packages/snap/src/constants/index.ts @@ -0,0 +1 @@ +export * from './multicodec'; diff --git a/packages/hedera-identify-snap/packages/snap/src/constants/multicodec.ts b/packages/hedera-identify-snap/packages/snap/src/constants/multicodec.ts new file mode 100644 index 00000000..8bce48f7 --- /dev/null +++ b/packages/hedera-identify-snap/packages/snap/src/constants/multicodec.ts @@ -0,0 +1,33 @@ +/*- + * + * Hedera Identify Snap + * + * Copyright (C) 2024 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Source: https://github.com/multiformats/multicodec/blob/master/table.csv +export type CodecName = + | 'secp256k1-priv' + | 'secp256k1-pub' + | 'ed25519-priv' + | 'ed25519-pub'; + +export const MULTICODECS: Record = { + 'secp256k1-priv': new Uint8Array([129, 38]), + 'secp256k1-pub': new Uint8Array([231, 1]), + 'ed25519-priv': new Uint8Array([128, 38]), + 'ed25519-pub': new Uint8Array([237, 1]), +}; diff --git a/packages/hedera-identify-snap/packages/snap/src/did/key/keyDidProvider.ts b/packages/hedera-identify-snap/packages/snap/src/did/key/keyDidProvider.ts new file mode 100644 index 00000000..38973c57 --- /dev/null +++ b/packages/hedera-identify-snap/packages/snap/src/did/key/keyDidProvider.ts @@ -0,0 +1,140 @@ +/*- + * + * Hedera Identify Snap + * + * Copyright (C) 2024 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/* eslint-disable @typescript-eslint/no-unsafe-argument */ +/* eslint-disable @typescript-eslint/no-unsafe-member-access */ +/* eslint-disable @typescript-eslint/no-unsafe-call */ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/require-await */ +import { + IAgentContext, + IIdentifier, + IKey, + IKeyManager, + IService, +} from '@veramo/core'; +import { AbstractIdentifierProvider } from '@veramo/did-manager'; +import { base58btc } from 'multiformats/bases/base58'; +import { addMulticodecPrefix } from '../../utils/formatUtils'; + +type IContext = IAgentContext; + +/** + * {@link @veramo/did-manager#DIDManager} identifier provider for `did:key` identifiers + * + * @beta This API may change without a BREAKING CHANGE notice. + */ +export class KeyDIDProvider extends AbstractIdentifierProvider { + private defaultKms: string; + + constructor(options: { defaultKms: string }) { + super(); + this.defaultKms = options.defaultKms; + } + + async createIdentifier( + // eslint-disable-next-line @typescript-eslint/no-unused-vars + { kms, options }: { kms?: string; options?: any }, + context: IContext, + ): Promise> { + const key = await context.agent.keyManagerCreate({ + kms: kms || this.defaultKms, + type: 'Ed25519', + }); + + const methodSpecificId = Buffer.from( + base58btc.encode( + addMulticodecPrefix( + 'ed25519-pub', + Buffer.from(key.publicKeyHex, 'hex'), + ), + ), + ).toString(); + + const identifier: Omit = { + did: `did:key:${methodSpecificId}`, + controllerKeyId: key.kid, + keys: [key], + services: [], + }; + return identifier; + } + + async updateIdentifier( + args: { + did: string; + kms?: string | undefined; + alias?: string | undefined; + options?: any; + }, + context: IAgentContext, + ): Promise { + throw new Error('KeyDIDProvider updateIdentifier not supported yet.'); + } + + async deleteIdentifier( + identifier: IIdentifier, + context: IContext, + ): Promise { + // eslint-disable-next-line no-restricted-syntax + for (const { kid } of identifier.keys) { + // eslint-disable-next-line no-await-in-loop + await context.agent.keyManagerDelete({ kid }); + } + return true; + } + + async addKey( + { + identifier, + key, + options, + }: { identifier: IIdentifier; key: IKey; options?: any }, + context: IContext, + ): Promise { + throw Error('KeyDIDProvider addKey not supported'); + } + + async addService( + { + identifier, + service, + options, + }: { identifier: IIdentifier; service: IService; options?: any }, + context: IContext, + ): Promise { + throw Error('KeyDIDProvider addService not supported'); + } + + async removeKey( + args: { identifier: IIdentifier; kid: string; options?: any }, + context: IContext, + ): Promise { + throw Error('KeyDIDProvider removeKey not supported'); + } + + async removeService( + args: { identifier: IIdentifier; id: string; options?: any }, + context: IContext, + ): Promise { + throw Error('KeyDIDProvider removeService not supported'); + } +} diff --git a/packages/hedera-identify-snap/packages/snap/src/did/key/keyDidResolver.ts b/packages/hedera-identify-snap/packages/snap/src/did/key/keyDidResolver.ts new file mode 100644 index 00000000..61efc579 --- /dev/null +++ b/packages/hedera-identify-snap/packages/snap/src/did/key/keyDidResolver.ts @@ -0,0 +1,121 @@ +/*- + * + * Hedera Identify Snap + * + * Copyright (C) 2024 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import { + DIDDocument, + DIDResolutionOptions, + DIDResolutionResult, + DIDResolver, + ParsedDID, + Resolvable, +} from 'did-resolver'; +import { getAccountStateByCoinType, getState } from '../../snap/state'; +import { getCurrentMetamaskAccount } from '../../veramo/accountImport'; + +export const resolveSecp256k1 = async ( + account: string, + did: string, +): Promise => { + const accountState = await getAccountStateByCoinType( + await getState(), + account, + ); + const controllerKeyId = `metamask-${account}`; + const publicKey = accountState.snapKeyStore[controllerKeyId].publicKeyHex; + + // TODO: Change id ? + const didDocument: DIDDocument = { + id: `did:key:${did}#${did}`, + '@context': [ + 'https://www.w3.org/ns/did/v1', + 'https://w3id.org/security/suites/secp256k1-2019/v1', + ], + assertionMethod: [`did:key:${did}#${did}`], + authentication: [`did:key:${did}#${did}`], + capabilityInvocation: [`did:key:${did}#${did}`], + capabilityDelegation: [`did:key:${did}#${did}`], + keyAgreement: [`did:key:${did}#${did}`], + verificationMethod: [ + { + id: `did:key:${did}#${did}`, + type: 'EcdsaSecp256k1RecoveryMethod2020', + controller: `did:key:${did}#${did}`, + publicKeyHex: publicKey.split('0x')[1], + }, + ], + }; + return didDocument; +}; + +type ResolutionFunction = ( + account: string, + did: string, +) => Promise; + +const startsWithMap: Record = { + 'did:key:zQ3s': resolveSecp256k1, +}; + +export const resolveDidKey: DIDResolver = async ( + didUrl: string, + parsed: ParsedDID, + resolver: Resolvable, + options: DIDResolutionOptions, +): Promise => { + try { + const account = await getCurrentMetamaskAccount(); + const startsWith = parsed.did.substring(0, 12); + if (startsWithMap[startsWith] !== undefined) { + const didDocument = await startsWithMap[startsWith](account, didUrl); + return { + didDocumentMetadata: {}, + didResolutionMetadata: {}, + didDocument, + } as DIDResolutionResult; + } + + return { + didDocumentMetadata: {}, + didResolutionMetadata: { + error: 'invalidDid', + message: 'unsupported key type for did:key', + }, + didDocument: null, + }; + } catch (err: unknown) { + return { + didDocumentMetadata: {}, + didResolutionMetadata: { + error: 'invalidDid', + message: (err as string).toString(), + }, + didDocument: null, + }; + } +}; + +/** + * Provides a mapping to a did:key resolver, usable by {@link did-resolver#Resolver}. + * + * @public + */ +export function getDidKeyResolver() { + return { key: resolveDidKey }; +} diff --git a/packages/hedera-identify-snap/packages/snap/src/did/key/keyDidUtils.ts b/packages/hedera-identify-snap/packages/snap/src/did/key/keyDidUtils.ts new file mode 100644 index 00000000..29b92aaa --- /dev/null +++ b/packages/hedera-identify-snap/packages/snap/src/did/key/keyDidUtils.ts @@ -0,0 +1,34 @@ +/*- + * + * Hedera Identify Snap + * + * Copyright (C) 2024 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import { base58btc } from 'multiformats/bases/base58'; + +import { addMulticodecPrefix } from '../../utils/formatUtils'; +import { getCompressedPublicKey } from '../../utils/keyPair'; + +export async function getDidKeyIdentifier(publicKey: string): Promise { + const compressedKey = getCompressedPublicKey(publicKey); + + return Buffer.from( + base58btc.encode( + addMulticodecPrefix('secp256k1-pub', Buffer.from(compressedKey, 'hex')), + ), + ).toString(); +} diff --git a/packages/hedera-identify-snap/packages/snap/src/hedera/config.ts b/packages/hedera-identify-snap/packages/snap/src/hedera/config.ts index 8ac0b29d..62508a08 100644 --- a/packages/hedera-identify-snap/packages/snap/src/hedera/config.ts +++ b/packages/hedera-identify-snap/packages/snap/src/hedera/config.ts @@ -26,11 +26,35 @@ const hederaChainIDs: Record = { '0x129': 'previewnet', }; +const otherChainIDs: Record = { + '0x1': 'Ethereum Mainnet', + '0xa': 'Optimisim', + '0xe': 'Flare', + '0x13': 'Songbird', + '0x14': 'Elastos', + '0x1e': 'RSK', + '0x32': 'XDC', + '0x38': 'Binance Smart Chain', + '0x89': 'Polygon', + '0x13a': 'Filecoin', + '0x44d': 'Polygon ZKEVM', + '0x8ae': 'Kava', + '0x2105': 'Base', + '0xa4b1': 'Arbitrum', + '0xa86a': 'Avalanche', + '0xe71c': 'Linea', +}; + export const getHederaNetwork = (chainId: string): string => { const network = hederaChainIDs[chainId]; return network || 'mainnet'; }; +export const getOtherNetwork = (chainId: string): string => { + const network = otherChainIDs[chainId]; + return network || `Unknown Network (Chain ID: ${chainId})`; +}; + export const validHederaChainID = (x: string) => { return isIn(Object.keys(hederaChainIDs) as string[], x); }; diff --git a/packages/hedera-identify-snap/packages/snap/src/hedera/index.ts b/packages/hedera-identify-snap/packages/snap/src/hedera/index.ts index 866c7b7c..c5c9ff74 100644 --- a/packages/hedera-identify-snap/packages/snap/src/hedera/index.ts +++ b/packages/hedera-identify-snap/packages/snap/src/hedera/index.ts @@ -45,21 +45,32 @@ export class HederaServiceImpl implements HederaService { keyIndex: number; accountId: AccountId; }): Promise { - const client = Client.forNetwork(this.network as any); + if (options.walletHedera === null) { + return null; + } - // NOTE: important, ensure that we pre-compute the health state of all nodes - await client.pingAll(); + let client: Client; + + if (this.network === 'testnet') { + client = Client.forTestnet(); + } else if (this.network === 'previewnet') { + client = Client.forPreviewnet(); + } else { + client = Client.forMainnet(); + } + + client.setNetworkUpdatePeriod(2000); const transactionSigner = await options.walletHedera.getTransactionSigner( options.keyIndex, ); + const privateKey = await options.walletHedera.getPrivateKey( options.keyIndex, ); const publicKey = await options.walletHedera.getPublicKey(options.keyIndex); if (publicKey === null) { - console.error('Public key is null'); return null; } @@ -87,11 +98,6 @@ export class HederaServiceImpl implements HederaService { const accountInfoUrl = `https://${network}.mirrornode.hedera.com/api/v1/accounts?account.publickey=${publicKey}&limit=1&order=asc`; const accountInfoResult = await mirrorNodeQuery(accountInfoUrl); - console.log( - 'getAccountFromPublicKey - result: ', - JSON.stringify(accountInfoResult, null, 4), - ); - if ( !( accountInfoResult.accounts && @@ -145,57 +151,60 @@ export class HederaServiceImpl implements HederaService { async getAccountFromEvmAddres( evmAddress: string, ): Promise { - // Returns all account information for the given evmAddress - const network = - this.network === 'mainnet' ? 'mainnet-public' : this.network; - const accountInfoUrl = `https://${network}.mirrornode.hedera.com/api/v1/accounts/${evmAddress}?limit=1&order=asc`; - const result = await mirrorNodeQuery(accountInfoUrl); + try { + // Returns all account information for the given evmAddress + const network = + this.network === 'mainnet' ? 'mainnet-public' : this.network; + const accountInfoUrl = `https://${network}.mirrornode.hedera.com/api/v1/accounts/${evmAddress}?limit=1&order=asc`; + const result = await mirrorNodeQuery(accountInfoUrl); - console.log( - 'getAccountFromEvmAddres - result: ', - JSON.stringify(result, null, 4), - ); + if (result === null || _.isEmpty(result) || !result.account) { + console.log( + `Could not retrieve info about this evm address from hedera mirror node for some reason. Please try again later`, + ); + return null; + } - if (result === null || _.isEmpty(result) || !result.account) { + const createdDate = new Date( + (result.created_timestamp.split('.')[0] as number) * 1000, + ).toLocaleString(undefined, { + year: 'numeric', + month: '2-digit', + day: '2-digit', + weekday: 'long', + hour: '2-digit', + hour12: false, + minute: '2-digit', + second: '2-digit', + }); + const expiryDate = new Date( + (result.expiry_timestamp.split('.')[0] as number) * 1000, + ).toLocaleString(undefined, { + year: 'numeric', + month: '2-digit', + day: '2-digit', + weekday: 'long', + hour: '2-digit', + hour12: false, + minute: '2-digit', + second: '2-digit', + }); + return { + account: result.account, + evmAddress: result.evm_address, + alias: result.alias, + balance: result.balance.balance / 100000000.0, + createdDate, + expiryDate, + memo: result.memo, + } as HederaMirrorInfo; + } catch (error) { console.log( - `Could not retrieve info about this evm address from hedera mirror node for some reason. Please try again later`, + 'Error while retrieving account info using evm address from the mirror node. Error: ', + error, ); return null; } - - const createdDate = new Date( - (result.created_timestamp.split('.')[0] as number) * 1000, - ).toLocaleString(undefined, { - year: 'numeric', - month: '2-digit', - day: '2-digit', - weekday: 'long', - hour: '2-digit', - hour12: false, - minute: '2-digit', - second: '2-digit', - }); - const expiryDate = new Date( - (result.expiry_timestamp.split('.')[0] as number) * 1000, - ).toLocaleString(undefined, { - year: 'numeric', - month: '2-digit', - day: '2-digit', - weekday: 'long', - hour: '2-digit', - hour12: false, - minute: '2-digit', - second: '2-digit', - }); - return { - account: result.account, - evmAddress: result.evm_address, - alias: result.alias, - balance: result.balance.balance / 100000000.0, - createdDate, - expiryDate, - memo: result.memo, - } as HederaMirrorInfo; } } @@ -212,40 +221,29 @@ export async function testClientOperatorMatch(client: Client) { try { await tx.execute(client); - } catch (err) { - if (err instanceof StatusError) { - if ( - err.status === Status.InsufficientTxFee || - err.status === Status.InsufficientPayerBalance - ) { - // If the transaction fails with Insufficient Tx Fee, this means - // that the account ID verification succeeded before this point - // Same for Insufficient Payer Balance - return true; - } - return false; + } catch (error: any) { + console.log('error: ', JSON.stringify(error, null, 4)); + if (error instanceof StatusError) { + // If the transaction fails with Insufficient Tx Fee, this means + // that the account ID verification succeeded before this point + // Same for Insufficient Payer Balance + return ( + error.status === Status.InsufficientTxFee || + error.status === Status.InsufficientPayerBalance + ); } - console.error( - `Error while validating private key and account id: ${JSON.stringify( - err, - null, - 4, - )}`, - ); - throw new Error( - `Error while validating private key and account id: ${JSON.stringify( - err, - null, - 4, - )}`, - ); + const errMessage = + 'The account id does not belong to the associated private key'; + console.log(errMessage, String(error)); + throw new Error(errMessage); } // under *no* cirumstances should this transaction succeed - throw new Error( - 'unexpected success of intentionally-erroneous transaction to confirm account ID', - ); + const errMessage = + 'Unexpected success of intentionally-erroneous transaction to confirm account ID'; + console.log(errMessage); + throw new Error(errMessage); } /** diff --git a/packages/hedera-identify-snap/packages/snap/src/index.tsx b/packages/hedera-identify-snap/packages/snap/src/index.tsx index 35bdb931..795a7525 100644 --- a/packages/hedera-identify-snap/packages/snap/src/index.tsx +++ b/packages/hedera-identify-snap/packages/snap/src/index.tsx @@ -18,8 +18,9 @@ * */ -import { OnRpcRequestHandler } from '@metamask/snaps-types'; -import { heading, text } from '@metamask/snaps-ui'; +import { rpcErrors } from '@metamask/rpc-errors'; +import { OnRpcRequestHandler } from '@metamask/snaps-sdk'; +import { HelloUI } from './components/hello'; import { Account, ExternalAccount, IdentitySnapParams } from './interfaces'; import { getAccountInfo } from './rpc/account/getAccountInfo'; import { getAvailableDIDMethods } from './rpc/did/getAvailableDIDMethods'; @@ -27,7 +28,6 @@ import { getCurrentDIDMethod } from './rpc/did/getCurrentDIDMethod'; import { resolveDID } from './rpc/did/resolveDID'; import { switchDIDMethod } from './rpc/did/switchDIDMethod'; import { configureGoogleAccount } from './rpc/gdrive/configureGoogleAccount'; -import { createNewHederaAccount } from './rpc/hedera/createNewHederaAccount'; import { togglePopups } from './rpc/snap/togglePopups'; import { createVC } from './rpc/vc/createVC'; import { createVP } from './rpc/vc/createVP'; @@ -40,14 +40,12 @@ import { syncGoogleVCs } from './rpc/vc/syncGoogleVCs'; import { verifyVC } from './rpc/vc/verifyVC'; import { verifyVP } from './rpc/vc/verifyVP'; import { getCurrentAccount } from './snap/account'; -import { generateCommonPanel } from './snap/dialog'; -import { getSnapStateUnchecked } from './snap/state'; -import { CreateNewHederaAccountRequestParams } from './types/params'; +import { getCurrentNetwork } from './snap/network'; +import { getStateUnchecked } from './snap/state'; import { init } from './utils/init'; import { isExternalAccountFlagSet, isValidConfigueGoogleRequest, - isValidCreateNewHederaAccountParams, isValidCreateVCRequest, isValidCreateVPRequest, isValidDeleteAllVCsRequest, @@ -77,17 +75,44 @@ export const onRpcRequest: OnRpcRequestHandler = async ({ console.log('Request:', JSON.stringify(request, null, 4)); console.log('Origin:', origin); console.log('-------------------------------------------------------------'); - console.log( - 'request.params=========', - JSON.stringify(request.params, null, 4), - ); - let state = await getSnapStateUnchecked(snap); + const network = await getCurrentNetwork(); + + let state = await getStateUnchecked(); if (state === null) { - state = await init(snap); + state = await init(origin, network); } console.log('state:', JSON.stringify(state, null, 4)); + const identitySnapParams: IdentitySnapParams = { + origin, + network, + state, + account: {} as Account, + }; + + switch (request.method) { + case 'hello': { + return await snap.request({ + method: 'snap_dialog', + params: { + type: 'alert', + content: , + }, + }); + } + case 'togglePopups': { + return await togglePopups(identitySnapParams); + } + case 'switchDIDMethod': { + isValidSwitchMethodRequest(request.params); + return await switchDIDMethod( + identitySnapParams, + request.params.didMethod, + ); + } + } + let isExternalAccount: boolean; let extraData: unknown; if (isExternalAccountFlagSet(request.params)) { @@ -99,58 +124,22 @@ export const onRpcRequest: OnRpcRequestHandler = async ({ } const account: Account = await getCurrentAccount( + origin, + network, state, request.params, isExternalAccount, ); account.extraData = extraData; - console.log(`Current account: ${JSON.stringify(account, null, 4)}`); + identitySnapParams.account = account; - const identitySnapParams: IdentitySnapParams = { - origin, - snap, - state, - metamask: ethereum, - account, - }; + const accountInfoPublic = await getAccountInfo(identitySnapParams); switch (request.method) { - case 'hello': { - return snap.request({ - method: 'snap_dialog', - params: { - /* - Type can be one of the following: - - 'alert': for displaying information. - - 'confirmation': for accepting or rejecting some action. - - 'prompt': for inputting some information. - */ - type: 'alert', - content: await generateCommonPanel(origin, [ - heading('Hello from Identify Snap!'), - text('This custom alert is just for display purposes.'), - ]), - }, - }); - } - - case 'togglePopups': { - return await togglePopups(identitySnapParams); - } - case 'getAccountInfo': { - return await getAccountInfo(identitySnapParams); + return accountInfoPublic; } - - case 'createNewHederaAccount': { - isValidCreateNewHederaAccountParams(request.params); - return await createNewHederaAccount( - identitySnapParams, - request.params as CreateNewHederaAccountRequestParams, - ); - } - case 'resolveDID': { isValidResolveDIDRequest(request.params); return await resolveDID(identitySnapParams, request.params.did); @@ -210,14 +199,6 @@ export const onRpcRequest: OnRpcRequestHandler = async ({ return getCurrentDIDMethod(identitySnapParams); } - case 'switchDIDMethod': { - isValidSwitchMethodRequest(request.params); - return await switchDIDMethod( - identitySnapParams, - request.params.didMethod, - ); - } - case 'getSupportedProofFormats': { return getSupportedProofFormats(); } @@ -231,9 +212,8 @@ export const onRpcRequest: OnRpcRequestHandler = async ({ return await syncGoogleVCs(identitySnapParams); } - default: { - console.error('Method not found'); - throw new Error('Method not found'); - } + default: + // Throw a known error to avoid crashing the Snap + throw rpcErrors.methodNotFound(request.method); } }; diff --git a/packages/hedera-identify-snap/packages/snap/src/interfaces.ts b/packages/hedera-identify-snap/packages/snap/src/interfaces.ts index b93e881b..49016f81 100644 --- a/packages/hedera-identify-snap/packages/snap/src/interfaces.ts +++ b/packages/hedera-identify-snap/packages/snap/src/interfaces.ts @@ -18,26 +18,25 @@ * */ -import { MetaMaskInpageProvider } from '@metamask/providers'; -import { SnapsGlobalObject } from '@metamask/snaps-types'; -import { Panel } from '@metamask/snaps-ui'; import { IIdentifier, IKey, W3CVerifiableCredential } from '@veramo/core'; import { ManagedPrivateKey } from '@veramo/key-manager'; export type Account = { - evmAddress: string; - addrToUseForDid: string; + metamaskAddress: string; + snapAddress: string; method: string; identifier: IIdentifier; privateKey: string; + publicKey: string; extraData?: unknown; }; export type PublicAccountInfo = { - evmAddress: string; + metamaskAddress: string; + snapAddress: string; did: string; method: string; - extraData?: unknown; + accountID: string; }; export type IdentitySnapState = { @@ -60,6 +59,7 @@ export type IdentitySnapConfig = { acceptedTerms: boolean; }; dApp: { + didMethod: string; disablePopups: boolean; friendlyDapps: string[]; }; @@ -86,7 +86,6 @@ export type GoogleUserInfo = { export type IdentityAccountConfig = { identity: { - didMethod: string; vcStore: string; googleUserInfo: GoogleUserInfo; }; @@ -94,18 +93,11 @@ export type IdentityAccountConfig = { export type IdentitySnapParams = { origin: string; - snap: SnapsGlobalObject; + network: string; state: IdentitySnapState; - metamask: MetaMaskInpageProvider; account: Account; }; -export type SnapDialogParams = { - type: 'alert' | 'confirmation' | 'prompt'; - content: Panel; - placeholder?: string; -}; - export type UploadData = { fileName: string; content: string; diff --git a/packages/hedera-identify-snap/packages/snap/src/plugins/veramo/google-drive-data-store/src/googleDriveVCStore.ts b/packages/hedera-identify-snap/packages/snap/src/plugins/veramo/google-drive-data-store/src/googleDriveVCStore.ts index 20e80dc3..8a253c27 100644 --- a/packages/hedera-identify-snap/packages/snap/src/plugins/veramo/google-drive-data-store/src/googleDriveVCStore.ts +++ b/packages/hedera-identify-snap/packages/snap/src/plugins/veramo/google-drive-data-store/src/googleDriveVCStore.ts @@ -18,11 +18,11 @@ * */ -import { SnapsGlobalObject } from '@metamask/snaps-types'; import { VerifiableCredential } from '@veramo/core'; +import { sha256 } from 'js-sha256'; import jsonpath from 'jsonpath'; -import { IdentitySnapState } from 'src/interfaces'; -import { v4 as uuidv4 } from 'uuid'; +import { getDidKeyIdentifier } from '../../../../did/key/keyDidUtils'; +import { IdentitySnapState } from '../../../../interfaces'; import { AbstractDataStore, IConfigureArgs, @@ -45,17 +45,12 @@ import { decodeJWT } from './jwt'; * This is usable by {@link @vc-manager/VCManager} to hold the vc data */ export class GoogleDriveVCStore extends AbstractDataStore { - snap: SnapsGlobalObject; - state: IdentitySnapState; - accessToken: string; - email: string; - constructor(snap: SnapsGlobalObject, state: IdentitySnapState) { + constructor(state: IdentitySnapState) { super(); - this.snap = snap; this.state = state; this.accessToken = ''; this.email = ''; @@ -63,9 +58,12 @@ export class GoogleDriveVCStore extends AbstractDataStore { async queryVC(args: IFilterArgs): Promise { const { filter } = args; - const account = this.state.currentAccount.evmAddress; + const account = this.state.currentAccount.metamaskAddress; + if (!account) { - throw Error(`SnapVCStore - Cannot get current account: ${account}`); + throw Error( + `GoogleDriveVCStore - Cannot get current account: ${account}`, + ); } const googleVCs = await getGoogleVCs( @@ -78,102 +76,60 @@ export class GoogleDriveVCStore extends AbstractDataStore { return []; } + const currentMethod = this.state.currentAccount.method; + + // Helper function to decode VC if it's in JWT format + const decodeVC = (k: string) => { + let vc = googleVCs[k] as unknown; + if (typeof vc === 'string') { + vc = decodeJWT(vc); + } + return { metadata: { id: k }, data: vc }; + }; + + // Helper function to filter VCs by the current DID method + const filterByMethod = (vc: any) => { + const vcId = vc.data.credentialSubject.id || ''; + return vcId.startsWith(currentMethod); // Ensure VC matches the current DID method + }; + + const filteredVCs = Object.keys(googleVCs) + .map(decodeVC) + .filter(filterByMethod); // Filter VCs by method + if (filter && filter.type === 'id') { - return Object.keys(googleVCs) - .map((k) => { - let vc = googleVCs[k] as unknown; - if (typeof vc === 'string') { - vc = decodeJWT(vc); - } - - return { - metadata: { id: k }, - data: vc, - }; - }) - .filter((item: any) => { - return ( - item.metadata.id === (filter.filter as string) && - item.data.credentialSubject.id?.split(':')[4] === - this.state.currentAccount.addrToUseForDid - ); - }); + return filteredVCs.filter((item) => item.metadata.id === filter.filter); } if (filter && filter.type === 'vcType') { - return Object.keys(googleVCs) - .map((k) => { - let vc = googleVCs[k] as unknown; - if (typeof vc === 'string') { - vc = decodeJWT(vc); - } - - return { - metadata: { id: k }, - data: vc, - }; - }) - .filter((item: any) => { - return ( - item.data.type?.includes(filter.filter as string) && - item.data.credentialSubject.id?.split(':')[4] === - this.state.currentAccount.addrToUseForDid - ); - }); + return filteredVCs.filter((item) => + (item.data as VerifiableCredential).type?.includes(filter.filter), + ); } - if (filter === undefined || (filter && filter.type === 'none')) { - return Object.keys(googleVCs) - .map((k) => { - let vc = googleVCs[k] as unknown; - if (typeof vc === 'string') { - vc = decodeJWT(vc); - } - return { - metadata: { id: k }, - data: vc, - }; - }) - .filter((item: any) => { - return ( - item.data.credentialSubject.id?.split(':')[4] === - this.state.currentAccount.addrToUseForDid - ); - }); + if (!filter || filter.type === 'none') { + return filteredVCs; } if (filter && filter.type === 'JSONPath') { - const objects = Object.keys(googleVCs) - .map((k) => { - let vc = googleVCs[k] as unknown; - if (typeof vc === 'string') { - vc = decodeJWT(vc); - } - return { - metadata: { id: k }, - data: vc, - }; - }) - .filter((item: any) => { - return ( - item.data.credentialSubject.id?.split(':')[4] === - this.state.currentAccount.addrToUseForDid - ); - }); - const filteredObjects = jsonpath.query(objects, filter.filter as string); + const filteredObjects = jsonpath.query( + filteredVCs, + filter.filter as string, + ); return filteredObjects as IQueryResult[]; } + return []; } - async saveVC(args: { - data: ISaveVC[]; - options?: unknown; - }): Promise { + async saveVC(args: { data: ISaveVC[] }): Promise { const { data: vcs } = args; - const account = this.state.currentAccount.evmAddress; + const account = this.state.currentAccount.metamaskAddress; + if (!account) { - throw Error(`SnapVCStore - Cannot get current account: ${account}`); + throw Error( + `GoogleDriveVCStore - Cannot get current account: ${account}`, + ); } let googleVCs = await getGoogleVCs( @@ -187,14 +143,24 @@ export class GoogleDriveVCStore extends AbstractDataStore { } const ids: string[] = []; - let newVCs = { ...googleVCs }; + const newVCs = { ...googleVCs }; + const currentMethod = this.state.currentAccount.method; + for (const vc of vcs) { + let identifier = this.state.currentAccount.snapAddress; + if (currentMethod === 'did:key') { + identifier = await getDidKeyIdentifier( + this.state.currentAccount.publicKey, + ); + } + + const vcId = (vc.vc as VerifiableCredential).credentialSubject.id || ''; if ( - (vc.vc as VerifiableCredential).credentialSubject.id?.split(':')[4] === - this.state.currentAccount.addrToUseForDid + vcId.startsWith(currentMethod) && + vcId.split(':').pop() === identifier ) { - const newId = vc.id || uuidv4(); - newVCs = { ...newVCs, [newId]: vc.vc }; + const newId = vc.id || sha256(JSON.stringify(vc)); + newVCs[newId] = vc.vc; ids.push(newId); } } @@ -208,9 +174,12 @@ export class GoogleDriveVCStore extends AbstractDataStore { } async deleteVC({ id }: { id: string }): Promise { - const account = this.state.currentAccount.evmAddress; + const account = this.state.currentAccount.metamaskAddress; + if (!account) { - throw Error(`SnapVCStore - Cannot get current account: ${account}`); + throw Error( + `GoogleDriveVCStore - Cannot get current account: ${account}`, + ); } const googleVCs = await getGoogleVCs( @@ -218,41 +187,47 @@ export class GoogleDriveVCStore extends AbstractDataStore { GOOGLE_DRIVE_VCS_FILE_NAME, ); - if (!googleVCs) { - console.log('Invalid vcs file'); + if (!googleVCs || !googleVCs[id]) { + console.log(`VC ID '${id}' not found`); return false; } - if (!googleVCs[id]) { - console.log(`VC ID '${id}' not found`); - throw Error(`VC ID '${id}' not found`); + const currentMethod = this.state.currentAccount.method; + let identifier = this.state.currentAccount.snapAddress; + if (currentMethod === 'did:key') { + identifier = await getDidKeyIdentifier( + this.state.currentAccount.publicKey, + ); } + const vcId = + (googleVCs[id] as VerifiableCredential).credentialSubject.id || ''; if ( - (googleVCs[id] as VerifiableCredential).credentialSubject.id?.split( - ':', - )[4] !== account + !vcId.startsWith(currentMethod) || + vcId.split(':').pop() !== identifier ) { console.log( - `VC ID '${id}' does not belong to the currently connected Metamask account. Skipping...`, + `GoogleDriveVCStore - VC ID '${id}' does not match the current account.`, ); return false; } delete googleVCs[id]; - const gdriveResponse = await uploadToGoogleDrive(this.accessToken, { + await uploadToGoogleDrive(this.accessToken, { fileName: GOOGLE_DRIVE_VCS_FILE_NAME, content: JSON.stringify(googleVCs), }); - console.log({ gdriveResponse }); return true; } public async clearVCs(_args: IFilterArgs): Promise { - const account = this.state.currentAccount.evmAddress; + const account = this.state.currentAccount.metamaskAddress; + if (!account) { - throw Error(`SnapVCStore - Cannot get current account: ${account}`); + throw Error( + `GoogleDriveVCStore - Cannot get current account: ${account}`, + ); } const googleVCs = await getGoogleVCs( @@ -262,27 +237,25 @@ export class GoogleDriveVCStore extends AbstractDataStore { if (!googleVCs) { await createEmptyFile(this.accessToken, GOOGLE_DRIVE_VCS_FILE_NAME); - console.log( - 'Google drive does not have any VCs associated with the currently connected Metamask account. Skipping...', - ); + console.log('No VCs to clear.'); return false; } - const newVCs: any = {}; - Object.entries(googleVCs).forEach(([vcId, vc]) => { - if ( - (vc as VerifiableCredential).credentialSubject.id?.split(':')[4] !== - account - ) { - newVCs[vcId] = vc; - } - }); + const currentMethod = this.state.currentAccount.method; // 'did:key' or 'did:pkh' - const gdriveResponse = await uploadToGoogleDrive(this.accessToken, { + // Use Object.fromEntries to filter VCs like in SnapVCStore + const filteredVCs = Object.fromEntries( + Object.entries(googleVCs).filter(([_, vc]) => { + const vcSubjectId = + (vc as VerifiableCredential).credentialSubject.id || ''; + return !vcSubjectId.startsWith(currentMethod); // Keep only VCs not matching the current method + }), + ); + + await uploadToGoogleDrive(this.accessToken, { fileName: GOOGLE_DRIVE_VCS_FILE_NAME, - content: JSON.stringify(newVCs), + content: JSON.stringify(filteredVCs), }); - console.log({ gdriveResponse }); return true; } @@ -292,10 +265,9 @@ export class GoogleDriveVCStore extends AbstractDataStore { const email = await verifyToken(accessToken); this.accessToken = accessToken; this.email = email; - return true; } catch (error) { - console.error('Could not configure google account', error); + console.error('Could not configure Google account', error); throw error; } } diff --git a/packages/hedera-identify-snap/packages/snap/src/plugins/veramo/snap-data-store/src/snapDataStore.ts b/packages/hedera-identify-snap/packages/snap/src/plugins/veramo/snap-data-store/src/snapDataStore.ts index 2ad9d30d..50d46aa4 100644 --- a/packages/hedera-identify-snap/packages/snap/src/plugins/veramo/snap-data-store/src/snapDataStore.ts +++ b/packages/hedera-identify-snap/packages/snap/src/plugins/veramo/snap-data-store/src/snapDataStore.ts @@ -18,7 +18,6 @@ * */ -import { SnapsGlobalObject } from '@metamask/snaps-types'; import { IIdentifier, IKey, @@ -32,13 +31,15 @@ import { ImportablePrivateKey, ManagedPrivateKey, } from '@veramo/key-manager'; +import { sha256 } from 'js-sha256'; import jsonpath from 'jsonpath'; import { v4 as uuidv4 } from 'uuid'; +import { getDidKeyIdentifier } from '../../../../did/key/keyDidUtils'; import { IdentitySnapState } from '../../../../interfaces'; import { getAccountStateByCoinType, getCurrentCoinType, - updateSnapState, + updateState, } from '../../../../snap/state'; import { decodeJWT } from '../../../../utils/jwt'; import { @@ -54,18 +55,15 @@ import { * This is usable by {@link @veramo/kms-local} to hold the key data. */ export class SnapKeyStore extends AbstractKeyStore { - snap: SnapsGlobalObject; - state: IdentitySnapState; - constructor(snap: SnapsGlobalObject, state: IdentitySnapState) { + constructor(state: IdentitySnapState) { super(); - this.snap = snap; this.state = state; } async getKey({ kid }: { kid: string }): Promise { - const account = this.state.currentAccount.evmAddress; + const account = this.state.currentAccount.metamaskAddress; if (!account) { throw Error(`SnapKeyStore - Cannot get current account: ${account}`); } @@ -79,7 +77,7 @@ export class SnapKeyStore extends AbstractKeyStore { } async deleteKey({ kid }: { kid: string }) { - const account = this.state.currentAccount.evmAddress; + const account = this.state.currentAccount.metamaskAddress; if (!account) { throw Error(`SnapKeyStore - Cannot get current account: ${account}`); } @@ -91,12 +89,12 @@ export class SnapKeyStore extends AbstractKeyStore { const coinType = await getCurrentCoinType(); delete this.state.accountState[coinType][account].snapKeyStore[kid]; - await updateSnapState(this.snap, this.state); + await updateState(this.state); return true; } async importKey(args: IKey) { - const account = this.state.currentAccount.evmAddress; + const account = this.state.currentAccount.metamaskAddress; if (!account) { throw Error(`SnapKeyStore - Cannot get current account: ${account}`); } @@ -105,12 +103,12 @@ export class SnapKeyStore extends AbstractKeyStore { this.state.accountState[coinType][account].snapKeyStore[args.kid] = { ...args, }; - await updateSnapState(this.snap, this.state); + await updateState(this.state); return true; } async listKeys(): Promise[]> { - const account = this.state.currentAccount.evmAddress; + const account = this.state.currentAccount.metamaskAddress; if (!account) { throw Error(`SnapKeyStore - Cannot get current account: ${account}`); } @@ -130,18 +128,15 @@ export class SnapKeyStore extends AbstractKeyStore { * This is usable by {@link @veramo/kms-local} to hold the key data. */ export class SnapPrivateKeyStore extends AbstractPrivateKeyStore { - snap: SnapsGlobalObject; - state: IdentitySnapState; - constructor(snap: SnapsGlobalObject, state: IdentitySnapState) { + constructor(state: IdentitySnapState) { super(); - this.snap = snap; this.state = state; } async getKey({ alias }: { alias: string }): Promise { - const account = this.state.currentAccount.evmAddress; + const account = this.state.currentAccount.metamaskAddress; if (!account) { throw Error( `SnapPrivateKeyStore - Cannot get current account: ${account}`, @@ -159,7 +154,7 @@ export class SnapPrivateKeyStore extends AbstractPrivateKeyStore { } async deleteKey({ alias }: { alias: string }) { - const account = this.state.currentAccount.evmAddress; + const account = this.state.currentAccount.metamaskAddress; if (!account) { throw Error( `SnapPrivateKeyStore - Cannot get current account: ${account}`, @@ -175,12 +170,12 @@ export class SnapPrivateKeyStore extends AbstractPrivateKeyStore { delete this.state.accountState[coinType][account].snapPrivateKeyStore[ alias ]; - await updateSnapState(this.snap, this.state); + await updateState(this.state); return true; } async importKey(args: ImportablePrivateKey) { - const account = this.state.currentAccount.evmAddress; + const account = this.state.currentAccount.metamaskAddress; if (!account) { throw Error( `SnapPrivateKeyStore - Cannot get current account: ${account}`, @@ -204,14 +199,14 @@ export class SnapPrivateKeyStore extends AbstractPrivateKeyStore { ...args, alias, }; - await updateSnapState(this.snap, this.state); + await updateState(this.state); return this.state.accountState[coinType][account].snapPrivateKeyStore[ alias ]; } async listKeys(): Promise { - const account = this.state.currentAccount.evmAddress; + const account = this.state.currentAccount.metamaskAddress; if (!account) { throw Error( `SnapPrivateKeyStore - Cannot get current account: ${account}`, @@ -229,13 +224,10 @@ export class SnapPrivateKeyStore extends AbstractPrivateKeyStore { * This is usable by {@link @veramo/did-manager} to hold the did key data. */ export class SnapDIDStore extends AbstractDIDStore { - snap: SnapsGlobalObject; - state: IdentitySnapState; - constructor(snap: SnapsGlobalObject, state: IdentitySnapState) { + constructor(state: IdentitySnapState) { super(); - this.snap = snap; this.state = state; } @@ -248,7 +240,7 @@ export class SnapDIDStore extends AbstractDIDStore { alias: string; provider: string; }): Promise { - const account = this.state.currentAccount.evmAddress; + const account = this.state.currentAccount.metamaskAddress; if (!account) { throw Error(`SnapDIDStore - Cannot get current account: ${account}`); } @@ -284,7 +276,7 @@ export class SnapDIDStore extends AbstractDIDStore { } async deleteDID({ did }: { did: string }) { - const account = this.state.currentAccount.evmAddress; + const account = this.state.currentAccount.metamaskAddress; if (!account) { throw Error(`SnapDIDStore - Cannot get current account: ${account}`); } @@ -298,12 +290,12 @@ export class SnapDIDStore extends AbstractDIDStore { const coinType = await getCurrentCoinType(); delete this.state.accountState[coinType][account].identifiers[did]; - await updateSnapState(this.snap, this.state); + await updateState(this.state); return true; } async importDID(args: IIdentifier) { - const account = this.state.currentAccount.evmAddress; + const account = this.state.currentAccount.metamaskAddress; if (!account) { throw Error(`SnapDIDStore - Cannot get current account: ${account}`); } @@ -319,7 +311,7 @@ export class SnapDIDStore extends AbstractDIDStore { console.log('account: ', account, ' did: ', args.did); this.state.accountState[coinType][account].identifiers[args.did] = identifier; - await updateSnapState(this.snap, this.state); + await updateState(this.state); return true; } @@ -327,7 +319,7 @@ export class SnapDIDStore extends AbstractDIDStore { alias?: string; provider?: string; }): Promise { - const account = this.state.currentAccount.evmAddress; + const account = this.state.currentAccount.metamaskAddress; if (!account) { throw Error(`SnapDIDStore - Cannot get current account: ${account}`); } @@ -358,165 +350,170 @@ export class SnapDIDStore extends AbstractDIDStore { * This is usable by {@link @vc-manager/VCManager} to hold the vc data */ export class SnapVCStore extends AbstractDataStore { - snap: SnapsGlobalObject; - state: IdentitySnapState; configure: undefined; - constructor(snap: SnapsGlobalObject, state: IdentitySnapState) { + constructor(state: IdentitySnapState) { super(); - this.snap = snap; this.state = state; } async queryVC(args: IFilterArgs): Promise { const { filter } = args; - const account = this.state.currentAccount.evmAddress; + const account = this.state.currentAccount.metamaskAddress; if (!account) { throw Error(`SnapVCStore - Cannot get current account: ${account}`); } const accountState = await getAccountStateByCoinType(this.state, account); + const currentMethod = this.state.currentAccount.method; + + // Helper function to decode VC if it's in JWT format + const decodeVC = (k: string) => { + let vc = accountState.vcs[k] as unknown; + if (typeof vc === 'string') { + vc = decodeJWT(vc); + } + return { metadata: { id: k }, data: vc }; + }; + + // Helper function to filter VCs by the current DID method + const filterByMethod = (vc: any) => { + const vcId = vc.data.credentialSubject.id || ''; + return vcId.startsWith(currentMethod); // Only return if VC matches the current method (e.g., 'did:key') + }; + + // Step 1: Decode all VCs and filter them by method upfront + const filteredVCs = Object.keys(accountState.vcs) + .map(decodeVC) + .filter(filterByMethod); // Only VCs matching the current DID method are kept + + // Step 2: Apply additional filters based on the `args.filter` if (filter && filter.type === 'id') { - return Object.keys(accountState.vcs) - .map((k) => { - let vc = accountState.vcs[k] as unknown; - if (typeof vc === 'string') { - vc = decodeJWT(vc); - } - return { - metadata: { id: k }, - data: vc, - }; - }) - .filter((item: any) => { - return ( - item.metadata.id === (filter.filter as string) && - item.data.credentialSubject.id?.split(':')[4] === - this.state.currentAccount.addrToUseForDid - ); - }); + return filteredVCs.filter((item) => item.metadata.id === filter.filter); } if (filter && filter.type === 'vcType') { - return Object.keys(accountState.vcs) - .map((k) => { - let vc = accountState.vcs[k] as unknown; - if (typeof vc === 'string') { - vc = decodeJWT(vc); - } - return { - metadata: { id: k }, - data: vc, - }; - }) - .filter((item: any) => { - return ( - item.data.type?.includes(filter.filter as string) && - item.data.credentialSubject.id?.split(':')[4] === - this.state.currentAccount.addrToUseForDid - ); - }); + return filteredVCs.filter((item) => + (item.data as VerifiableCredential).type?.includes(filter.filter), + ); } if (filter === undefined || (filter && filter.type === 'none')) { - return Object.keys(accountState.vcs) - .map((k) => { - let vc = accountState.vcs[k] as unknown; - if (typeof vc === 'string') { - vc = decodeJWT(vc); - } - return { - metadata: { id: k }, - data: vc, - }; - }) - .filter((item: any) => { - return ( - item.data.credentialSubject.id?.split(':')[4] === - this.state.currentAccount.addrToUseForDid - ); - }); + return filteredVCs; } if (filter && filter.type === 'JSONPath') { - const objects = Object.keys(accountState.vcs) - .map((k) => { - let vc = accountState.vcs[k] as unknown; - if (typeof vc === 'string') { - vc = decodeJWT(vc); - } - return { - metadata: { id: k }, - data: vc, - }; - }) - .filter((item: any) => { - return ( - item.data.credentialSubject.id?.split(':')[4] === - this.state.currentAccount.addrToUseForDid - ); - }); - const filteredObjects = jsonpath.query(objects, filter.filter as string); + const filteredObjects = jsonpath.query( + filteredVCs, + filter.filter as string, + ); return filteredObjects as IQueryResult[]; } + return []; } async saveVC(args: { data: ISaveVC[] }): Promise { const { data: vcs } = args; + const account = this.state.currentAccount.metamaskAddress; - const account = this.state.currentAccount.evmAddress; if (!account) { throw Error(`SnapVCStore - Cannot get current account: ${account}`); } const coinType = await getCurrentCoinType(); + const currentMethod = this.state.currentAccount.method; // 'did:key' or 'did:pkh' const ids: string[] = []; + for (const vc of vcs) { + let identifier = this.state.currentAccount.snapAddress; + if (currentMethod === 'did:key') { + identifier = await getDidKeyIdentifier( + this.state.currentAccount.publicKey, + ); + } + + // Save only if the VC matches the current DID method + const vcId = (vc.vc as VerifiableCredential).credentialSubject.id || ''; if ( - (vc.vc as VerifiableCredential).credentialSubject.id?.split(':')[4] === - this.state.currentAccount.addrToUseForDid + vcId.startsWith(currentMethod) && + vcId.split(':').pop() === identifier ) { - const newId = vc.id || uuidv4(); + const newId = vc.id || sha256(JSON.stringify(vc)); ids.push(newId); this.state.accountState[coinType][account].vcs[newId] = vc.vc as W3CVerifiableCredential; } } - await updateSnapState(this.snap, this.state); + await updateState(this.state); return ids; } async deleteVC({ id }: { id: string }): Promise { - const account = this.state.currentAccount.evmAddress; + const account = this.state.currentAccount.metamaskAddress; + if (!account) { throw Error(`SnapVCStore - Cannot get current account: ${account}`); } const accountState = await getAccountStateByCoinType(this.state, account); - if (!accountState.vcs[id]) { - throw Error(`SnapVCStore - VC ID '${id}' not found`); + const coinType = await getCurrentCoinType(); + + // Ensure VC exists and matches the current DID method + const currentMethod = this.state.currentAccount.method; + let identifier = this.state.currentAccount.snapAddress; + if (currentMethod === 'did:key') { + identifier = await getDidKeyIdentifier( + this.state.currentAccount.publicKey, + ); + } + + const vcId = + (accountState.vcs[id] as VerifiableCredential).credentialSubject.id || ''; + if ( + !vcId.startsWith(currentMethod) || + vcId.split(':').pop() !== identifier + ) { + console.log( + `SnapVCStore - VC ID '${id}' does not match the current account.`, + ); + return false; } - const coinType = await getCurrentCoinType(); delete this.state.accountState[coinType][account].vcs[id]; - await updateSnapState(this.snap, this.state); + await updateState(this.state); + return true; } public async clearVCs(_args: IFilterArgs): Promise { - const account = this.state.currentAccount.evmAddress; + const account = this.state.currentAccount.metamaskAddress; + if (!account) { throw Error(`SnapVCStore - Cannot get current account: ${account}`); } const coinType = await getCurrentCoinType(); - this.state.accountState[coinType][account].vcs = {}; - await updateSnapState(this.snap, this.state); + const currentMethod = this.state.currentAccount.method; + + // Ensure vc is correctly typed with a conditional check + const accountVCs = this.state.accountState[coinType][account].vcs; + this.state.accountState[coinType][account].vcs = Object.fromEntries( + Object.entries(accountVCs).filter(([_, vc]) => { + return ( + vc && // Check vc exists + typeof vc === 'object' && // Ensure vc is an object + 'credentialSubject' in vc && // Ensure credentialSubject exists + vc.credentialSubject?.id?.startsWith(currentMethod) === false // Filter based on DID method + ); + }), + ); + + await updateState(this.state); return true; } } diff --git a/packages/hedera-identify-snap/packages/snap/src/plugins/veramo/verifiable-creds-manager/data-store/abstractDataStore.ts b/packages/hedera-identify-snap/packages/snap/src/plugins/veramo/verifiable-creds-manager/data-store/abstractDataStore.ts index 227b5a81..93b572a5 100644 --- a/packages/hedera-identify-snap/packages/snap/src/plugins/veramo/verifiable-creds-manager/data-store/abstractDataStore.ts +++ b/packages/hedera-identify-snap/packages/snap/src/plugins/veramo/verifiable-creds-manager/data-store/abstractDataStore.ts @@ -19,24 +19,24 @@ */ export type ISaveArgs = { - data: unknown; - options?: unknown; + data: any; + options?: any; }; export type ISaveVC = { - vc: unknown; + vc: any; id?: string; }; export type IDeleteArgs = { id: string; - options?: unknown; + options?: any; }; export type IFilterArgs = { filter?: { type: string; - filter: unknown; + filter: any; }; }; @@ -45,7 +45,7 @@ export type IConfigureArgs = { }; export type IQueryResult = { - data: unknown; + data: any; metadata: { id: string; }; diff --git a/packages/hedera-identify-snap/packages/snap/src/plugins/veramo/verifiable-creds-manager/types/IDataManager.ts b/packages/hedera-identify-snap/packages/snap/src/plugins/veramo/verifiable-creds-manager/types/IDataManager.ts index c80cc32d..6cb475b9 100644 --- a/packages/hedera-identify-snap/packages/snap/src/plugins/veramo/verifiable-creds-manager/types/IDataManager.ts +++ b/packages/hedera-identify-snap/packages/snap/src/plugins/veramo/verifiable-creds-manager/types/IDataManager.ts @@ -91,7 +91,7 @@ export type IDataManagerDeleteArgs = { * Types for DataManager method return values */ export type IDataManagerQueryResult = { - data: unknown; + data: any; metadata: QueryMetadata; }; diff --git a/packages/hedera-identify-snap/packages/snap/src/rpc/account/getAccountInfo.ts b/packages/hedera-identify-snap/packages/snap/src/rpc/account/getAccountInfo.ts index 2eaefaa0..f7a35d35 100644 --- a/packages/hedera-identify-snap/packages/snap/src/rpc/account/getAccountInfo.ts +++ b/packages/hedera-identify-snap/packages/snap/src/rpc/account/getAccountInfo.ts @@ -18,14 +18,8 @@ * */ -import { validHederaChainID } from '../../hedera/config'; -import { - HederaAccountParams, - IdentitySnapParams, - PublicAccountInfo, -} from '../../interfaces'; -import { getCurrentNetwork } from '../../snap/network'; -import { getHederaAccountIfExists } from '../../utils/params'; +import { IdentitySnapParams, PublicAccountInfo } from '../../interfaces'; +import { getCurrentCoinType } from '../../snap/state'; /** * Get account info such as address, did, public key, etc. @@ -38,34 +32,15 @@ export async function getAccountInfo( ): Promise { const { state, account } = identitySnapParams; + const coinType = (await getCurrentCoinType()).toString(); + const publicAccountInfo: PublicAccountInfo = { - evmAddress: account.evmAddress, + metamaskAddress: account.metamaskAddress, + snapAddress: account.snapAddress, did: account.identifier.did, method: account.method, + accountID: state.accountState[coinType][account.metamaskAddress] + .extraData as string, }; - const chainId = await getCurrentNetwork(ethereum); - - if (validHederaChainID(chainId)) { - let accountId = ''; - if (account.extraData) { - accountId = (account.extraData as HederaAccountParams).accountId; - } - - if (!accountId) { - accountId = await getHederaAccountIfExists( - state, - undefined, - account.evmAddress, - ); - } - - if (accountId) { - publicAccountInfo.extraData = { - accountId, - } as HederaAccountParams; - } - } - - console.log(JSON.stringify(publicAccountInfo, null, 4)); return publicAccountInfo; } diff --git a/packages/hedera-identify-snap/packages/snap/src/rpc/did/getCurrentDIDMethod.ts b/packages/hedera-identify-snap/packages/snap/src/rpc/did/getCurrentDIDMethod.ts index 6ea59b42..2d6866ae 100644 --- a/packages/hedera-identify-snap/packages/snap/src/rpc/did/getCurrentDIDMethod.ts +++ b/packages/hedera-identify-snap/packages/snap/src/rpc/did/getCurrentDIDMethod.ts @@ -19,7 +19,6 @@ */ import { IdentitySnapParams } from '../../interfaces'; -import { getAccountStateByCoinType } from '../../snap/state'; /** * Function to get available methods. @@ -29,10 +28,6 @@ import { getAccountStateByCoinType } from '../../snap/state'; export async function getCurrentDIDMethod( identitySnapParams: IdentitySnapParams, ): Promise { - const { state, account } = identitySnapParams; - const accountState = await getAccountStateByCoinType( - state, - account.evmAddress, - ); - return accountState.accountConfig.identity.didMethod; + const { state } = identitySnapParams; + return state.snapConfig.dApp.didMethod; } diff --git a/packages/hedera-identify-snap/packages/snap/src/rpc/did/resolveDID.ts b/packages/hedera-identify-snap/packages/snap/src/rpc/did/resolveDID.ts index 9117333b..a4c5f3f7 100644 --- a/packages/hedera-identify-snap/packages/snap/src/rpc/did/resolveDID.ts +++ b/packages/hedera-identify-snap/packages/snap/src/rpc/did/resolveDID.ts @@ -18,9 +18,7 @@ * */ -import { DIDResolutionResult } from '@veramo/core'; import { IdentitySnapParams } from '../../interfaces'; -import { getVeramoAgent } from '../../veramo/agent'; /** * Resolve DID. @@ -31,18 +29,17 @@ import { getVeramoAgent } from '../../veramo/agent'; export async function resolveDID( identitySnapParams: IdentitySnapParams, didUrl?: string, -): Promise { - const { state, account } = identitySnapParams; - - // Get Veramo agent - const agent = await getVeramoAgent(snap, state); +): Promise { + const { account } = identitySnapParams; let did = didUrl; // GET DID if not exists if (!did) { did = account.identifier.did; } - return await agent.resolveDid({ - didUrl: did, - }); + + const response = await fetch( + `https://dev.uniresolver.io/1.0/identifiers/${did}`, + ); + return await response.json(); } diff --git a/packages/hedera-identify-snap/packages/snap/src/rpc/did/switchDIDMethod.ts b/packages/hedera-identify-snap/packages/snap/src/rpc/did/switchDIDMethod.ts index 6f185c21..bb415ba3 100644 --- a/packages/hedera-identify-snap/packages/snap/src/rpc/did/switchDIDMethod.ts +++ b/packages/hedera-identify-snap/packages/snap/src/rpc/did/switchDIDMethod.ts @@ -18,10 +18,10 @@ * */ -import { divider, heading, text } from '@metamask/snaps-ui'; -import { IdentitySnapParams, SnapDialogParams } from '../../interfaces'; +import { DialogParams, divider, heading, text } from '@metamask/snaps-sdk'; +import { IdentitySnapParams } from '../../interfaces'; +import { updateDIDMethod } from '../../snap/dapp'; import { generateCommonPanel, snapDialog } from '../../snap/dialog'; -import { getAccountStateByCoinType, updateSnapState } from '../../snap/state'; import { availableMethods, isValidMethod } from '../../types/constants'; /** @@ -34,13 +34,9 @@ export async function switchDIDMethod( identitySnapParams: IdentitySnapParams, didMethod: string, ): Promise { - const { snap, state, account } = identitySnapParams; + const { origin, network, state } = identitySnapParams; - const accountState = await getAccountStateByCoinType( - state, - account.evmAddress, - ); - const method = accountState.accountConfig.identity.didMethod; + const method = state.snapConfig.dApp.didMethod; if (!isValidMethod(didMethod)) { console.error( `did method '${didMethod}' not supported. Supported methods are: ${availableMethods}`, @@ -51,19 +47,19 @@ export async function switchDIDMethod( } if (method !== didMethod) { - const dialogParams: SnapDialogParams = { + const dialogParams: DialogParams = { type: 'confirmation', - content: await generateCommonPanel(origin, [ + content: await generateCommonPanel(origin, network, [ heading('Switch to a different DID method to use'), text('Would you like to change did method to the following?'), divider(), - text(`Current DID method: ${method}\nNew DID method: ${didMethod}`), + text(`Current DID method: ${method}`), + text(`New DID method: ${didMethod}`), ]), }; - if (await snapDialog(snap, dialogParams)) { - accountState.accountConfig.identity.didMethod = didMethod; - await updateSnapState(snap, state); + if (await snapDialog(dialogParams)) { + await updateDIDMethod(state, didMethod); return true; } diff --git a/packages/hedera-identify-snap/packages/snap/src/rpc/gdrive/configureGoogleAccount.ts b/packages/hedera-identify-snap/packages/snap/src/rpc/gdrive/configureGoogleAccount.ts index 3d91fb02..b724a256 100644 --- a/packages/hedera-identify-snap/packages/snap/src/rpc/gdrive/configureGoogleAccount.ts +++ b/packages/hedera-identify-snap/packages/snap/src/rpc/gdrive/configureGoogleAccount.ts @@ -18,32 +18,28 @@ * */ -import { divider, heading, text } from '@metamask/snaps-ui'; -import { - GoogleToken, - IdentitySnapParams, - SnapDialogParams, -} from '../../interfaces'; +import { DialogParams, divider, heading, text } from '@metamask/snaps-sdk'; +import { GoogleToken, IdentitySnapParams } from '../../interfaces'; import { verifyToken } from '../../plugins/veramo/google-drive-data-store'; import { generateCommonPanel, snapDialog } from '../../snap/dialog'; -import { getCurrentCoinType, updateSnapState } from '../../snap/state'; +import { getCurrentCoinType, updateState } from '../../snap/state'; export const configureGoogleAccount = async ( identitySnapParams: IdentitySnapParams, { accessToken }: GoogleToken, ) => { - const { origin, snap, state, account } = identitySnapParams; + const { origin, network, state, account } = identitySnapParams; try { const newGUserEmail = await verifyToken(accessToken); const coinType = await getCurrentCoinType(); const currentGUserInfo = - state.accountState[coinType][account.evmAddress].accountConfig.identity - .googleUserInfo; + state.accountState[coinType][account.metamaskAddress].accountConfig + .identity.googleUserInfo; - const dialogParams: SnapDialogParams = { + const dialogParams: DialogParams = { type: 'confirmation', - content: await generateCommonPanel(origin, [ + content: await generateCommonPanel(origin, network, [ heading('Configure Google Drive'), text('Would you like to change your Google account to the following?'), divider(), @@ -56,18 +52,18 @@ export const configureGoogleAccount = async ( ]), }; - const result = await snapDialog(snap, dialogParams); + const result = await snapDialog(dialogParams); if (result) { state.accountState[coinType][ - account.evmAddress + account.metamaskAddress ].accountConfig.identity.googleUserInfo.accessToken = accessToken; state.accountState[coinType][ - account.evmAddress + account.metamaskAddress ].accountConfig.identity.googleUserInfo.email = newGUserEmail; console.log('new state: ', JSON.stringify(state, null, 4)); - await updateSnapState(snap, state); + await updateState(state); return true; } return false; diff --git a/packages/hedera-identify-snap/packages/snap/src/rpc/hedera/createNewHederaAccount.ts b/packages/hedera-identify-snap/packages/snap/src/rpc/hedera/createNewHederaAccount.ts deleted file mode 100644 index 51134cb0..00000000 --- a/packages/hedera-identify-snap/packages/snap/src/rpc/hedera/createNewHederaAccount.ts +++ /dev/null @@ -1,165 +0,0 @@ -/*- - * - * Hedera Identify Snap - * - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -import { AccountId, PrivateKey, PublicKey } from '@hashgraph/sdk'; -import { BigNumber } from 'bignumber.js'; -import _ from 'lodash'; -import { HederaServiceImpl, isValidHederaAccountInfo } from '../../hedera'; -import { getHederaNetwork, validHederaChainID } from '../../hedera/config'; -import { HederaMirrorInfo, SimpleHederaClient } from '../../hedera/service'; -import { WalletHedera } from '../../hedera/wallet/abstract'; -import { PrivateKeySoftwareWallet } from '../../hedera/wallet/software-private-key'; -import { HederaAccountParams, IdentitySnapParams } from '../../interfaces'; -import { getCurrentNetwork } from '../../snap/network'; -import { CreateNewHederaAccountRequestParams } from '../../types/params'; -import { getHederaAccountIfExists } from '../../utils/params'; - -/** - * Function to create a new hedera account. - * - * @param identitySnapParams - Identity snap params. - * @param newHederaAccountParams - Parameters for creating a new hedera account. - */ -export async function createNewHederaAccount( - identitySnapParams: IdentitySnapParams, - newHederaAccountParams: CreateNewHederaAccountRequestParams, -): Promise { - const { state, account } = identitySnapParams; - const { - hbarAmountToSend, - newAccountPublickey = '', - newAccountEvmAddress = '', - } = newHederaAccountParams; - - const chainId = await getCurrentNetwork(ethereum); - if (!validHederaChainID(chainId)) { - console.error( - 'Invalid Chain ID. Valid chainIDs for Hedera: [0x127: mainnet, 0x128: testnet, 0x129: previewnet]', - ); - throw new Error( - 'Non-Hedera network was selected on Metamask while trying to configure the Hedera network. Please switch the network to Hedera Network first', - ); - } - - let _accountId = ''; - if (account.extraData === null || _.isEmpty(account.extraData)) { - _accountId = await getHederaAccountIfExists( - state, - undefined, - account.evmAddress, - ); - } else { - _accountId = (account.extraData as HederaAccountParams).accountId; - } - - const network = getHederaNetwork(chainId); - if ( - !(await isValidHederaAccountInfo(account.evmAddress, _accountId, network)) - ) { - console.error( - `Could not retrieve hedera account info using the accountId '${_accountId} and evm address '${account.evmAddress}'`, - ); - throw new Error( - `Could not retrieve hedera account info using the accountId '${_accountId} and evm address '${account.evmAddress}'`, - ); - } - - const hederaService = new HederaServiceImpl(network); - const accountId = AccountId.fromString(_accountId); - const privateKey = PrivateKey.fromStringECDSA(account.privateKey); - const walletHedera: WalletHedera = new PrivateKeySoftwareWallet(privateKey); - const hederaClient = (await hederaService.createClient({ - walletHedera, - keyIndex: 0, - accountId, - })) as SimpleHederaClient; - if (hederaClient === null || _.isEmpty(hederaClient)) { - console.error('Invalid private key or account Id of the operator'); - throw new Error('Invalid private key or account Id of the operator'); - } - - let newAccount = false; - let result; - if (newAccountPublickey) { - const publicKey = PublicKey.fromString(newAccountPublickey).toStringRaw(); - try { - result = (await hederaService.getAccountFromPublicKey( - publicKey, - )) as HederaMirrorInfo; - - if (result === null || _.isEmpty(result)) { - newAccount = true; - } - } catch (error) { - console.log( - 'Error while retrieving account info using public key from the mirror node so let us just try to fund this account. Error: ', - error, - ); - newAccount = true; - } - - if (newAccount) { - result = (await hederaClient.createAccountForPublicKey({ - publicKey: PublicKey.fromString(publicKey), - initialBalance: BigNumber(hbarAmountToSend), - })) as HederaMirrorInfo; - } - } else { - try { - result = (await hederaService.getAccountFromEvmAddres( - newAccountEvmAddress, - )) as HederaMirrorInfo; - - if (result === null || _.isEmpty(result)) { - newAccount = true; - } - } catch (error) { - console.log( - 'Error while retrieving account info using evm address from the mirror node so let us just try to fund this account. Error: ', - error, - ); - newAccount = true; - } - - if (newAccount) { - result = (await hederaClient.createAccountForEvmAddress({ - evmAddress: newAccountEvmAddress, - initialBalance: BigNumber(hbarAmountToSend), - })) as HederaMirrorInfo; - } - } - - console.log( - 'Newly created Hedera Account info: ', - JSON.stringify(result, null, 4), - ); - - if (result === null || _.isEmpty(result)) { - console.error( - 'Could not create a new hedera account id for the given public key or evm address. Please try again', - ); - throw new Error( - 'Could not create a new hedera account id for the given public key or evm address. Please try again', - ); - } - result.newlyCreated = newAccount; - - return result; -} diff --git a/packages/hedera-identify-snap/packages/snap/src/rpc/snap/togglePopups.ts b/packages/hedera-identify-snap/packages/snap/src/rpc/snap/togglePopups.ts index ffad5c48..5d7b726a 100644 --- a/packages/hedera-identify-snap/packages/snap/src/rpc/snap/togglePopups.ts +++ b/packages/hedera-identify-snap/packages/snap/src/rpc/snap/togglePopups.ts @@ -18,13 +18,10 @@ * */ -import { heading, text } from '@metamask/snaps-ui'; -import { IdentitySnapParams, SnapDialogParams } from '../../interfaces'; -import { - generateCommonPanel, - snapDialog, - updatePopups, -} from '../../snap/dialog'; +import { DialogParams, heading, text } from '@metamask/snaps-sdk'; +import { IdentitySnapParams } from '../../interfaces'; +import { updatePopups } from '../../snap/dapp'; +import { generateCommonPanel, snapDialog } from '../../snap/dialog'; /** * Function to toggle popups. @@ -34,20 +31,20 @@ import { export async function togglePopups( identitySnapParams: IdentitySnapParams, ): Promise { - const { origin, snap, state } = identitySnapParams; + const { origin, network, state } = identitySnapParams; const { disablePopups } = state.snapConfig.dApp; const toggleTextToShow = disablePopups ? 'enable' : 'disable'; - const dialogParams: SnapDialogParams = { + const dialogParams: DialogParams = { type: 'confirmation', - content: await generateCommonPanel(origin, [ + content: await generateCommonPanel(origin, network, [ heading('Toggle Popups'), text(`Would you like to ${toggleTextToShow} the popups?`), ]), }; - const result = await snapDialog(snap, dialogParams); + const result = await snapDialog(dialogParams); if (result) { - await updatePopups(snap, state); + await updatePopups(state); return true; } return false; diff --git a/packages/hedera-identify-snap/packages/snap/src/rpc/vc/createVC.ts b/packages/hedera-identify-snap/packages/snap/src/rpc/vc/createVC.ts index 0f50e97f..15052abb 100644 --- a/packages/hedera-identify-snap/packages/snap/src/rpc/vc/createVC.ts +++ b/packages/hedera-identify-snap/packages/snap/src/rpc/vc/createVC.ts @@ -18,15 +18,16 @@ * */ -import { divider, heading, text } from '@metamask/snaps-ui'; +import { DialogParams, divider, heading, text } from '@metamask/snaps-sdk'; import { ProofFormat, W3CVerifiableCredential } from '@veramo/core'; import cloneDeep from 'lodash.clonedeep'; import { v4 as uuidv4 } from 'uuid'; import { validHederaChainID } from '../../hedera/config'; -import { IdentitySnapParams, SnapDialogParams } from '../../interfaces'; +import { IdentitySnapParams } from '../../interfaces'; import { IDataManagerSaveResult, ISaveVC, + QueryMetadata, SaveOptions, } from '../../plugins/veramo/verifiable-creds-manager'; import { generateCommonPanel, snapDialog } from '../../snap/dialog'; @@ -37,6 +38,7 @@ import { CreateVCResponseResult, } from '../../types/params'; import { getVeramoAgent } from '../../veramo/agent'; +import { sha256 } from 'js-sha256'; /** * Function to create VC. @@ -48,10 +50,10 @@ export async function createVC( identitySnapParams: IdentitySnapParams, vcRequestParams: CreateVCRequestParams, ): Promise { - const { origin, snap, state, metamask, account } = identitySnapParams; + const { origin, network, state, account } = identitySnapParams; // Get Veramo agent - const agent = await getVeramoAgent(snap, state); + const agent = await getVeramoAgent(state); // GET DID const { did } = account.identifier; @@ -65,9 +67,9 @@ export async function createVC( const { store = 'snap' } = options || {}; const optionsFiltered = { store } as SaveOptions; - const dialogParams: SnapDialogParams = { + const dialogParams: DialogParams = { type: 'confirmation', - content: await generateCommonPanel(origin, [ + content: await generateCommonPanel(origin, network, [ heading('Create Verifiable Credential'), text('Would you like to create and save the following VC in the snap?'), divider(), @@ -79,7 +81,7 @@ export async function createVC( ]), }; - if (await snapDialog(snap, dialogParams)) { + if (await snapDialog(dialogParams)) { const issuanceDate = new Date(); // Set the expiration date to be 1 year from the date it's issued const expirationDate = cloneDeep(issuanceDate); @@ -99,10 +101,10 @@ export async function createVC( id: did, // identifier for the only subject of the credential [vcKey]: vcValue, // assertion about the only subject of the credential }; - const chainId = await getCurrentNetwork(metamask); + const chainId = await getCurrentNetwork(); const accountState = await getAccountStateByCoinType( state, - account.evmAddress, + account.metamaskAddress, ); if (validHederaChainID(chainId)) { const hederaAccountId = accountState.extraData as string; @@ -119,10 +121,19 @@ export async function createVC( // digital proof that makes the credential tamper-evident proofFormat: 'jwt' as ProofFormat, }); + console.log( + 'verifiableCredential: ', + JSON.stringify(verifiableCredential, null, 4), + ); // Save the Verifiable Credential to all the stores the user requested for const saved: IDataManagerSaveResult[] = await agent.saveVC({ - data: [{ vc: verifiableCredential, id: uuidv4() }] as ISaveVC[], + data: [ + { + vc: verifiableCredential, + id: sha256(JSON.stringify(verifiableCredential)), + }, + ] as ISaveVC[], options: optionsFiltered, accessToken: accountState.accountConfig.identity.googleUserInfo.accessToken, @@ -130,11 +141,11 @@ export async function createVC( // Retrieve the created Verifiable Credential const result: CreateVCResponseResult = { - data: verifiableCredential, + data: verifiableCredential as W3CVerifiableCredential, metadata: { id: saved[0].id, store: saved.map((res) => res.store), - }, + } as QueryMetadata, }; console.log( diff --git a/packages/hedera-identify-snap/packages/snap/src/rpc/vc/createVP.ts b/packages/hedera-identify-snap/packages/snap/src/rpc/vc/createVP.ts index 2add2d6d..19573689 100644 --- a/packages/hedera-identify-snap/packages/snap/src/rpc/vc/createVP.ts +++ b/packages/hedera-identify-snap/packages/snap/src/rpc/vc/createVP.ts @@ -18,12 +18,13 @@ * */ +import { DialogParams } from '@metamask/snaps-sdk'; import { ProofFormat, VerifiableCredential, VerifiablePresentation, } from '@veramo/core'; -import { IdentitySnapParams, SnapDialogParams } from '../../interfaces'; +import { IdentitySnapParams } from '../../interfaces'; import { IDataManagerQueryResult, QueryOptions, @@ -46,7 +47,7 @@ export async function createVP( identitySnapParams: IdentitySnapParams, vpRequestParams: CreateVPRequestParams, ): Promise { - const { origin, snap, state, account } = identitySnapParams; + const { origin, network, state, account } = identitySnapParams; const { vcIds = [], @@ -65,7 +66,7 @@ export async function createVP( const challenge = proofInfo?.challenge; // Get Veramo agent - const agent = await getVeramoAgent(snap, state); + const agent = await getVeramoAgent(state); // GET DID const { did } = account.identifier; @@ -111,17 +112,18 @@ export async function createVP( const prompt = 'Do you wish to create a VP from the following VCs?'; const description = 'A Verifiable Presentation is a secure way for someone to present information about themselves or their identity to someone else while ensuring that the information is accureate and trustworthy'; - const dialogParams: SnapDialogParams = { + const dialogParams: DialogParams = { type: 'confirmation', content: await generateVCPanel( origin, + network, header, prompt, description, vcsWithMetadata, ), }; - if (config.dApp.disablePopups || (await snapDialog(snap, dialogParams))) { + if (config.dApp.disablePopups || (await snapDialog(dialogParams))) { // Generate a Verifiable Presentation from VCs const vp = await agent.createVerifiablePresentation({ presentation: { diff --git a/packages/hedera-identify-snap/packages/snap/src/rpc/vc/deleteAllVCs.ts b/packages/hedera-identify-snap/packages/snap/src/rpc/vc/deleteAllVCs.ts index 44b9b0e4..13347e75 100644 --- a/packages/hedera-identify-snap/packages/snap/src/rpc/vc/deleteAllVCs.ts +++ b/packages/hedera-identify-snap/packages/snap/src/rpc/vc/deleteAllVCs.ts @@ -18,7 +18,8 @@ * */ -import { IdentitySnapParams, SnapDialogParams } from '../../interfaces'; +import { DialogParams } from '@metamask/snaps-sdk'; +import { IdentitySnapParams } from '../../interfaces'; import { ClearOptions, IDataManagerClearArgs, @@ -39,17 +40,17 @@ export async function deleteAllVCs( identitySnapParams: IdentitySnapParams, vcRequestParams: IDataManagerClearArgs, ): Promise { - const { origin, snap, state, account } = identitySnapParams; + const { origin, network, state, account } = identitySnapParams; const { options } = vcRequestParams || {}; const { store = 'snap' } = options || {}; const optionsFiltered = { store } as ClearOptions; // Get Veramo agent - const agent = await getVeramoAgent(snap, state); + const agent = await getVeramoAgent(state); const accountState = await getAccountStateByCoinType( state, - account.evmAddress, + account.metamaskAddress, ); const vcsToBeRemoved = (await agent.queryVC({ filter: undefined, @@ -60,10 +61,11 @@ export async function deleteAllVCs( const header = 'Delete all Verifiable Credentials'; const prompt = `Are you sure you want to remove all your VCs from the store '${store}'?`; const description = `Note that this action cannot be reversed and you will need to recreate your VCs if you go through with it. Number of VCs to be removed is ${vcsToBeRemoved.length.toString()}`; - const dialogParams: SnapDialogParams = { + const dialogParams: DialogParams = { type: 'confirmation', content: await generateVCPanel( origin, + network, header, prompt, description, @@ -71,7 +73,7 @@ export async function deleteAllVCs( ), }; - if (await snapDialog(snap, dialogParams)) { + if (await snapDialog(dialogParams)) { // Remove all the Verifiable Credentials from the store return await agent.clearVCs({ options: optionsFiltered, diff --git a/packages/hedera-identify-snap/packages/snap/src/rpc/vc/getVCs.ts b/packages/hedera-identify-snap/packages/snap/src/rpc/vc/getVCs.ts index c2bce131..4cacf4d9 100644 --- a/packages/hedera-identify-snap/packages/snap/src/rpc/vc/getVCs.ts +++ b/packages/hedera-identify-snap/packages/snap/src/rpc/vc/getVCs.ts @@ -18,7 +18,8 @@ * */ -import { IdentitySnapParams, SnapDialogParams } from '../../interfaces'; +import { DialogParams } from '@metamask/snaps-sdk'; +import { IdentitySnapParams } from '../../interfaces'; import { IDataManagerQueryArgs, IDataManagerQueryResult, @@ -38,18 +39,18 @@ export async function getVCs( identitySnapParams: IdentitySnapParams, vcRequestParams: IDataManagerQueryArgs, ): Promise { - const { origin, snap, state, account } = identitySnapParams; + const { origin, network, state, account } = identitySnapParams; const { filter, options } = vcRequestParams || {}; const { store = 'snap', returnStore = true } = options || {}; // Get Veramo agent - const agent = await getVeramoAgent(snap, state); + const agent = await getVeramoAgent(state); // Get VCs const accountState = await getAccountStateByCoinType( state, - account.evmAddress, + account.metamaskAddress, ); const optionsFiltered = { store, returnStore } as QueryOptions; const vcs = (await agent.queryVC({ @@ -57,20 +58,23 @@ export async function getVCs( options: optionsFiltered, accessToken: accountState.accountConfig.identity.googleUserInfo.accessToken, })) as IDataManagerQueryResult[]; - console.log('VCs: ', JSON.stringify(vcs, null, 4)); const header = 'Retrieve Verifiable Credentials'; const prompt = 'Are you sure you want to send VCs to the dApp?'; const description = `Some dApps are less secure than others and could save data from VCs against your will. Be careful where you send your private VCs! Number of VCs submitted is ${vcs.length.toString()}`; - const dialogParams: SnapDialogParams = { + const dialogParams: DialogParams = { type: 'confirmation', - content: await generateVCPanel(origin, header, prompt, description, vcs), + content: await generateVCPanel( + origin, + network, + header, + prompt, + description, + vcs, + ), }; - if ( - state.snapConfig.dApp.disablePopups || - (await snapDialog(snap, dialogParams)) - ) { + if (state.snapConfig.dApp.disablePopups || (await snapDialog(dialogParams))) { return vcs; } diff --git a/packages/hedera-identify-snap/packages/snap/src/rpc/vc/removeVC.ts b/packages/hedera-identify-snap/packages/snap/src/rpc/vc/removeVC.ts index 70d00212..95f0ac34 100644 --- a/packages/hedera-identify-snap/packages/snap/src/rpc/vc/removeVC.ts +++ b/packages/hedera-identify-snap/packages/snap/src/rpc/vc/removeVC.ts @@ -18,7 +18,8 @@ * */ -import { IdentitySnapParams, SnapDialogParams } from '../../interfaces'; +import { DialogParams } from '@metamask/snaps-sdk'; +import { IdentitySnapParams } from '../../interfaces'; import { DeleteOptions, IDataManagerDeleteArgs, @@ -39,14 +40,14 @@ export async function removeVC( identitySnapParams: IdentitySnapParams, vcRequestParams: IDataManagerDeleteArgs, ): Promise { - const { origin, snap, state, account } = identitySnapParams; + const { origin, network, state, account } = identitySnapParams; const { id = '', options } = vcRequestParams || {}; const { store = 'snap' } = options || {}; const optionsFiltered = { store } as DeleteOptions; // Get Veramo agent - const agent = await getVeramoAgent(snap, state); + const agent = await getVeramoAgent(state); const ids = typeof id === 'string' ? [id] : id; if (ids.length === 0) { @@ -55,7 +56,7 @@ export async function removeVC( const accountState = await getAccountStateByCoinType( state, - account.evmAddress, + account.metamaskAddress, ); const vcsToBeRemoved: IDataManagerQueryResult[] = []; for (const vcId of ids) { @@ -76,10 +77,11 @@ export async function removeVC( const header = 'Remove specific Verifiable Credentials'; const prompt = 'Are you sure you want to remove the following VCs?'; const description = `Note that this action cannot be reversed and you will need to recreate your VCs if you go through with it. Number of VCs to be removed is ${vcsToBeRemoved.length.toString()}`; - const dialogParams: SnapDialogParams = { + const dialogParams: DialogParams = { type: 'confirmation', content: await generateVCPanel( origin, + network, header, prompt, description, @@ -87,7 +89,7 @@ export async function removeVC( ), }; - if (await snapDialog(snap, dialogParams)) { + if (await snapDialog(dialogParams)) { // Remove the specified Verifiable Credentials from the store based on their IDs return Promise.all( ids.map(async (_id: string) => { diff --git a/packages/hedera-identify-snap/packages/snap/src/rpc/vc/saveVC.ts b/packages/hedera-identify-snap/packages/snap/src/rpc/vc/saveVC.ts index 546a1e6d..988ad129 100644 --- a/packages/hedera-identify-snap/packages/snap/src/rpc/vc/saveVC.ts +++ b/packages/hedera-identify-snap/packages/snap/src/rpc/vc/saveVC.ts @@ -18,8 +18,9 @@ * */ +import { DialogParams } from '@metamask/snaps-sdk'; import { W3CVerifiableCredential } from '@veramo/core'; -import { IdentitySnapParams, SnapDialogParams } from '../../interfaces'; +import { IdentitySnapParams } from '../../interfaces'; import { IDataManagerQueryResult, IDataManagerSaveArgs, @@ -41,7 +42,7 @@ export async function saveVC( identitySnapParams: IdentitySnapParams, vcSaveRequestParams: IDataManagerSaveArgs, ): Promise { - const { origin, snap, state, account } = identitySnapParams; + const { origin, network, state, account } = identitySnapParams; const { data: verifiableCredentials, options } = vcSaveRequestParams || {}; const { store = 'snap' } = options || {}; @@ -49,7 +50,7 @@ export async function saveVC( const optionsFiltered = { store } as SaveOptions; // Get Veramo agent - const agent = await getVeramoAgent(snap, state); + const agent = await getVeramoAgent(state); const header = 'Save Verifiable Credentials'; const prompt = `Are you sure you want to save the following VCs in ${ @@ -72,10 +73,11 @@ export async function saveVC( }); }, ); - const dialogParams: SnapDialogParams = { + const dialogParams: DialogParams = { type: 'confirmation', content: await generateVCPanel( origin, + network, header, prompt, description, @@ -83,11 +85,11 @@ export async function saveVC( ), }; - if (await snapDialog(snap, dialogParams)) { + if (await snapDialog(dialogParams)) { // Save the Verifiable Credential const accountState = await getAccountStateByCoinType( state, - account.evmAddress, + account.metamaskAddress, ); const filteredCredentials: W3CVerifiableCredential[] = ( @@ -97,7 +99,7 @@ export async function saveVC( const subjectDid: string = vcObj.credentialSubject.id; const subjectAccount = subjectDid.split(':')[4]; - return account.evmAddress === subjectAccount; + return account.metamaskAddress === subjectAccount; }); return await agent.saveVC({ data: (filteredCredentials as W3CVerifiableCredential[]).map( diff --git a/packages/hedera-identify-snap/packages/snap/src/rpc/vc/syncGoogleVCs.ts b/packages/hedera-identify-snap/packages/snap/src/rpc/vc/syncGoogleVCs.ts index 3b842dd7..9ff27031 100644 --- a/packages/hedera-identify-snap/packages/snap/src/rpc/vc/syncGoogleVCs.ts +++ b/packages/hedera-identify-snap/packages/snap/src/rpc/vc/syncGoogleVCs.ts @@ -18,11 +18,11 @@ * */ +import { DialogParams } from '@metamask/snaps-sdk'; import { Account, IdentitySnapParams, IdentitySnapState, - SnapDialogParams, } from '../../interfaces'; import { verifyToken } from '../../plugins/veramo/google-drive-data-store'; import { @@ -44,15 +44,15 @@ import { Agent, getVeramoAgent } from '../../veramo/agent'; export async function syncGoogleVCs( identitySnapParams: IdentitySnapParams, ): Promise { - const { origin, state, account } = identitySnapParams; + const { origin, network, state, account } = identitySnapParams; try { // Get Veramo agent - const agent = await getVeramoAgent(snap, state); + const agent = await getVeramoAgent(state); const accountState = await getAccountStateByCoinType( state, - account.evmAddress, + account.metamaskAddress, ); const gUserEmail = await verifyToken( accountState.accountConfig.identity.googleUserInfo.accessToken, @@ -95,6 +95,7 @@ export async function syncGoogleVCs( let vcsNotInSnapSync = true; if (vcsNotInSnap.length > 0) { vcsNotInSnapSync = await handleSync( + network, state, account, agent, @@ -109,6 +110,7 @@ export async function syncGoogleVCs( let vcsNotInGDriveSync = true; if (vcsNotInGDrive.length > 0) { vcsNotInGDriveSync = await handleSync( + network, state, account, agent, @@ -143,6 +145,7 @@ export async function syncGoogleVCs( /** * Function to handle the snap dialog and import/export each VC. * + * @param network- Network name. * @param state - Identity state. * @param account - Currently connected account. * @param agent - Veramo. @@ -154,6 +157,7 @@ export async function syncGoogleVCs( * @param store - The snap store to use(snap or googleDrive). */ async function handleSync( + network: string, state: IdentitySnapState, account: Account, agent: Agent, @@ -164,17 +168,24 @@ async function handleSync( vcs: IDataManagerQueryResult[], store: string, ): Promise { - const dialogParams: SnapDialogParams = { + const dialogParams: DialogParams = { type: 'confirmation', - content: await generateVCPanel(origin, header, prompt, description, vcs), + content: await generateVCPanel( + origin, + network, + header, + prompt, + description, + vcs, + ), }; - if (await snapDialog(snap, dialogParams)) { + if (await snapDialog(dialogParams)) { const options = { store, } as SaveOptions; const accountState = await getAccountStateByCoinType( state, - account.evmAddress, + account.metamaskAddress, ); const data = vcs.map((x) => { return { vc: x.data, id: x.metadata.id } as ISaveVC; diff --git a/packages/hedera-identify-snap/packages/snap/src/rpc/vc/verifyVC.ts b/packages/hedera-identify-snap/packages/snap/src/rpc/vc/verifyVC.ts index cfd15658..266cb2ba 100644 --- a/packages/hedera-identify-snap/packages/snap/src/rpc/vc/verifyVC.ts +++ b/packages/hedera-identify-snap/packages/snap/src/rpc/vc/verifyVC.ts @@ -34,7 +34,7 @@ export async function verifyVC( ): Promise { const { state } = identitySnapParams; // Get Veramo agent - const agent = await getVeramoAgent(snap, state); + const agent = await getVeramoAgent(state); // Verify the verifiable credential(VC) const result = await agent.verifyCredential({ credential: vc }); diff --git a/packages/hedera-identify-snap/packages/snap/src/rpc/vc/verifyVP.ts b/packages/hedera-identify-snap/packages/snap/src/rpc/vc/verifyVP.ts index 81ee7a8d..13952687 100644 --- a/packages/hedera-identify-snap/packages/snap/src/rpc/vc/verifyVP.ts +++ b/packages/hedera-identify-snap/packages/snap/src/rpc/vc/verifyVP.ts @@ -34,7 +34,7 @@ export async function verifyVP( ): Promise { const { state } = identitySnapParams; // Get Veramo agent - const agent = await getVeramoAgent(snap, state); + const agent = await getVeramoAgent(state); // Verify the verifiable presentation(VP) const result = await agent.verifyPresentation({ diff --git a/packages/hedera-identify-snap/packages/snap/src/snap/account.ts b/packages/hedera-identify-snap/packages/snap/src/snap/account.ts index 7d89a23a..7a639088 100644 --- a/packages/hedera-identify-snap/packages/snap/src/snap/account.ts +++ b/packages/hedera-identify-snap/packages/snap/src/snap/account.ts @@ -19,7 +19,8 @@ */ import { AccountId, PrivateKey } from '@hashgraph/sdk'; -import { divider, heading, text } from '@metamask/snaps-ui'; +import { MetaMaskInpageProvider } from '@metamask/providers'; +import { DialogParams, divider, heading, text } from '@metamask/snaps-sdk'; import { Wallet, ethers } from 'ethers'; import _ from 'lodash'; import { validHederaChainID } from '../hedera/config'; @@ -31,7 +32,6 @@ import { HederaAccountParams, IdentitySnapState, MetamaskAccountParams, - SnapDialogParams, } from '../interfaces'; import { DEFAULTCOINTYPE, HEDERACOINTYPE } from '../types/constants'; import { getHederaAccountIfExists } from '../utils/params'; @@ -49,6 +49,8 @@ import { getCurrentCoinType, initAccountState } from './state'; * @returns MetaMask address and did. */ export async function getCurrentAccount( + origin: string, + network: string, state: IdentitySnapState, params: unknown, isExternalAccount: boolean, @@ -70,7 +72,12 @@ export async function getCurrentAccount( `Invalid Hedera Account Id '${hederaAccountId}' is not a valid account Id`, ); } - return await connectHederaAccount(state, hederaAccountId); + return await connectHederaAccount( + origin, + network, + state, + hederaAccountId, + ); } else if ( nonMetamaskAccount.externalAccount.blockchainType === 'evm' ) { @@ -85,7 +92,7 @@ export async function getCurrentAccount( `Invalid EVM Account Address '${ethAddress}' is not a valid address`, ); } - return await connectEVMAccount(state, ethAddress); + return await connectEVMAccount(origin, network, state, ethAddress); } console.error( @@ -114,12 +121,12 @@ export async function getCurrentAccount( console.log( `The address ${metamaskAddress} has NOT yet been configured in the Identify Snap. Configuring now...`, ); - await initAccountState(snap, state, coinType, metamaskAddress); + await initAccountState(state, coinType, metamaskAddress); } return await veramoImportMetaMaskAccount( - snap, + network, state, - ethereum, + (window as any).ethereum as MetaMaskInpageProvider, metamaskAddress, ); } catch (e: any) { @@ -135,6 +142,8 @@ export async function getCurrentAccount( * @param evmAddress - EVM Account address. */ async function connectEVMAccount( + origin: string, + network: string, state: IdentitySnapState, evmAddress: string, ): Promise { @@ -154,9 +163,9 @@ async function connectEVMAccount( controllerKeyId ].privateKeyHex; } else { - const dialogParamsForPrivateKey: SnapDialogParams = { + const dialogParamsForPrivateKey: DialogParams = { type: 'prompt', - content: await generateCommonPanel(origin, [ + content: await generateCommonPanel(origin, network, [ heading('Connect to EVM Account'), text('Enter your ECDSA private key for the following Account'), divider(), @@ -165,7 +174,7 @@ async function connectEVMAccount( placeholder: '2386d1d21644dc65d...', // You can use '2386d1d21644dc65d4e4b9e2242c5f155cab174916cbc46ad85622cdaeac835c' for testing purposes }; privateKey = PrivateKey.fromString( - (await snapDialog(snap, dialogParamsForPrivateKey)) as string, + (await snapDialog(dialogParamsForPrivateKey)) as string, ).toStringRaw(); } @@ -177,9 +186,9 @@ async function connectEVMAccount( }; return await veramoImportMetaMaskAccount( - snap, + network, state, - ethereum, + (window as any).ethereum as MetaMaskInpageProvider, '', accountViaPrivateKey, ); @@ -192,10 +201,12 @@ async function connectEVMAccount( * @param accountId - Account id. */ async function connectHederaAccount( + origin: string, + network: string, state: IdentitySnapState, accountId: string, ): Promise { - const chainId = await getCurrentNetwork(ethereum); + const chainId = await getCurrentNetwork(); if (!validHederaChainID(chainId)) { console.error( 'Invalid Chain ID. Valid chainIDs for Hedera: [0x127: mainnet, 0x128: testnet, 0x129: previewnet]', @@ -212,9 +223,9 @@ async function connectHederaAccount( undefined, ); if (evmAddress === null || _.isEmpty(evmAddress)) { - const dialogParamsForPrivateKey: SnapDialogParams = { + const dialogParamsForPrivateKey: DialogParams = { type: 'prompt', - content: await generateCommonPanel(origin, [ + content: await generateCommonPanel(origin, network, [ heading('Connect to Hedera Account'), text('Enter your ECDSA private key for the following Account'), divider(), @@ -222,8 +233,8 @@ async function connectHederaAccount( ]), placeholder: '2386d1d21644dc65d...', // You can use '2386d1d21644dc65d4e4b9e2242c5f155cab174916cbc46ad85622cdaeac835c' and '0.0.15215' for testing purposes }; - privateKey = PrivateKey.fromString( - (await snapDialog(snap, dialogParamsForPrivateKey)) as string, + privateKey = PrivateKey.fromStringECDSA( + (await snapDialog(dialogParamsForPrivateKey)) as string, ).toStringRaw(); } else { const controllerKeyId = `metamask-${evmAddress}`; @@ -242,9 +253,9 @@ async function connectHederaAccount( }; return await veramoImportMetaMaskAccount( - snap, + network, state, - ethereum, + (window as any).ethereum as MetaMaskInpageProvider, '', accountViaPrivateKey, ); diff --git a/packages/hedera-identify-snap/packages/snap/src/snap/dapp.ts b/packages/hedera-identify-snap/packages/snap/src/snap/dapp.ts index ec4293c4..246c8e3e 100644 --- a/packages/hedera-identify-snap/packages/snap/src/snap/dapp.ts +++ b/packages/hedera-identify-snap/packages/snap/src/snap/dapp.ts @@ -18,9 +18,19 @@ * */ -import { SnapsGlobalObject } from '@metamask/snaps-types'; import { IdentitySnapState } from '../interfaces'; -import { updateSnapState } from './state'; +import { updateState } from './state'; + +/** + * Function that toggles the disablePopups flag in the config. + * + * @param snap - Snap. + * @param state - IdentitySnapState. + */ +export async function updatePopups(state: IdentitySnapState) { + state.snapConfig.dApp.disablePopups = !state.snapConfig.dApp.disablePopups; + await updateState(state); +} /** * Function that lets you add a friendly dApp. @@ -29,13 +39,9 @@ import { updateSnapState } from './state'; * @param state - IdentitySnapState. * @param dapp - Dapp. */ -export async function addFriendlyDapp( - snap: SnapsGlobalObject, - state: IdentitySnapState, - dapp: string, -) { +export async function addFriendlyDapp(state: IdentitySnapState, dapp: string) { state.snapConfig.dApp.friendlyDapps.push(dapp); - await updateSnapState(snap, state); + await updateState(state); } /** @@ -46,7 +52,6 @@ export async function addFriendlyDapp( * @param dapp - Dapp. */ export async function removeFriendlyDapp( - snap: SnapsGlobalObject, state: IdentitySnapState, dapp: string, ) { @@ -55,5 +60,19 @@ export async function removeFriendlyDapp( // friendlyDapps = friendlyDapps.filter((d) => d !== dapp); state.snapConfig.dApp.friendlyDapps = state.snapConfig.dApp.friendlyDapps.filter((d) => d !== dapp); - await updateSnapState(snap, state); + await updateState(state); +} + +/** + * Function that switches the did method to use. + * + * @param snap - Snap. + * @param state - IdentitySnapState. + */ +export async function updateDIDMethod( + state: IdentitySnapState, + didMethod: string, +) { + state.snapConfig.dApp.didMethod = didMethod; + await updateState(state); } diff --git a/packages/hedera-identify-snap/packages/snap/src/snap/dialog.ts b/packages/hedera-identify-snap/packages/snap/src/snap/dialog.ts index 91fa495d..e5d21e28 100644 --- a/packages/hedera-identify-snap/packages/snap/src/snap/dialog.ts +++ b/packages/hedera-identify-snap/packages/snap/src/snap/dialog.ts @@ -18,27 +18,46 @@ * */ -import { SnapsGlobalObject } from '@metamask/snaps-types'; -import { divider, heading, panel, Panel, text } from '@metamask/snaps-ui'; +import { + DialogParams, + divider, + heading, + NodeType, + panel, + Panel, + text, +} from '@metamask/snaps-sdk'; import { VerifiableCredential } from '@veramo/core'; import _ from 'lodash'; import cloneDeep from 'lodash.clonedeep'; -import { IdentitySnapState, SnapDialogParams } from '../interfaces'; +import { + getHederaNetwork, + getOtherNetwork, + validHederaChainID, +} from '../hedera/config'; import { IDataManagerQueryResult } from '../plugins/veramo/verifiable-creds-manager'; -import { updateSnapState } from './state'; -/** - * Function that toggles the disablePopups flag in the config. - * - * @param snap - Snap. - * @param state - IdentitySnapState. - */ -export async function updatePopups( - snap: SnapsGlobalObject, - state: IdentitySnapState, -) { - state.snapConfig.dApp.disablePopups = !state.snapConfig.dApp.disablePopups; - await updateSnapState(snap, state); +export function initializePanelToShow(): any { + const panelToShow: ( + | { + value: string; + type: NodeType.Heading; + } + | { + value: string; + type: NodeType.Text; + markdown?: boolean | undefined; + } + | { + type: NodeType.Divider; + } + | { + value: string; + type: NodeType.Copyable; + sensitive?: boolean | undefined; + } + )[] = []; + return panelToShow; } /** @@ -48,8 +67,7 @@ export async function updatePopups( * @param params - Snap dialog params. */ export async function snapDialog( - snap: SnapsGlobalObject, - params: SnapDialogParams, + params: DialogParams, ): Promise { return (await snap.request({ method: 'snap_dialog', @@ -59,15 +77,29 @@ export async function snapDialog( /** * Function to generate snap dialog panel. - * * @param origin - The origin of where the call is being made from. + * @param network - The network the call is being made on. + * @param mirrorNodeUrl - The mirror node url. * @param prompt - Prompt text of the metamask dialog box(eg. 'Are you sure you want to send VCs to the dApp?'). + * @returns Panel to be displayed in the snap dialog. */ export async function generateCommonPanel( origin: string, + network: string, prompt: any[], ): Promise { - const panelToShow = [text(`Origin: ${origin}`), divider(), ...prompt]; + let networkToShow = network; + if (validHederaChainID(network)) { + networkToShow = `Hedera - ${getHederaNetwork(network)}`; + } else { + networkToShow = getOtherNetwork(network); + } + const panelToShow = [ + text(`Origin: **${origin}**`), + text(`Network: **${networkToShow}**`), + divider(), + ...prompt, + ]; return panel(panelToShow); } @@ -82,14 +114,22 @@ export async function generateCommonPanel( */ export async function generateVCPanel( origin: string, + network: string, header: string, prompt: string, description: string, vcs: IDataManagerQueryResult[], ): Promise { + let networkToShow = network; + if (validHederaChainID(network)) { + networkToShow = `Hedera - ${getHederaNetwork(network)}`; + } else { + networkToShow = getOtherNetwork(network); + } const vcsToUse = cloneDeep(vcs); const panelToShow = [ text(`Origin: ${origin}`), + text(`Network: **${networkToShow}**`), divider(), heading(header), text(prompt), @@ -165,12 +205,13 @@ export async function generateVCPanel( * @param prevHederaAccountId - HederaIdentifier. */ export async function requestHederaAccountId( - snap: SnapsGlobalObject, + origin: string, + network: string, prevHederaAccountId?: string, ): Promise { - const dialogParamsForHederaAccountId: SnapDialogParams = { + const dialogParamsForHederaAccountId: DialogParams = { type: 'prompt', - content: await generateCommonPanel(origin, [ + content: await generateCommonPanel(origin, network, [ heading('Connect to Hedera Account'), prevHederaAccountId ? text( @@ -180,5 +221,5 @@ export async function requestHederaAccountId( ]), placeholder: '0.0.3658062', }; - return (await snapDialog(snap, dialogParamsForHederaAccountId)) as string; + return (await snapDialog(dialogParamsForHederaAccountId)) as string; } diff --git a/packages/hedera-identify-snap/packages/snap/src/snap/network.ts b/packages/hedera-identify-snap/packages/snap/src/snap/network.ts index 27b8df07..ec924bb2 100644 --- a/packages/hedera-identify-snap/packages/snap/src/snap/network.ts +++ b/packages/hedera-identify-snap/packages/snap/src/snap/network.ts @@ -22,12 +22,11 @@ import { MetaMaskInpageProvider } from '@metamask/providers'; /** * Get current network. - * * @param metamask - Metamask provider. + * @returns Current network. */ -export async function getCurrentNetwork( - metamask: MetaMaskInpageProvider, -): Promise { +export async function getCurrentNetwork(): Promise { + const metamask = (window as any).ethereum as MetaMaskInpageProvider; return (await metamask.request({ method: 'eth_chainId', })) as string; diff --git a/packages/hedera-identify-snap/packages/snap/src/snap/state.ts b/packages/hedera-identify-snap/packages/snap/src/snap/state.ts index 8cf92c9a..6d96d1e0 100644 --- a/packages/hedera-identify-snap/packages/snap/src/snap/state.ts +++ b/packages/hedera-identify-snap/packages/snap/src/snap/state.ts @@ -18,12 +18,11 @@ * */ -import { SnapsGlobalObject } from '@metamask/snaps-types'; import { validHederaChainID } from '../hedera/config'; import { Account, + IdentitySnapState as IdentifySnapState, IdentityAccountState, - IdentitySnapState, } from '../interfaces'; import { DEFAULTCOINTYPE, HEDERACOINTYPE } from '../types/constants'; import { getEmptyAccountState, getInitialSnapState } from '../utils/config'; @@ -36,10 +35,7 @@ import { getCurrentNetwork } from './network'; * @param snap - Snap. * @param snapState - Object to replace the current object in the MetaMask state. */ -export async function updateSnapState( - snap: SnapsGlobalObject, - snapState: IdentitySnapState, -) { +export async function updateState(snapState: IdentifySnapState) { await snap.request({ method: 'snap_manageState', params: { @@ -56,35 +52,31 @@ export async function updateSnapState( * @public * @returns Object from the state. */ -export async function getSnapState( - snap: SnapsGlobalObject, -): Promise { +export async function getState(): Promise { const state = (await snap.request({ method: 'snap_manageState', params: { operation: 'get' }, - })) as IdentitySnapState | null; + })) as IdentifySnapState | null; if (!state) { - throw Error('IdentitySnapState is not initialized!'); + throw Error('IdentifySnapState is not initialized!'); } return state; } /** - * Function to retrieve IdentitySnapState object from the MetaMask state. + * Function to retrieve IdentifySnapState object from the MetaMask state. * * @param snap - Snap. * @public * @returns Object from the state. */ -export async function getSnapStateUnchecked( - snap: SnapsGlobalObject, -): Promise { +export async function getStateUnchecked(): Promise { const state = (await snap.request({ method: 'snap_manageState', params: { operation: 'get' }, - })) as IdentitySnapState | null; + })) as IdentifySnapState | null; return state; } @@ -96,11 +88,9 @@ export async function getSnapStateUnchecked( * @public * @returns Object. */ -export async function initSnapState( - snap: SnapsGlobalObject, -): Promise { +export async function initState(): Promise { const state = getInitialSnapState(); - await updateSnapState(snap, state); + await updateState(state); return state; } @@ -113,14 +103,13 @@ export async function initSnapState( * @param evmAddress - The account address. */ export async function initAccountState( - snap: SnapsGlobalObject, - state: IdentitySnapState, + state: IdentifySnapState, coinType: string, evmAddress: string, ): Promise { - state.currentAccount = { evmAddress } as Account; + state.currentAccount = { metamaskAddress: evmAddress } as Account; state.accountState[coinType][evmAddress] = getEmptyAccountState(); - await updateSnapState(snap, state); + await updateState(state); } /** @@ -129,7 +118,7 @@ export async function initAccountState( * @returns Result. */ export async function getCurrentCoinType(): Promise { - const chainId = await getCurrentNetwork(ethereum); + const chainId = await getCurrentNetwork(); let coinType = DEFAULTCOINTYPE; if (validHederaChainID(chainId)) { coinType = HEDERACOINTYPE; @@ -145,7 +134,7 @@ export async function getCurrentCoinType(): Promise { * @returns Result. */ export async function getAccountStateByCoinType( - state: IdentitySnapState, + state: IdentifySnapState, evmAddress: string, ): Promise { const coinType = await getCurrentCoinType(); diff --git a/packages/hedera-identify-snap/packages/snap/src/types/constants.ts b/packages/hedera-identify-snap/packages/snap/src/types/constants.ts index b9b85079..88bfeddd 100644 --- a/packages/hedera-identify-snap/packages/snap/src/types/constants.ts +++ b/packages/hedera-identify-snap/packages/snap/src/types/constants.ts @@ -27,7 +27,7 @@ export const isIn = (values: readonly T[], value: any): value is T => { export const availableVCStores = ['snap', 'googleDrive'] as const; export const isValidVCStore = (x: string) => isIn(availableVCStores, x); -export const availableMethods = ['did:pkh'] as const; +export const availableMethods = ['did:pkh', 'did:key', 'did:hedera'] as const; export const isValidMethod = (x: string) => isIn(availableMethods, x); // 60 for ethereum and 3030 for hedera diff --git a/packages/hedera-identify-snap/packages/snap/src/types/params.ts b/packages/hedera-identify-snap/packages/snap/src/types/params.ts index 71b943ed..0602820f 100644 --- a/packages/hedera-identify-snap/packages/snap/src/types/params.ts +++ b/packages/hedera-identify-snap/packages/snap/src/types/params.ts @@ -54,9 +54,3 @@ export type CreateVPRequestParams = { options?: CreateVPOptions; proofInfo?: ProofInfo; }; - -export type CreateNewHederaAccountRequestParams = { - hbarAmountToSend: number; - newAccountPublickey?: string; - newAccountEvmAddress?: string; -}; diff --git a/packages/hedera-identify-snap/packages/snap/src/utils/config.ts b/packages/hedera-identify-snap/packages/snap/src/utils/config.ts index 0c5208cb..c012f4b2 100644 --- a/packages/hedera-identify-snap/packages/snap/src/utils/config.ts +++ b/packages/hedera-identify-snap/packages/snap/src/utils/config.ts @@ -36,7 +36,6 @@ const emptyAccountState = { index: 0, accountConfig: { identity: { - didMethod: 'did:pkh', vcStore: 'snap', googleUserInfo: {} as GoogleUserInfo, }, @@ -55,6 +54,7 @@ const initialSnapState: IdentitySnapState = { }, snapConfig: { dApp: { + didMethod: 'did:pkh', disablePopups: false, friendlyDapps: [], }, diff --git a/packages/hedera-identify-snap/packages/snap/src/utils/formatUtils.ts b/packages/hedera-identify-snap/packages/snap/src/utils/formatUtils.ts new file mode 100644 index 00000000..bab2cf1c --- /dev/null +++ b/packages/hedera-identify-snap/packages/snap/src/utils/formatUtils.ts @@ -0,0 +1,44 @@ +/*- + * + * Hedera Identify Snap + * + * Copyright (C) 2024 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import { CodecName, MULTICODECS } from '../constants'; + +/** + * Prefix a buffer with a multicodec-packed. + * + * @param {CodecName} multicodec + * @param {Uint8Array} data + * + * @returns {Uint8Array} + */ +export const addMulticodecPrefix = ( + multicodec: CodecName, + data: Uint8Array, +): Uint8Array => { + let prefix; + + if (MULTICODECS[multicodec]) { + prefix = Buffer.from(MULTICODECS[multicodec]); + } else { + throw new Error('multicodec not recognized'); + } + + return Buffer.concat([prefix, data], prefix.length + data.length); +}; diff --git a/packages/hedera-identify-snap/packages/snap/src/utils/init.ts b/packages/hedera-identify-snap/packages/snap/src/utils/init.ts index 02fd30b1..2e2233cb 100644 --- a/packages/hedera-identify-snap/packages/snap/src/utils/init.ts +++ b/packages/hedera-identify-snap/packages/snap/src/utils/init.ts @@ -18,11 +18,10 @@ * */ -import { SnapsGlobalObject } from '@metamask/snaps-types'; -import { heading, text } from '@metamask/snaps-ui'; -import { IdentitySnapState, SnapDialogParams } from '../interfaces'; +import { DialogParams, heading, text } from '@metamask/snaps-sdk'; +import { IdentitySnapState } from '../interfaces'; import { generateCommonPanel, snapDialog } from '../snap/dialog'; -import { initSnapState } from '../snap/state'; +import { initState } from '../snap/state'; /** * Init snap state. @@ -30,11 +29,12 @@ import { initSnapState } from '../snap/state'; * @param snap - Snap. */ export async function init( - snap: SnapsGlobalObject, + origin: string, + network: string, ): Promise { - const dialogParams: SnapDialogParams = { + const dialogParams: DialogParams = { type: 'alert', - content: await generateCommonPanel(origin, [ + content: await generateCommonPanel(origin, network, [ heading('Risks about using Identify Snap'), text( 'Applications do NOT have access to your private keys. You are in control of what VCs and VPs you sign and what you use your DIDs for.', @@ -42,7 +42,7 @@ export async function init( ]), }; - await snapDialog(snap, dialogParams); + await snapDialog(dialogParams); console.log('starting init'); - return await initSnapState(snap); + return await initState(); } diff --git a/packages/hedera-identify-snap/packages/snap/src/utils/keyPair.ts b/packages/hedera-identify-snap/packages/snap/src/utils/keyPair.ts index af345ebf..97431be8 100644 --- a/packages/hedera-identify-snap/packages/snap/src/utils/keyPair.ts +++ b/packages/hedera-identify-snap/packages/snap/src/utils/keyPair.ts @@ -19,6 +19,7 @@ */ import { assertArgument, HDNodeWallet, Mnemonic } from 'ethers'; +import { publicKeyConvert } from 'secp256k1'; import { DEFAULTCOINTYPE } from '../types/constants'; export const generateWallet = async ( @@ -33,15 +34,15 @@ export const generateWallet = async ( }); let nodeWallet = HDNodeWallet.fromMnemonic(Mnemonic.fromEntropy(entropy)); - nodeWallet = await derivePathForWallet( - nodeWallet, - `m/44/${DEFAULTCOINTYPE}/0/0/0`, - ); + nodeWallet = derivePathForWallet(nodeWallet, `m/44/${DEFAULTCOINTYPE}/0/0/0`); return nodeWallet; }; -export const derivePathForWallet = async (node: HDNodeWallet, path: string) => { +export const derivePathForWallet = ( + node: HDNodeWallet, + path: string, +): HDNodeWallet => { const components = path.split('/'); assertArgument( @@ -87,3 +88,17 @@ export const derivePathForWallet = async (node: HDNodeWallet, path: string) => { return result; }; + +export function uint8ArrayToHex(arr: Uint8Array) { + return Buffer.from(arr).toString('hex'); +} + +export function hexToUint8Array(str: string): Uint8Array { + return new Uint8Array(Buffer.from(str, 'hex')); +} + +export function getCompressedPublicKey(publicKey: string): string { + return uint8ArrayToHex( + publicKeyConvert(hexToUint8Array(publicKey.split('0x')[1]), true), + ); +} diff --git a/packages/hedera-identify-snap/packages/snap/src/utils/params.ts b/packages/hedera-identify-snap/packages/snap/src/utils/params.ts index d34cfa75..67b5c4e2 100644 --- a/packages/hedera-identify-snap/packages/snap/src/utils/params.ts +++ b/packages/hedera-identify-snap/packages/snap/src/utils/params.ts @@ -42,11 +42,7 @@ import { isValidProofFormat, isValidVCStore, } from '../types/constants'; -import { - CreateNewHederaAccountRequestParams, - CreateVCRequestParams, - CreateVPRequestParams, -} from '../types/params'; +import { CreateVCRequestParams, CreateVPRequestParams } from '../types/params'; /** * Check whether the the account was imported using private key(external account). @@ -393,112 +389,6 @@ export function isValidSaveVCRequest( } } -/** - * Check validation of when trying to create a new Hedera account. - * - * @param params - Request params. - */ -export function isValidCreateNewHederaAccountParams( - params: unknown, -): asserts params is CreateNewHederaAccountRequestParams { - if (params === null || _.isEmpty(params)) { - console.error( - 'Invalid createNewHederaAccount Params passed. "newAccountPublickey/newAccountEvmAddress" and "hbarAmountToSend" must be passed as parameters', - ); - throw new Error( - 'Invalid createNewHederaAccount Params passed. "newAccountPublickey/newAccountEvmAddress" and "hbarAmountToSend" must be passed as parameters', - ); - } - const parameter = params as CreateNewHederaAccountRequestParams; - - // Check if hbarAmountToSend is valid - if ( - !( - 'hbarAmountToSend' in parameter && - parameter.hbarAmountToSend !== null && - typeof parameter.hbarAmountToSend === 'number' - ) - ) { - console.error( - 'Invalid createNewHederaAccount Params passed. "hbarAmountToSend" is either missing or is not a number', - ); - throw new Error( - 'Invalid createNewHederaAccount Params passed. "hbarAmountToSend" is either missing or is not a number', - ); - } - - // Ensure that either newAccountPublickey or newAccountEvmAddress is passed - if ( - !('newAccountPublickey' in parameter || 'newAccountEvmAddress' in parameter) - ) { - console.error( - 'Invalid createNewHederaAccount Params passed. Either "newAccountPublickey" or "newAccountEvmAddress" must be passed as a parameter', - ); - throw new Error( - 'Invalid createNewHederaAccount Params passed. Either "newAccountPublickey" or "newAccountEvmAddress" must be passed as a parameter', - ); - } - - if ( - 'newAccountPublickey' in parameter && - 'newAccountEvmAddress' in parameter - ) { - // Ensure that both newAccountPublickey and newAccountEvmAddress are not passed in any circumstance - console.error( - 'Invalid createNewHederaAccount Params passed. Please pass either "newAccountPublickey" or "newAccountEvmAddress" but not both', - ); - throw new Error( - 'Invalid createNewHederaAccount Params passed. Please pass either "newAccountPublickey" or "newAccountEvmAddress" but not both', - ); - } - - // Ensure that either newAccountPublickey or newAccountEvmAddress is passed - if ( - !('newAccountPublickey' in parameter || 'newAccountEvmAddress' in parameter) - ) { - console.error( - 'Invalid createNewHederaAccount Params passed. Either "newAccountPublickey" or "newAccountEvmAddress" must be passed as parameters', - ); - throw new Error( - 'Invalid createNewHederaAccount Params passed. Either "newAccountPublickey" or "newAccountEvmAddress" must be passed as parameters', - ); - } - - // Check if newAccountPublickey is valid - if ('newAccountPublickey' in parameter) { - if ( - !( - parameter.newAccountPublickey !== null && - typeof parameter.newAccountPublickey === 'string' - ) - ) { - console.error( - 'Invalid createNewHederaAccount Params passed. "newAccountPublickey" is not in a valid format. It must be a string', - ); - throw new Error( - 'Invalid createNewHederaAccount Params passed. "newAccountPublickey" is not in a valid format. It must be a string', - ); - } - } - - // Check if newAccountEvmAddress is valid - if ('newAccountEvmAddress' in parameter) { - if ( - !( - parameter.newAccountEvmAddress !== null && - typeof parameter.newAccountEvmAddress === 'string' - ) - ) { - console.error( - 'Invalid createNewHederaAccount Params passed. "newAccountEvmAddress" is not in a valid format. It must be a string', - ); - throw new Error( - 'Invalid createNewHederaAccount Params passed. "newAccountEvmAddress" is not in a valid format. It must be a string', - ); - } - } -} - /** * Check Validation of Create VC request. * diff --git a/packages/hedera-identify-snap/packages/snap/src/veramo/accountImport.ts b/packages/hedera-identify-snap/packages/snap/src/veramo/accountImport.ts index 3789f005..87195ca5 100644 --- a/packages/hedera-identify-snap/packages/snap/src/veramo/accountImport.ts +++ b/packages/hedera-identify-snap/packages/snap/src/veramo/accountImport.ts @@ -19,31 +19,28 @@ */ import { MetaMaskInpageProvider } from '@metamask/providers'; -import { SnapsGlobalObject } from '@metamask/snaps-types'; import { IIdentifier, MinimalImportableKey } from '@veramo/core'; -import { isValidHederaAccountInfo } from '../hedera'; +import { getDidKeyIdentifier } from '../did/key/keyDidUtils'; +import { HederaServiceImpl } from '../hedera'; import { getHederaNetwork, validHederaChainID } from '../hedera/config'; import { Account, AccountViaPrivateKey, IdentitySnapState, } from '../interfaces'; -import { requestHederaAccountId } from '../snap/dialog'; import { getCurrentNetwork } from '../snap/network'; import { - getAccountStateByCoinType, getCurrentCoinType, initAccountState, - updateSnapState, + updateState, } from '../snap/state'; import { generateWallet } from '../utils/keyPair'; import { convertChainIdFromHex } from '../utils/network'; import { getHederaAccountIfExists } from '../utils/params'; import { getVeramoAgent } from './agent'; -const getCurrentMetamaskAccount = async ( - metamask: MetaMaskInpageProvider, -): Promise => { +export const getCurrentMetamaskAccount = async (): Promise => { + const metamask = (window as any).ethereum as MetaMaskInpageProvider; const accounts = (await metamask.request({ method: 'eth_requestAccounts', })) as string[]; @@ -61,37 +58,37 @@ const getCurrentMetamaskAccount = async ( * @returns Account. */ export async function veramoImportMetaMaskAccount( - snap: SnapsGlobalObject, + network: string, state: IdentitySnapState, metamask: MetaMaskInpageProvider, evmAddress: string, accountViaPrivateKey?: AccountViaPrivateKey, ): Promise { - const chainId = await getCurrentNetwork(metamask); + const chainId = await getCurrentNetwork(); let privateKey: string; let publicKey: string; let address: string = evmAddress.toLowerCase(); - let addressToUseForDid = ''; + let snapAddress = ''; let hederaAccountId = ''; if (accountViaPrivateKey) { privateKey = accountViaPrivateKey.privateKey; publicKey = accountViaPrivateKey.publicKey; address = accountViaPrivateKey.address.toLowerCase(); - addressToUseForDid = address; + snapAddress = address; if (validHederaChainID(chainId)) { hederaAccountId = accountViaPrivateKey.extraData as string; } } else { // Verify if the user is connected to the correct wallet - const connectedAddress = await getCurrentMetamaskAccount(metamask); + const connectedAddress = await getCurrentMetamaskAccount(); if (address !== connectedAddress) { console.log( - `Please connect to the account '${address}' via Metamask first`, + `You are currently connected to '${connectedAddress}. Please connect to the account '${address}' via Metamask first`, ); throw new Error( - `Please connect to the account '${address}' via Metamask first`, + `You are currently connected to '${connectedAddress}. Please connect to the account '${address}' via Metamask first`, ); } @@ -101,9 +98,9 @@ export async function veramoImportMetaMaskAccount( console.log('Failed to generate snap wallet for DID operations'); throw new Error('Failed to generate snap wallet for DID operations'); } - privateKey = res.privateKey.split('0x')[1]; + privateKey = res.privateKey; publicKey = res.publicKey; - addressToUseForDid = res.address.toLowerCase(); + snapAddress = res.address.toLowerCase(); if (validHederaChainID(chainId)) { hederaAccountId = await getHederaAccountIfExists( @@ -113,7 +110,17 @@ export async function veramoImportMetaMaskAccount( ); if (!hederaAccountId) { - hederaAccountId = await requestHederaAccountId(snap); + const hederaService = new HederaServiceImpl(getHederaNetwork(network)); + const result = await hederaService.getAccountFromEvmAddres(address); + if (!result) { + console.error( + `Could not retrieve hedera account info for address '${address}'. Please make sure this account is activated on Hedera '${getHederaNetwork(network)}'`, + ); + throw new Error( + `Could not retrieve hedera account info for address '${address}'. Please make sure this account is activated on Hedera '${getHederaNetwork(network)}'`, + ); + } + hederaAccountId = result.account; } } } @@ -124,37 +131,20 @@ export async function veramoImportMetaMaskAccount( console.log( `The address ${address} has NOT yet been configured in the Identify Snap. Configuring now...`, ); - await initAccountState(snap, state, coinType, address); - } - - if (validHederaChainID(chainId)) { - if ( - !(await isValidHederaAccountInfo( - address, - hederaAccountId, - getHederaNetwork(chainId), - )) - ) { - console.error( - `Could not retrieve hedera account info using the accountId '${hederaAccountId}'`, - ); - throw new Error( - `Could not retrieve hedera account info using the accountId '${hederaAccountId}'`, - ); - } - - // eslint-disable-next-line - state.accountState[coinType][address].extraData = hederaAccountId; + await initAccountState(state, coinType, address); } + // eslint-disable-next-line + state.accountState[coinType][address].extraData = hederaAccountId; - const accountState = await getAccountStateByCoinType(state, address); - const method = accountState.accountConfig.identity.didMethod; + const method = state.snapConfig.dApp.didMethod; let did = ''; if (method === 'did:pkh') { - did = `did:pkh:eip155:${convertChainIdFromHex( - chainId, - )}:${addressToUseForDid}`; + did = `did:pkh:eip155:${convertChainIdFromHex(chainId)}:${snapAddress}`; + } else if (method === 'did:key') { + did = `did:key:${await getDidKeyIdentifier(publicKey)}`; + } else if (method === 'did:hedera') { + did = `did:hedera:${hederaAccountId}`; } if (!did) { @@ -163,11 +153,15 @@ export async function veramoImportMetaMaskAccount( } // eslint-disable-next-line - state.currentAccount.evmAddress = address; - state.currentAccount.addrToUseForDid = addressToUseForDid; + state.currentAccount.metamaskAddress = address; + state.currentAccount.snapAddress = snapAddress; + state.currentAccount.method = method; + state.currentAccount.privateKey = privateKey; + state.currentAccount.publicKey = publicKey; + state.currentAccount.extraData = hederaAccountId; // Get Veramo agent - const agent = await getVeramoAgent(snap, state); + const agent = await getVeramoAgent(state); const controllerKeyId = `metamask-${address}`; console.log( `Importing using did=${did}, provider=${method}, controllerKeyId=${controllerKeyId}...`, @@ -175,7 +169,6 @@ export async function veramoImportMetaMaskAccount( let identifier: IIdentifier; // Get identifier if it exists - console.log('did: ', did); try { identifier = await agent.didManagerGet({ did, @@ -191,8 +184,8 @@ export async function veramoImportMetaMaskAccount( kid: controllerKeyId, type: 'Secp256k1', kms: 'snap', - privateKeyHex: privateKey, - publicKeyHex: publicKey, + privateKeyHex: privateKey.split('0x')[1], + publicKeyHex: publicKey.split('0x')[1], } as MinimalImportableKey, ], }); @@ -203,14 +196,15 @@ export async function veramoImportMetaMaskAccount( ); } } - await updateSnapState(snap, state); + await updateState(state); console.log('Identifier imported successfully: ', identifier); return { - evmAddress: address, - addrToUseForDid: addressToUseForDid, + metamaskAddress: address, + snapAddress, method, identifier, privateKey, + publicKey, } as Account; } diff --git a/packages/hedera-identify-snap/packages/snap/src/veramo/agent.ts b/packages/hedera-identify-snap/packages/snap/src/veramo/agent.ts index 746d89f7..72635576 100644 --- a/packages/hedera-identify-snap/packages/snap/src/veramo/agent.ts +++ b/packages/hedera-identify-snap/packages/snap/src/veramo/agent.ts @@ -29,7 +29,6 @@ import { } from '@veramo/core'; import { CredentialIssuerEIP712 } from '@veramo/credential-eip712'; -import { SnapsGlobalObject } from '@metamask/snaps-types'; import { CredentialPlugin, W3cMessageHandler } from '@veramo/credential-w3c'; import { JwtMessageHandler } from '@veramo/did-jwt'; import { AbstractIdentifierProvider, DIDManager } from '@veramo/did-manager'; @@ -38,14 +37,15 @@ import { DIDResolverPlugin } from '@veramo/did-resolver'; import { KeyManager } from '@veramo/key-manager'; import { KeyManagementSystem } from '@veramo/kms-local'; import { MessageHandler } from '@veramo/message-handler'; -import { SdrMessageHandler } from '@veramo/selective-disclosure'; import { Resolver } from 'did-resolver'; +import { getDidKeyResolver as keyDidResolver } from '../did/key/keyDidResolver'; import { AbstractDataStore, DataManager, IDataManager, } from '../plugins/veramo/verifiable-creds-manager'; +import { KeyDIDProvider } from '../did/key/keyDidProvider'; import { IdentitySnapState } from '../interfaces'; import { GoogleDriveVCStore } from '../plugins/veramo/google-drive-data-store'; import { @@ -71,16 +71,14 @@ export type Agent = TAgent< * @param state - IdentitySnapState. * @returns Agent. */ -export async function getVeramoAgent( - snap: SnapsGlobalObject, - state: IdentitySnapState, -): Promise { +export async function getVeramoAgent(state: IdentitySnapState): Promise { const didProviders: Record = {}; const vcStorePlugins: Record = {}; didProviders['did:pkh'] = new PkhDIDProvider({ defaultKms: 'snap' }); - vcStorePlugins.snap = new SnapVCStore(snap, state); - vcStorePlugins.googleDrive = new GoogleDriveVCStore(snap, state); + didProviders['did:key'] = new KeyDIDProvider({ defaultKms: 'snap' }); + vcStorePlugins.snap = new SnapVCStore(state); + vcStorePlugins.googleDrive = new GoogleDriveVCStore(state); const agent = createAgent< IKeyManager & @@ -92,34 +90,27 @@ export async function getVeramoAgent( >({ plugins: [ new KeyManager({ - store: new SnapKeyStore(snap, state), + store: new SnapKeyStore(state), kms: { - snap: new KeyManagementSystem(new SnapPrivateKeyStore(snap, state)), + snap: new KeyManagementSystem(new SnapPrivateKeyStore(state)), }, }), new DIDManager({ - store: new SnapDIDStore(snap, state), + store: new SnapDIDStore(state), defaultProvider: 'metamask', providers: didProviders, }), new DIDResolverPlugin({ resolver: new Resolver({ ...getDidPkhResolver(), + ...keyDidResolver(), }), }), new DataManager({ store: vcStorePlugins }), new CredentialPlugin(), new CredentialIssuerEIP712(), - /* new CredentialIssuerLD({ - contextMaps: [LdDefaultContexts], - suites: [new VeramoEcdsaSecp256k1RecoverySignature2020()], - }), */ new MessageHandler({ - messageHandlers: [ - new JwtMessageHandler(), - new W3cMessageHandler(), - new SdrMessageHandler(), - ], + messageHandlers: [new JwtMessageHandler(), new W3cMessageHandler()], }), ], }); diff --git a/packages/hedera-identify-snap/packages/snap/tests/rpc/account/getAccountInfo.spec.disabled.ts b/packages/hedera-identify-snap/packages/snap/tests/rpc/account/getAccountInfo.spec.disabled.ts index f6608b60..0150257e 100644 --- a/packages/hedera-identify-snap/packages/snap/tests/rpc/account/getAccountInfo.spec.disabled.ts +++ b/packages/hedera-identify-snap/packages/snap/tests/rpc/account/getAccountInfo.spec.disabled.ts @@ -21,12 +21,7 @@ /* eslint-disable no-restricted-globals */ import { MetaMaskInpageProvider } from '@metamask/providers'; -import { SnapsGlobalObject } from '@metamask/snaps-types'; -import { - EvmAccountParams, - HederaAccountParams, - PublicAccountInfo, -} from 'src/interfaces'; +import { PublicAccountInfo } from 'src/interfaces'; import { onRpcRequest } from '../../../src'; import { ETH_ADDRESS, @@ -40,16 +35,13 @@ import { getRequestParams } from '../../testUtils/helper'; import { buildMockSnap, SnapMock } from '../../testUtils/snap.mock'; describe('getAccountInfo', () => { - let snapMock: SnapsGlobalObject & SnapMock; + let snapMock: SnapMock; let metamask: MetaMaskInpageProvider; describe('getAccountInfo Ethereum', () => { beforeAll(async () => { snapMock = buildMockSnap(ETH_CHAIN_ID, ETH_ADDRESS); metamask = snapMock as unknown as MetaMaskInpageProvider; - - global.snap = snapMock; - global.ethereum = metamask; }); beforeEach(async () => { @@ -65,8 +57,8 @@ describe('getAccountInfo', () => { origin: 'tests', request: accountInfoRequestParams as any, })) as PublicAccountInfo; - expect(accountInfo.evmAddress).toBe(ETH_ADDRESS); - expect(accountInfo.extraData).toBeUndefined(); + expect(accountInfo.metamaskAddress).toBe(ETH_ADDRESS); + expect(accountInfo.accountID).toBeUndefined(); expect.assertions(2); }); @@ -95,9 +87,6 @@ describe('getAccountInfo', () => { beforeAll(async () => { snapMock = buildMockSnap(HEDERA_CHAIN_ID.testnet, HEDERA_ACCOUNT.address); metamask = snapMock as unknown as MetaMaskInpageProvider; - - global.snap = snapMock; - global.ethereum = metamask; }); it('should set hedera external account info', async () => { @@ -116,11 +105,9 @@ describe('getAccountInfo', () => { origin: 'tests', request: accountInfoRequestParams as any, })) as PublicAccountInfo; - expect(accountInfo.evmAddress).toBe(HEDERA_ACCOUNT.address); + expect(accountInfo.metamaskAddress).toBe(HEDERA_ACCOUNT.address); console.log(JSON.stringify(accountInfo)); - expect((accountInfo.extraData as HederaAccountParams).accountId).toBe( - HEDERA_ACCOUNT.accountId, - ); + expect(accountInfo.accountID).toBe(HEDERA_ACCOUNT.accountId); expect.assertions(2); }); }); @@ -129,9 +116,6 @@ describe('getAccountInfo', () => { beforeAll(async () => { snapMock = buildMockSnap(EVM_ACCOUNT.chainId, EVM_ACCOUNT.address); metamask = snapMock as unknown as MetaMaskInpageProvider; - - global.snap = snapMock; - global.ethereum = metamask; }); // eslint-disable-next-line @@ -156,11 +140,9 @@ describe('getAccountInfo', () => { origin: 'tests', request: accountInfoRequestParams as any, })) as PublicAccountInfo; - expect(accountInfo.evmAddress).toBe(EVM_ACCOUNT.address); + expect(accountInfo.metamaskAddress).toBe(EVM_ACCOUNT.address); console.log(JSON.stringify(accountInfo)); - expect( - (accountInfo.externalAccountInfo as EvmAccountParams).address, - ).toBe(EVM_ACCOUNT.address); + expect(accountInfo.snapAddress).toBe(EVM_ACCOUNT.address); expect.assertions(2); }); }); diff --git a/packages/hedera-identify-snap/packages/snap/tests/rpc/did/getCurrentDIDMethod.spec.disabled.ts b/packages/hedera-identify-snap/packages/snap/tests/rpc/did/getCurrentDIDMethod.spec.disabled.ts index 350feb2a..278b3ecd 100644 --- a/packages/hedera-identify-snap/packages/snap/tests/rpc/did/getCurrentDIDMethod.spec.disabled.ts +++ b/packages/hedera-identify-snap/packages/snap/tests/rpc/did/getCurrentDIDMethod.spec.disabled.ts @@ -21,7 +21,6 @@ /* eslint-disable no-restricted-globals */ import { MetaMaskInpageProvider } from '@metamask/providers'; -import { SnapsGlobalObject } from '@metamask/snaps-types'; import { onRpcRequest } from '../../../src'; import { ETH_ADDRESS, @@ -32,15 +31,12 @@ import { getRequestParams } from '../../testUtils/helper'; import { SnapMock, buildMockSnap } from '../../testUtils/snap.mock'; describe('GetCurrentDIDMethod', () => { - let snapMock: SnapsGlobalObject & SnapMock; + let snapMock: SnapMock; let metamask: MetaMaskInpageProvider; beforeAll(async () => { snapMock = buildMockSnap(ETH_CHAIN_ID, ETH_ADDRESS); metamask = snapMock as unknown as MetaMaskInpageProvider; - - global.snap = snapMock; - global.ethereum = metamask; }); beforeEach(async () => { diff --git a/packages/hedera-identify-snap/packages/snap/tests/rpc/did/resolveDID.spec.disabled.ts b/packages/hedera-identify-snap/packages/snap/tests/rpc/did/resolveDID.spec.disabled.ts index 6eb0101b..a8c28dc1 100644 --- a/packages/hedera-identify-snap/packages/snap/tests/rpc/did/resolveDID.spec.disabled.ts +++ b/packages/hedera-identify-snap/packages/snap/tests/rpc/did/resolveDID.spec.disabled.ts @@ -21,7 +21,6 @@ /* eslint-disable no-restricted-globals */ import { MetaMaskInpageProvider } from '@metamask/providers'; -import { SnapsGlobalObject } from '@metamask/snaps-types'; import { DIDResolutionResult } from 'did-resolver'; import { PublicAccountInfo } from 'src/interfaces'; import { onRpcRequest } from '../../../src'; @@ -35,7 +34,7 @@ import { getRequestParams } from '../../testUtils/helper'; import { SnapMock, buildMockSnap } from '../../testUtils/snap.mock'; describe('resolveDID', () => { - let snapMock: SnapsGlobalObject & SnapMock; + let snapMock: SnapMock; let metamask: MetaMaskInpageProvider; let currentDID = exampleDIDPkh; @@ -43,9 +42,6 @@ describe('resolveDID', () => { beforeAll(async () => { snapMock = buildMockSnap(ETH_CHAIN_ID, ETH_ADDRESS); metamask = snapMock as unknown as MetaMaskInpageProvider; - - global.snap = snapMock; - global.ethereum = metamask; }); beforeEach(async () => { @@ -69,7 +65,7 @@ describe('resolveDID', () => { const resolvedDID = (await onRpcRequest({ origin: 'tests', request: resolveDIDRequestParams as any, - })) as DIDResolutionResult; + })) as any; expect(resolvedDID.didDocument?.id).toBe(currentDID); expect.assertions(1); diff --git a/packages/hedera-identify-snap/packages/snap/tests/rpc/did/switchDIDMethod.spec.disabled.ts b/packages/hedera-identify-snap/packages/snap/tests/rpc/did/switchDIDMethod.spec.disabled.ts index ad570490..a7ceae0a 100644 --- a/packages/hedera-identify-snap/packages/snap/tests/rpc/did/switchDIDMethod.spec.disabled.ts +++ b/packages/hedera-identify-snap/packages/snap/tests/rpc/did/switchDIDMethod.spec.disabled.ts @@ -21,7 +21,6 @@ /* eslint-disable no-restricted-globals */ import { MetaMaskInpageProvider } from '@metamask/providers'; -import { SnapsGlobalObject } from '@metamask/snaps-types'; import { onRpcRequest } from '../../../src'; import { getAccountStateByCoinType } from '../../../src/snap/state'; import { @@ -33,15 +32,12 @@ import { getRequestParams } from '../../testUtils/helper'; import { SnapMock, buildMockSnap } from '../../testUtils/snap.mock'; describe('SwitchDIDMethod', () => { - let snapMock: SnapsGlobalObject & SnapMock; + let snapMock: SnapMock; let metamask: MetaMaskInpageProvider; beforeAll(async () => { snapMock = buildMockSnap(ETH_CHAIN_ID, ETH_ADDRESS); metamask = snapMock as unknown as MetaMaskInpageProvider; - - global.snap = snapMock; - global.ethereum = metamask; }); beforeEach(async () => { @@ -55,7 +51,7 @@ describe('SwitchDIDMethod', () => { it.skip('should change snap state when switch to did:pkh methods', async () => { const snapState = getDefaultSnapState(); const accountType = await getAccountStateByCoinType(snapState, ETH_ADDRESS); - accountType.accountConfig.identity.didMethod = 'did:key'; + snapState.snapConfig.dApp.didMethod = 'did:key'; snapState.accountState['60'][ETH_ADDRESS] = accountType; @@ -106,7 +102,7 @@ describe('SwitchDIDMethod', () => { const snapState = getDefaultSnapState(); const accountType = await getAccountStateByCoinType(snapState, ETH_ADDRESS); - accountType.accountConfig.identity.didMethod = 'did:key'; + snapState.snapConfig.dApp.didMethod = 'did:key'; snapState.accountState['60'][ETH_ADDRESS] = accountType; diff --git a/packages/hedera-identify-snap/packages/snap/tests/rpc/gdrive/configureGoogleAccount.spec.ts b/packages/hedera-identify-snap/packages/snap/tests/rpc/gdrive/configureGoogleAccount.spec.ts index 744be8ca..bce44b9a 100644 --- a/packages/hedera-identify-snap/packages/snap/tests/rpc/gdrive/configureGoogleAccount.spec.ts +++ b/packages/hedera-identify-snap/packages/snap/tests/rpc/gdrive/configureGoogleAccount.spec.ts @@ -20,7 +20,6 @@ /* eslint-disable */ import { MetaMaskInpageProvider } from '@metamask/providers'; -import { SnapsGlobalObject } from '@metamask/snaps-types'; import { GoogleToken, IdentitySnapParams } from '../../../src/interfaces'; import { SnapMock } from '../../testUtils/snap.mock'; @@ -28,7 +27,7 @@ describe('ConfigureGoogleAccount', () => { let identitySnapParams: IdentitySnapParams; let googleToken: GoogleToken; let snapState: GoogleToken; - let snapMock: SnapsGlobalObject & SnapMock; + let snapMock: SnapMock; let metamask: MetaMaskInpageProvider; it('should return true if configured properly', async () => {}); diff --git a/packages/hedera-identify-snap/packages/snap/tests/rpc/hedera/connectHederaAccount.spec.ts b/packages/hedera-identify-snap/packages/snap/tests/rpc/hedera/connectHederaAccount.spec.ts index 364351d8..ab6316b5 100644 --- a/packages/hedera-identify-snap/packages/snap/tests/rpc/hedera/connectHederaAccount.spec.ts +++ b/packages/hedera-identify-snap/packages/snap/tests/rpc/hedera/connectHederaAccount.spec.ts @@ -20,14 +20,13 @@ /* eslint-disable */ import { MetaMaskInpageProvider } from '@metamask/providers'; -import { SnapsGlobalObject } from '@metamask/snaps-types'; import { IdentitySnapParams, IdentitySnapState } from '../../../src/interfaces'; import { SnapMock } from '../../testUtils/snap.mock'; describe('ConnectHederaAccount', () => { let identitySnapParams: IdentitySnapParams; let snapState: IdentitySnapState; - let snapMock: SnapsGlobalObject & SnapMock; + let snapMock: SnapMock; let metamask: MetaMaskInpageProvider; let accountId: '0.0.15215'; diff --git a/packages/hedera-identify-snap/packages/snap/tests/rpc/snap/togglePopups.spec.ts b/packages/hedera-identify-snap/packages/snap/tests/rpc/snap/togglePopups.spec.ts index 28160f48..ae520cdc 100644 --- a/packages/hedera-identify-snap/packages/snap/tests/rpc/snap/togglePopups.spec.ts +++ b/packages/hedera-identify-snap/packages/snap/tests/rpc/snap/togglePopups.spec.ts @@ -20,14 +20,13 @@ /* eslint-disable */ import { MetaMaskInpageProvider } from '@metamask/providers'; -import { SnapsGlobalObject } from '@metamask/snaps-types'; import { IdentitySnapParams, IdentitySnapState } from '../../../src/interfaces'; import { SnapMock } from '../../testUtils/snap.mock'; describe('TogglePopups', () => { let identitySnapParams: IdentitySnapParams; let snapState: IdentitySnapState; - let snapMock: SnapsGlobalObject & SnapMock; + let snapMock: SnapMock; let metamask: MetaMaskInpageProvider; it('should return true', async () => {}); diff --git a/packages/hedera-identify-snap/packages/snap/tests/rpc/vc/createVC.spec.disabled.ts b/packages/hedera-identify-snap/packages/snap/tests/rpc/vc/createVC.spec.disabled.ts index 113ce267..497bdbdb 100644 --- a/packages/hedera-identify-snap/packages/snap/tests/rpc/vc/createVC.spec.disabled.ts +++ b/packages/hedera-identify-snap/packages/snap/tests/rpc/vc/createVC.spec.disabled.ts @@ -21,7 +21,6 @@ /* eslint-disable no-restricted-globals */ import { MetaMaskInpageProvider } from '@metamask/providers'; -import { SnapsGlobalObject } from '@metamask/snaps-types'; import { CreateVCResponseResult } from 'src/types/params'; import { onRpcRequest } from '../../../src'; import { getDefaultSnapState } from '../../testUtils/constants'; @@ -29,15 +28,12 @@ import { getRequestParams } from '../../testUtils/helper'; import { createMockSnap, SnapMock } from '../../testUtils/snap.mock'; describe('createVC', () => { - let snapMock: SnapsGlobalObject & SnapMock; + let snapMock: SnapMock; let metamask: MetaMaskInpageProvider; beforeAll(async () => { snapMock = createMockSnap(); metamask = snapMock as unknown as MetaMaskInpageProvider; - - global.snap = snapMock; - global.ethereum = metamask; }); beforeEach(async () => { diff --git a/packages/hedera-identify-snap/packages/snap/tests/rpc/vc/createVP.spec.disabled.ts b/packages/hedera-identify-snap/packages/snap/tests/rpc/vc/createVP.spec.disabled.ts index c95dcbad..88e3a222 100644 --- a/packages/hedera-identify-snap/packages/snap/tests/rpc/vc/createVP.spec.disabled.ts +++ b/packages/hedera-identify-snap/packages/snap/tests/rpc/vc/createVP.spec.disabled.ts @@ -21,7 +21,6 @@ /* eslint-disable no-restricted-globals */ import { MetaMaskInpageProvider } from '@metamask/providers'; -import { SnapsGlobalObject } from '@metamask/snaps-types'; import { VerifiablePresentation } from '@veramo/core'; import { CreateVCResponseResult } from 'src/types/params'; import { onRpcRequest } from '../../../src'; @@ -34,7 +33,7 @@ import { getRequestParams } from '../../testUtils/helper'; import { SnapMock, buildMockSnap } from '../../testUtils/snap.mock'; describe('createVP', () => { - let snapMock: SnapsGlobalObject & SnapMock; + let snapMock: SnapMock; let metamask: MetaMaskInpageProvider; const vcIds: string[] = []; @@ -42,9 +41,6 @@ describe('createVP', () => { beforeAll(async () => { snapMock = buildMockSnap(ETH_CHAIN_ID, ETH_ADDRESS); metamask = snapMock as unknown as MetaMaskInpageProvider; - - global.snap = snapMock; - global.ethereum = metamask; }); beforeEach(async () => { diff --git a/packages/hedera-identify-snap/packages/snap/tests/rpc/vc/deleteAllVCs.spec.disabled.ts b/packages/hedera-identify-snap/packages/snap/tests/rpc/vc/deleteAllVCs.spec.disabled.ts index ce489da7..500fb253 100644 --- a/packages/hedera-identify-snap/packages/snap/tests/rpc/vc/deleteAllVCs.spec.disabled.ts +++ b/packages/hedera-identify-snap/packages/snap/tests/rpc/vc/deleteAllVCs.spec.disabled.ts @@ -21,22 +21,18 @@ /* eslint-disable no-restricted-globals */ import { MetaMaskInpageProvider } from '@metamask/providers'; -import { SnapsGlobalObject } from '@metamask/snaps-types'; import { onRpcRequest } from '../../../src'; import { getDefaultSnapState } from '../../testUtils/constants'; import { getRequestParams } from '../../testUtils/helper'; import { createMockSnap, SnapMock } from '../../testUtils/snap.mock'; describe('delete all VCs', () => { - let snapMock: SnapsGlobalObject & SnapMock; + let snapMock: SnapMock; let metamask: MetaMaskInpageProvider; beforeAll(async () => { snapMock = createMockSnap(); metamask = snapMock as unknown as MetaMaskInpageProvider; - - global.snap = snapMock; - global.ethereum = metamask; }); beforeEach(async () => { diff --git a/packages/hedera-identify-snap/packages/snap/tests/rpc/vc/getVCs.spec.disabled.ts b/packages/hedera-identify-snap/packages/snap/tests/rpc/vc/getVCs.spec.disabled.ts index 91ce01d1..5ee97197 100644 --- a/packages/hedera-identify-snap/packages/snap/tests/rpc/vc/getVCs.spec.disabled.ts +++ b/packages/hedera-identify-snap/packages/snap/tests/rpc/vc/getVCs.spec.disabled.ts @@ -21,7 +21,6 @@ /* eslint-disable no-restricted-globals */ import { MetaMaskInpageProvider } from '@metamask/providers'; -import { SnapsGlobalObject } from '@metamask/snaps-types'; import { IDataManagerQueryResult } from 'src/plugins/veramo/verifiable-creds-manager'; import { CreateVCResponseResult } from 'src/types/params'; import { onRpcRequest } from '../../../src'; @@ -31,15 +30,12 @@ import { getDefaultSnapState } from '../../testUtils/constants'; import { createMockSnap, SnapMock } from '../../testUtils/snap.mock'; describe('getVCs', () => { - let snapMock: SnapsGlobalObject & SnapMock; + let snapMock: SnapMock; let metamask: MetaMaskInpageProvider; beforeAll(async () => { snapMock = createMockSnap(); metamask = snapMock as unknown as MetaMaskInpageProvider; - - global.snap = snapMock; - global.ethereum = metamask; }); beforeEach(async () => { diff --git a/packages/hedera-identify-snap/packages/snap/tests/rpc/vc/removeVC.spec.disabled.ts b/packages/hedera-identify-snap/packages/snap/tests/rpc/vc/removeVC.spec.disabled.ts index 32d720a2..d13eb677 100644 --- a/packages/hedera-identify-snap/packages/snap/tests/rpc/vc/removeVC.spec.disabled.ts +++ b/packages/hedera-identify-snap/packages/snap/tests/rpc/vc/removeVC.spec.disabled.ts @@ -21,7 +21,6 @@ /* eslint-disable no-restricted-globals */ import { MetaMaskInpageProvider } from '@metamask/providers'; -import { SnapsGlobalObject } from '@metamask/snaps-types'; import { W3CVerifiableCredential } from '@veramo/core'; import { IDataManagerDeleteResult, @@ -38,7 +37,7 @@ import { getRequestParams } from '../../testUtils/helper'; import { SnapMock, buildMockSnap } from '../../testUtils/snap.mock'; describe('RemoveVC', () => { - let snapMock: SnapsGlobalObject & SnapMock; + let snapMock: SnapMock; let metamask: MetaMaskInpageProvider; const vcs: W3CVerifiableCredential[] = []; @@ -46,9 +45,6 @@ describe('RemoveVC', () => { beforeAll(async () => { snapMock = buildMockSnap(ETH_CHAIN_ID, ETH_ADDRESS); metamask = snapMock as unknown as MetaMaskInpageProvider; - - global.snap = snapMock; - global.ethereum = metamask; }); beforeEach(async () => { diff --git a/packages/hedera-identify-snap/packages/snap/tests/rpc/vc/saveVC.spec.disabled.ts b/packages/hedera-identify-snap/packages/snap/tests/rpc/vc/saveVC.spec.disabled.ts index 579e0221..f879f15c 100644 --- a/packages/hedera-identify-snap/packages/snap/tests/rpc/vc/saveVC.spec.disabled.ts +++ b/packages/hedera-identify-snap/packages/snap/tests/rpc/vc/saveVC.spec.disabled.ts @@ -20,22 +20,18 @@ /* eslint-disable */ import { MetaMaskInpageProvider } from '@metamask/providers'; -import { SnapsGlobalObject } from '@metamask/snaps-types'; import { onRpcRequest } from '../../../src'; import { getRequestParams } from '../../../tests/testUtils/helper'; import { getDefaultSnapState } from '../../testUtils/constants'; import { createMockSnap, SnapMock } from '../../testUtils/snap.mock'; describe('saveVC', () => { - let snapMock: SnapsGlobalObject & SnapMock; + let snapMock: SnapMock; let metamask: MetaMaskInpageProvider; beforeAll(async () => { snapMock = createMockSnap(); metamask = snapMock as unknown as MetaMaskInpageProvider; - - global.snap = snapMock; - global.ethereum = metamask; }); beforeEach(async () => { diff --git a/packages/hedera-identify-snap/packages/snap/tests/rpc/vc/syncGoogleVCs.spec.ts b/packages/hedera-identify-snap/packages/snap/tests/rpc/vc/syncGoogleVCs.spec.ts index b7c5e2c9..d0c4af7e 100644 --- a/packages/hedera-identify-snap/packages/snap/tests/rpc/vc/syncGoogleVCs.spec.ts +++ b/packages/hedera-identify-snap/packages/snap/tests/rpc/vc/syncGoogleVCs.spec.ts @@ -20,14 +20,13 @@ /* eslint-disable */ import { MetaMaskInpageProvider } from '@metamask/providers'; -import { SnapsGlobalObject } from '@metamask/snaps-types'; import { IdentitySnapParams, IdentitySnapState } from '../../../src/interfaces'; import { SnapMock } from '../../testUtils/snap.mock'; describe('SyncGoogleVCs', () => { let identitySnapParams: IdentitySnapParams; let snapState: IdentitySnapState; - let snapMock: SnapsGlobalObject & SnapMock; + let snapMock: SnapMock; let metamask: MetaMaskInpageProvider; it('should return true', async () => {}); diff --git a/packages/hedera-identify-snap/packages/snap/tests/rpc/vc/verifyVC.spec.disabled.ts b/packages/hedera-identify-snap/packages/snap/tests/rpc/vc/verifyVC.spec.disabled.ts index 1ba38a19..0aff8771 100644 --- a/packages/hedera-identify-snap/packages/snap/tests/rpc/vc/verifyVC.spec.disabled.ts +++ b/packages/hedera-identify-snap/packages/snap/tests/rpc/vc/verifyVC.spec.disabled.ts @@ -21,7 +21,6 @@ /* eslint-disable no-restricted-globals */ import { MetaMaskInpageProvider } from '@metamask/providers'; -import { SnapsGlobalObject } from '@metamask/snaps-types'; import { W3CVerifiableCredential } from '@veramo/core'; import { IDataManagerQueryResult } from 'src/plugins/veramo/verifiable-creds-manager'; import { onRpcRequest } from '../../../src'; @@ -30,7 +29,7 @@ import { getRequestParams } from '../../testUtils/helper'; import { createMockSnap, SnapMock } from '../../testUtils/snap.mock'; describe('VerifyVC', () => { - let snapMock: SnapsGlobalObject & SnapMock; + let snapMock: SnapMock; let metamask: MetaMaskInpageProvider; let credentials: W3CVerifiableCredential[]; @@ -38,9 +37,6 @@ describe('VerifyVC', () => { beforeAll(async () => { snapMock = createMockSnap(); metamask = snapMock as unknown as MetaMaskInpageProvider; - - global.snap = snapMock; - global.ethereum = metamask; }); beforeEach(async () => { diff --git a/packages/hedera-identify-snap/packages/snap/tests/rpc/vc/verifyVP.spec.disabled.ts b/packages/hedera-identify-snap/packages/snap/tests/rpc/vc/verifyVP.spec.disabled.ts index 884519a4..86eded22 100644 --- a/packages/hedera-identify-snap/packages/snap/tests/rpc/vc/verifyVP.spec.disabled.ts +++ b/packages/hedera-identify-snap/packages/snap/tests/rpc/vc/verifyVP.spec.disabled.ts @@ -21,7 +21,6 @@ /* eslint-disable no-restricted-globals */ import { MetaMaskInpageProvider } from '@metamask/providers'; -import { SnapsGlobalObject } from '@metamask/snaps-types'; import { VerifiablePresentation } from '@veramo/core'; import { CreateVCResponseResult } from 'src/types/params'; import { buildMockSnap, SnapMock } from '../../testUtils/snap.mock'; @@ -35,7 +34,7 @@ import { import { getRequestParams } from '../../testUtils/helper'; describe('VerifyVP', () => { - let snapMock: SnapsGlobalObject & SnapMock; + let snapMock: SnapMock; let metamask: MetaMaskInpageProvider; const vcIds: string[] = []; @@ -44,9 +43,6 @@ describe('VerifyVP', () => { beforeAll(async () => { snapMock = buildMockSnap(ETH_CHAIN_ID, ETH_ADDRESS); metamask = snapMock as unknown as MetaMaskInpageProvider; - - global.snap = snapMock; - global.ethereum = metamask; }); beforeEach(async () => { diff --git a/packages/hedera-identify-snap/packages/snap/tests/testUtils/constants.ts b/packages/hedera-identify-snap/packages/snap/tests/testUtils/constants.ts index b46d3e97..d3891bbb 100644 --- a/packages/hedera-identify-snap/packages/snap/tests/testUtils/constants.ts +++ b/packages/hedera-identify-snap/packages/snap/tests/testUtils/constants.ts @@ -19,7 +19,7 @@ */ import cloneDeep from 'lodash.clonedeep'; -import { IdentitySnapState } from '../../src/interfaces'; +import { Account, IdentitySnapState } from '../../src/interfaces'; import { getEmptyAccountState } from '../../src/utils/config'; export const privateKey = @@ -60,12 +60,12 @@ export const exampleDIDPkh = `did:pkh:eip155:4:${ETH_ADDRESS}`; const defaultSnapState: IdentitySnapState = { currentAccount: { - evmAddress: ETH_ADDRESS, + metamaskAddress: ETH_ADDRESS, method: '', identifier: {} as any, privateKey: '', publicKey: '', - }, + } as Account, accountState: { '60': { '0xf49d65c80c3d2d98231654513b2da4652f09c9fe': getEmptyAccountState(), @@ -73,6 +73,7 @@ const defaultSnapState: IdentitySnapState = { }, snapConfig: { dApp: { + didMethod: 'did:pkh', disablePopups: false, friendlyDapps: [], }, diff --git a/packages/hedera-identify-snap/packages/snap/tests/testUtils/snap.mock.ts b/packages/hedera-identify-snap/packages/snap/tests/testUtils/snap.mock.ts index cffc09f6..4a64f09a 100644 --- a/packages/hedera-identify-snap/packages/snap/tests/testUtils/snap.mock.ts +++ b/packages/hedera-identify-snap/packages/snap/tests/testUtils/snap.mock.ts @@ -21,13 +21,12 @@ /* eslint-disable */ import { BIP44CoinTypeNode } from '@metamask/key-tree'; -import { RequestArguments } from '@metamask/providers/dist/BaseProvider'; -import { Maybe } from '@metamask/providers/dist/utils'; -import { SnapsGlobalObject } from '@metamask/snaps-types'; -import { providers, Wallet } from 'ethers'; +import { AlchemyProvider, Provider, Wallet } from 'ethers'; import { IdentitySnapState } from '../../src/interfaces'; import { ETH_ADDRESS, mnemonic, privateKey } from './constants'; +import { RequestArguments } from '@metamask/providers'; +import { Maybe } from '@metamask/providers/dist/utils.cjs'; type ISnapMock = { request(args: RequestArguments): Promise>; @@ -69,15 +68,15 @@ export class SnapMock implements ISnapMock { // eslint-disable-next-line @typescript-eslint/no-explicit-any private async snapEthCall(data: any[]): Promise { const apiKey = 'NRFBwig_CLVL0WnQLY3dUo8YkPmW-7iN'; - const provider = new providers.AlchemyProvider('goerli', apiKey); + const provider = new AlchemyProvider('goerli', apiKey); // eslint-disable-next-line @typescript-eslint/no-unsafe-argument - return provider.call(data[0], data[1]); + return provider.call(data[0]); } // eslint-disable-next-line @typescript-eslint/no-explicit-any private async snapEthLogs(data: any[]): Promise { const apiKey = 'NRFBwig_CLVL0WnQLY3dUo8YkPmW-7iN'; - const provider = new providers.AlchemyProvider('goerli', apiKey); + const provider = new AlchemyProvider('goerli', apiKey); // eslint-disable-next-line @typescript-eslint/no-unsafe-argument return provider.getLogs(data[0]); } @@ -122,7 +121,7 @@ export class SnapMock implements ISnapMock { delete types.EIP712Domain; // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, no-underscore-dangle - return this.snap._signTypedData(domain, types, message); + return this.snap.signTypedData(domain, types, message); }), }; @@ -143,8 +142,8 @@ export class SnapMock implements ISnapMock { * * @returns {SnapsGlobalObject & SnapMock} SnapMock */ -export function createMockSnap(): SnapsGlobalObject & SnapMock { - return new SnapMock() as SnapsGlobalObject & SnapMock; +export function createMockSnap(): SnapMock { + return new SnapMock() as SnapMock; } /** @@ -152,11 +151,8 @@ export function createMockSnap(): SnapsGlobalObject & SnapMock { * * @returns {SnapsGlobalObject & SnapMock} SnapMock */ -export function buildMockSnap( - chainId: string, - address: string, -): SnapsGlobalObject & SnapMock { - let snapMock = new SnapMock() as SnapsGlobalObject & SnapMock; +export function buildMockSnap(chainId: string, address: string): SnapMock { + let snapMock = new SnapMock() as SnapMock; snapMock.rpcMocks.eth_requestAccounts.mockResolvedValue([address]); snapMock.rpcMocks.eth_chainId.mockResolvedValue(chainId); return snapMock; diff --git a/packages/hedera-identify-snap/packages/snap/tests/testUtils/wallet.mock.ts b/packages/hedera-identify-snap/packages/snap/tests/testUtils/wallet.mock.ts index 05b97915..8c28d3bd 100644 --- a/packages/hedera-identify-snap/packages/snap/tests/testUtils/wallet.mock.ts +++ b/packages/hedera-identify-snap/packages/snap/tests/testUtils/wallet.mock.ts @@ -17,13 +17,11 @@ * limitations under the License. * */ - -import { RequestArguments } from '@metamask/providers/dist/BaseProvider'; -import { Maybe } from '@metamask/providers/dist/utils'; -import { SnapsGlobalObject } from '@metamask/snaps-types'; import { Wallet } from 'ethers'; import { IdentitySnapState } from '../../src/interfaces'; import { ETH_ADDRESS, privateKey, signedMsg } from './constants'; +import { RequestArguments } from '@metamask/providers'; +import { Maybe } from '@metamask/providers/dist/utils.cjs'; type IWalletMock = { request(args: RequestArguments): Promise>; @@ -93,6 +91,6 @@ export class WalletMock implements IWalletMock { * * @returns Wallet mock. */ -export function createMockWallet(): SnapsGlobalObject & WalletMock { - return new WalletMock() as SnapsGlobalObject & WalletMock; +export function createMockWallet(): WalletMock { + return new WalletMock() as WalletMock; } diff --git a/packages/hedera-identify-snap/packages/snap/tests/utils/init.spec.disabled.ts b/packages/hedera-identify-snap/packages/snap/tests/utils/init.spec.disabled.ts index b8108784..7c449c80 100644 --- a/packages/hedera-identify-snap/packages/snap/tests/utils/init.spec.disabled.ts +++ b/packages/hedera-identify-snap/packages/snap/tests/utils/init.spec.disabled.ts @@ -20,13 +20,12 @@ /* eslint-disable */ -import { SnapsGlobalObject } from '@metamask/snaps-types'; import { getInitialSnapState } from '../../src/utils/config'; import { init } from '../../src/utils/init'; import { createMockWallet, WalletMock } from '../testUtils/wallet.mock'; describe.skip('RPC handler [init]', () => { - let walletMock: SnapsGlobalObject & WalletMock; + let walletMock: WalletMock; beforeEach(() => { walletMock = createMockWallet(); @@ -36,7 +35,7 @@ describe.skip('RPC handler [init]', () => { const initialState = getInitialSnapState(); walletMock.rpcMocks.snap_confirm.mockReturnValueOnce(true); - await expect(init(walletMock)).resolves.toEqual(initialState); + await expect(init('test-origin', 'testnet')).resolves.toEqual(initialState); expect(walletMock.rpcMocks.snap_manageState).toHaveBeenCalledWith( 'update', initialState, @@ -48,7 +47,7 @@ describe.skip('RPC handler [init]', () => { it('should fail for rejected terms and conditions', async function () { walletMock.rpcMocks.snap_confirm.mockReturnValueOnce(false); - await expect(init(walletMock)).rejects.toThrow( + await expect(init('test-origin', 'testnet')).rejects.toThrow( new Error('User did not accept terms and conditions!'), ); diff --git a/packages/hedera-identify-snap/packages/snap/tests/utils/stateUtils.spec.disabled.ts b/packages/hedera-identify-snap/packages/snap/tests/utils/stateUtils.spec.disabled.ts index 1addbb85..08f7e564 100644 --- a/packages/hedera-identify-snap/packages/snap/tests/utils/stateUtils.spec.disabled.ts +++ b/packages/hedera-identify-snap/packages/snap/tests/utils/stateUtils.spec.disabled.ts @@ -20,20 +20,19 @@ /* eslint-disable */ -import { SnapsGlobalObject } from '@metamask/snaps-types'; +import { DEFAULTCOINTYPE } from 'src/types/constants'; import { - getSnapStateUnchecked, + getStateUnchecked, initAccountState, - initSnapState, - updateSnapState, + initState, + updateState, } from '../../src/snap/state'; import { getInitialSnapState } from '../../src/utils/config'; import { ETH_ADDRESS, getDefaultSnapState } from '../testUtils/constants'; import { WalletMock, createMockWallet } from '../testUtils/wallet.mock'; -import { DEFAULTCOINTYPE } from 'src/types/constants'; describe.skip('Utils [state]', () => { - let walletMock: SnapsGlobalObject & WalletMock; + let walletMock: WalletMock; beforeEach(() => { walletMock = createMockWallet(); @@ -43,9 +42,7 @@ describe.skip('Utils [state]', () => { it('should succeed updating snap state with default state', async () => { const initialState = getDefaultSnapState(); - await expect( - updateSnapState(walletMock, initialState), - ).resolves.not.toThrow(); + await expect(updateState(initialState)).resolves.not.toThrow(); expect(walletMock.rpcMocks.snap_manageState).toHaveBeenCalledWith( 'update', @@ -60,7 +57,7 @@ describe.skip('Utils [state]', () => { await expect( // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any - updateSnapState(walletMock, emptyState as any), + updateState(emptyState as any), ).resolves.not.toThrow(); expect(walletMock.rpcMocks.snap_manageState).toHaveBeenCalledWith( @@ -74,7 +71,7 @@ describe.skip('Utils [state]', () => { describe('getSnapStateUnchecked', () => { it('should return null if state is not initialized', async () => { - await expect(getSnapStateUnchecked(walletMock)).resolves.toEqual(null); + await expect(getStateUnchecked()).resolves.toEqual(null); expect.assertions(1); }); @@ -83,9 +80,7 @@ describe.skip('Utils [state]', () => { const initialState = getDefaultSnapState(); walletMock.rpcMocks.snap_manageState.mockReturnValueOnce(initialState); - await expect(getSnapStateUnchecked(walletMock)).resolves.toEqual( - initialState, - ); + await expect(getStateUnchecked()).resolves.toEqual(initialState); expect.assertions(1); }); @@ -95,7 +90,7 @@ describe.skip('Utils [state]', () => { it('should succeed initializing snap state', async () => { const initialState = getInitialSnapState(); - await expect(initSnapState(walletMock)).resolves.toEqual(initialState); + await expect(initState()).resolves.toEqual(initialState); expect(walletMock.rpcMocks.snap_manageState).toHaveBeenCalledWith( 'update', @@ -113,12 +108,7 @@ describe.skip('Utils [state]', () => { // defaultState.accountState[address].publicKey = publicKey; await expect( - initAccountState( - walletMock, - initialState, - DEFAULTCOINTYPE.toString(), - ETH_ADDRESS, - ), + initAccountState(initialState, DEFAULTCOINTYPE.toString(), ETH_ADDRESS), ).resolves.not.toThrow(); expect(walletMock.rpcMocks.snap_manageState).toHaveBeenCalledWith( diff --git a/packages/hedera-identify-snap/yarn.lock b/packages/hedera-identify-snap/yarn.lock index dac351bc..6c9cd77a 100644 --- a/packages/hedera-identify-snap/yarn.lock +++ b/packages/hedera-identify-snap/yarn.lock @@ -1863,17 +1863,6 @@ __metadata: languageName: node linkType: hard -"@digitalcredentials/vc@npm:^5.0.0": - version: 5.0.0 - resolution: "@digitalcredentials/vc@npm:5.0.0" - dependencies: - "@digitalcredentials/jsonld": ^5.2.1 - "@digitalcredentials/jsonld-signatures": ^9.3.1 - credentials-context: ^2.0.0 - checksum: 8b4d9807ab89396f5aeff836c485128a769b904ba49077c8e1925008c69606d23029af8cae292ffb35278c4aeb92c4ba284c6c01f0dd00b092dc1dd388e14340 - languageName: node - linkType: hard - "@digitalcredentials/vc@npm:^6.0.0": version: 6.0.1 resolution: "@digitalcredentials/vc@npm:6.0.1" @@ -2037,17 +2026,6 @@ __metadata: languageName: node linkType: hard -"@es-joy/jsdoccomment@npm:~0.41.0": - version: 0.41.0 - resolution: "@es-joy/jsdoccomment@npm:0.41.0" - dependencies: - comment-parser: 1.4.1 - esquery: ^1.5.0 - jsdoc-type-pratt-parser: ~4.0.0 - checksum: cfe0714027ff8fa82dad8c84f75af3f6df9d6797d60c289b8d3c259c5375c134bd5ca630beba0daed3adceef01a74f19e05052018f6b66ad6a4f483adf599c39 - languageName: node - linkType: hard - "@es-joy/jsdoccomment@npm:~0.48.0": version: 0.48.0 resolution: "@es-joy/jsdoccomment@npm:0.48.0" @@ -2070,7 +2048,7 @@ __metadata: languageName: node linkType: hard -"@eslint-community/regexpp@npm:^4.11.0, @eslint-community/regexpp@npm:^4.4.0, @eslint-community/regexpp@npm:^4.6.1": +"@eslint-community/regexpp@npm:^4.11.0, @eslint-community/regexpp@npm:^4.4.0": version: 4.11.1 resolution: "@eslint-community/regexpp@npm:4.11.1" checksum: 6986685529d30e33c2640973c3d8e7ddd31bef3cc8cb10ad54ddc1dea12680779a2c23a45562aa1462c488137a3570e672d122fac7da22d82294382d915cec70 @@ -2094,7 +2072,7 @@ __metadata: languageName: node linkType: hard -"@eslint/eslintrc@npm:^2.0.2, @eslint/eslintrc@npm:^2.1.4": +"@eslint/eslintrc@npm:^2.0.2": version: 2.1.4 resolution: "@eslint/eslintrc@npm:2.1.4" dependencies: @@ -2135,13 +2113,6 @@ __metadata: languageName: node linkType: hard -"@eslint/js@npm:8.57.1": - version: 8.57.1 - resolution: "@eslint/js@npm:8.57.1" - checksum: 2afb77454c06e8316793d2e8e79a0154854d35e6782a1217da274ca60b5044d2c69d6091155234ed0551a1e408f86f09dd4ece02752c59568fa403e60611e880 - languageName: node - linkType: hard - "@eslint/js@npm:^9.10.0": version: 9.12.0 resolution: "@eslint/js@npm:9.12.0" @@ -2971,25 +2942,6 @@ __metadata: "@hashgraph/hedera-identify-snap-monorepo@workspace:.": version: 0.0.0-use.local resolution: "@hashgraph/hedera-identify-snap-monorepo@workspace:." - dependencies: - "@metamask/eslint-config": ^11.1.0 - "@metamask/eslint-config-jest": ^11.1.0 - "@metamask/eslint-config-nodejs": ^11.1.0 - "@metamask/eslint-config-typescript": ^11.1.0 - "@typescript-eslint/eslint-plugin": ^5.57.1 - "@typescript-eslint/parser": ^5.57.1 - "@yarnpkg/plugin-workspace-tools": ^4.1.0 - eslint: ^8.38.0 - eslint-config-prettier: ^9.0.0 - eslint-plugin-import: ^2.28.1 - eslint-plugin-jest: ^27.4.0 - eslint-plugin-jsdoc: ^46.8.1 - eslint-plugin-node: ^11.1.0 - eslint-plugin-prettier: ^4.2.1 - prettier: ^3.0.3 - prettier-plugin-packagejson: ^2.4.5 - protobufjs: ^7.4.0 - typescript: ^5.2.2 languageName: unknown linkType: soft @@ -3013,16 +2965,15 @@ __metadata: "@metamask/snaps-cli": ^6.3.1 "@metamask/snaps-jest": ^8.3.0 "@metamask/snaps-sdk": ^6.3.0 - "@metamask/snaps-ui": ^3.1.0 "@types/jest": ^29.5.12 "@types/jsonpath": ^0.2.4 "@types/lodash.clonedeep": ^4.5.9 + "@types/secp256k1": ^4.0.6 "@types/uuid": ^10.0.0 "@typescript-eslint/eslint-plugin": 5.62.0 "@typescript-eslint/parser": 5.62.0 "@veramo/core": 5.1.2 "@veramo/credential-eip712": ^6.0.0 - "@veramo/credential-ld": 5.1.2 "@veramo/credential-w3c": 5.1.2 "@veramo/did-jwt": 5.1.2 "@veramo/did-manager": 5.1.2 @@ -3031,7 +2982,6 @@ __metadata: "@veramo/key-manager": 5.1.2 "@veramo/kms-local": 5.1.2 "@veramo/message-handler": 5.1.2 - "@veramo/selective-disclosure": 5.1.2 bignumber.js: ^9.1.2 caip: ^1.1.1 did-jwt-vc: ^3.1.3 @@ -3049,12 +2999,14 @@ __metadata: jest: ^29.7.0 jest-junit: ^16.0.0 jest-mock: ^29.7.0 + js-sha256: ^0.11.0 jsonpath: ^1.1.1 lodash: ^4.17.21 lodash.clonedeep: ^4.5.0 prettier: ^3.3.3 prettier-plugin-packagejson: ^2.5.2 rimraf: ^6.0.1 + secp256k1: ^5.0.0 ts-jest: ^29.2.2 ts-node: ^10.9.2 typescript: ^5.6.2 @@ -3114,17 +3066,6 @@ __metadata: languageName: node linkType: hard -"@humanwhocodes/config-array@npm:^0.13.0": - version: 0.13.0 - resolution: "@humanwhocodes/config-array@npm:0.13.0" - dependencies: - "@humanwhocodes/object-schema": ^2.0.3 - debug: ^4.3.1 - minimatch: ^3.0.5 - checksum: eae69ff9134025dd2924f0b430eb324981494be26f0fddd267a33c28711c4db643242cf9fddf7dadb9d16c96b54b2d2c073e60a56477df86e0173149313bd5d6 - languageName: node - linkType: hard - "@humanwhocodes/config-array@npm:^0.5.0": version: 0.5.0 resolution: "@humanwhocodes/config-array@npm:0.5.0" @@ -3150,7 +3091,7 @@ __metadata: languageName: node linkType: hard -"@humanwhocodes/object-schema@npm:^2.0.2, @humanwhocodes/object-schema@npm:^2.0.3": +"@humanwhocodes/object-schema@npm:^2.0.2": version: 2.0.3 resolution: "@humanwhocodes/object-schema@npm:2.0.3" checksum: d3b78f6c5831888c6ecc899df0d03bcc25d46f3ad26a11d7ea52944dc36a35ef543fad965322174238d677a43d5c694434f6607532cff7077062513ad7022631 @@ -3692,17 +3633,6 @@ __metadata: languageName: node linkType: hard -"@metamask/eslint-config-jest@npm:^11.1.0": - version: 11.1.0 - resolution: "@metamask/eslint-config-jest@npm:11.1.0" - peerDependencies: - "@metamask/eslint-config": ^11.0.0 - eslint: ^8.27.0 - eslint-plugin-jest: ^27.1.5 - checksum: a649cf317327532d0d18795ac3bc74766e649e821ca3130dac288b16d5243ae72b5bda4eb85c678f1b4f9c073904ac6162b740c237b67921e64ce4f40c6ceb77 - languageName: node - linkType: hard - "@metamask/eslint-config-jest@npm:^12.1.0": version: 12.1.0 resolution: "@metamask/eslint-config-jest@npm:12.1.0" @@ -3714,17 +3644,6 @@ __metadata: languageName: node linkType: hard -"@metamask/eslint-config-nodejs@npm:^11.1.0": - version: 11.1.0 - resolution: "@metamask/eslint-config-nodejs@npm:11.1.0" - peerDependencies: - "@metamask/eslint-config": ^11.0.0 - eslint: ^8.27.0 - eslint-plugin-node: ^11.1.0 - checksum: f672fc4a3269c55ec6189caf4fe1a4d94f375ebd4c72d479530bc561d6afc642999b055ff795398f6ad77e9e7f217baa44499699f3301e149ace316dc3cba861 - languageName: node - linkType: hard - "@metamask/eslint-config-nodejs@npm:^12.1.0": version: 12.1.0 resolution: "@metamask/eslint-config-nodejs@npm:12.1.0" @@ -3736,19 +3655,6 @@ __metadata: languageName: node linkType: hard -"@metamask/eslint-config-typescript@npm:^11.1.0": - version: 11.1.0 - resolution: "@metamask/eslint-config-typescript@npm:11.1.0" - peerDependencies: - "@metamask/eslint-config": ^11.0.0 - "@typescript-eslint/eslint-plugin": ^5.42.1 - "@typescript-eslint/parser": ^5.42.1 - eslint: ^8.27.0 - typescript: ~4.8.4 - checksum: 86f20303730fce7a2d6944d133e3d4cf745816bdc202fd17ebd341e4937777c662e80b3c1496a8da7d5e06e39518dec3206c4a4e872d9491f423e792bcdf56db - languageName: node - linkType: hard - "@metamask/eslint-config-typescript@npm:^12.1.0": version: 12.1.0 resolution: "@metamask/eslint-config-typescript@npm:12.1.0" @@ -3762,20 +3668,6 @@ __metadata: languageName: node linkType: hard -"@metamask/eslint-config@npm:^11.1.0": - version: 11.1.0 - resolution: "@metamask/eslint-config@npm:11.1.0" - peerDependencies: - eslint: ^8.27.0 - eslint-config-prettier: ^8.5.0 - eslint-plugin-import: ^2.26.0 - eslint-plugin-jsdoc: ^39.6.2 - eslint-plugin-prettier: ^4.2.1 - prettier: ^2.7.1 - checksum: 2345eb03821d80d605d60c393a3249b322ae32cee87497b338d81cc723d28d87d44adec92ba657fdc83e7df8599ec9eed06f1ad78f0febd13c318fb5a5ba2a7a - languageName: node - linkType: hard - "@metamask/eslint-config@npm:^12.2.0": version: 12.2.0 resolution: "@metamask/eslint-config@npm:12.2.0" @@ -4230,17 +4122,6 @@ __metadata: languageName: node linkType: hard -"@metamask/snaps-ui@npm:^3.1.0": - version: 3.1.0 - resolution: "@metamask/snaps-ui@npm:3.1.0" - dependencies: - "@metamask/utils": ^8.1.0 - is-svg: ^4.4.0 - superstruct: ^1.0.3 - checksum: a234217e961a103b89708d46732481e82c0778b3ebbecddabc9351eee48d082cdc231102442c3ae5c76aa33b24c24aad70e84fee9d7b492641f290a10c3211c1 - languageName: node - linkType: hard - "@metamask/snaps-utils@npm:^8.1.1, @metamask/snaps-utils@npm:^8.4.0": version: 8.4.0 resolution: "@metamask/snaps-utils@npm:8.4.0" @@ -4284,30 +4165,13 @@ __metadata: languageName: node linkType: hard -"@metamask/superstruct@npm:^3.0.0, @metamask/superstruct@npm:^3.1.0": +"@metamask/superstruct@npm:^3.1.0": version: 3.1.0 resolution: "@metamask/superstruct@npm:3.1.0" checksum: 00e4d0c0aae8b25ccc1885c1db0bb4ed1590010570140c255e4deee3bf8a10c859c8fce5e475b4ae09c8a56316207af87585b91f7f5a5c028d668ccd111f19e3 languageName: node linkType: hard -"@metamask/utils@npm:^8.1.0": - version: 8.5.0 - resolution: "@metamask/utils@npm:8.5.0" - dependencies: - "@ethereumjs/tx": ^4.2.0 - "@metamask/superstruct": ^3.0.0 - "@noble/hashes": ^1.3.1 - "@scure/base": ^1.1.3 - "@types/debug": ^4.1.7 - debug: ^4.3.4 - pony-cause: ^2.1.10 - semver: ^7.5.4 - uuid: ^9.0.1 - checksum: e8eac1c796c3f6b623be3c2736e8682248620f666b180f5c12ce56ee09587d4e28b6811862139a05c7a1bec91415f10ccf0516f3cdf342f88b0189d2a057c24b - languageName: node - linkType: hard - "@metamask/utils@npm:^9.0.0, @metamask/utils@npm:^9.1.0, @metamask/utils@npm:^9.2.1": version: 9.3.0 resolution: "@metamask/utils@npm:9.3.0" @@ -6165,7 +6029,7 @@ __metadata: languageName: node linkType: hard -"@transmute/credentials-context@npm:^0.7.0-unstable.79, @transmute/credentials-context@npm:^0.7.0-unstable.81, @transmute/credentials-context@npm:^0.7.0-unstable.82": +"@transmute/credentials-context@npm:^0.7.0-unstable.81, @transmute/credentials-context@npm:^0.7.0-unstable.82": version: 0.7.0-unstable.82 resolution: "@transmute/credentials-context@npm:0.7.0-unstable.82" checksum: 224ef148faf9a527e93ff42ca08974a21ea1fcb54916bfb7dcec7d35e76d3c8f5a5f12ceef2bcc160be93583128d60fbb3048a90aa8b9cc21430a12b568e9264 @@ -6194,7 +6058,7 @@ __metadata: languageName: node linkType: hard -"@transmute/ed25519-signature-2018@npm:^0.7.0-unstable.79, @transmute/ed25519-signature-2018@npm:^0.7.0-unstable.81": +"@transmute/ed25519-signature-2018@npm:^0.7.0-unstable.81": version: 0.7.0-unstable.82 resolution: "@transmute/ed25519-signature-2018@npm:0.7.0-unstable.82" dependencies: @@ -6221,7 +6085,7 @@ __metadata: languageName: node linkType: hard -"@transmute/json-web-signature@npm:^0.7.0-unstable.79, @transmute/json-web-signature@npm:^0.7.0-unstable.81": +"@transmute/json-web-signature@npm:^0.7.0-unstable.81": version: 0.7.0-unstable.82 resolution: "@transmute/json-web-signature@npm:0.7.0-unstable.82" dependencies: @@ -6770,6 +6634,15 @@ __metadata: languageName: node linkType: hard +"@types/secp256k1@npm:^4.0.6": + version: 4.0.6 + resolution: "@types/secp256k1@npm:4.0.6" + dependencies: + "@types/node": "*" + checksum: 984494caf49a4ce99fda2b9ea1840eb47af946b8c2737314108949bcc0c06b4880e871296bd49ed6ea4c8423e3a302ad79fec43abfc987330e7eb98f0c4e8ba4 + languageName: node + linkType: hard + "@types/semver@npm:^7.3.12, @types/semver@npm:^7.5.0": version: 7.5.8 resolution: "@types/semver@npm:7.5.8" @@ -6846,7 +6719,7 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:5.62.0, @typescript-eslint/eslint-plugin@npm:^5.57.1, @typescript-eslint/eslint-plugin@npm:^5.60.1": +"@typescript-eslint/eslint-plugin@npm:5.62.0, @typescript-eslint/eslint-plugin@npm:^5.60.1": version: 5.62.0 resolution: "@typescript-eslint/eslint-plugin@npm:5.62.0" dependencies: @@ -6870,7 +6743,7 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/parser@npm:5.62.0, @typescript-eslint/parser@npm:^5.57.1, @typescript-eslint/parser@npm:^5.60.1": +"@typescript-eslint/parser@npm:5.62.0, @typescript-eslint/parser@npm:^5.60.1": version: 5.62.0 resolution: "@typescript-eslint/parser@npm:5.62.0" dependencies: @@ -6975,7 +6848,7 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/utils@npm:5.62.0, @typescript-eslint/utils@npm:^5.10.0": +"@typescript-eslint/utils@npm:5.62.0": version: 5.62.0 resolution: "@typescript-eslint/utils@npm:5.62.0" dependencies: @@ -7030,13 +6903,6 @@ __metadata: languageName: node linkType: hard -"@ungap/structured-clone@npm:^1.2.0": - version: 1.2.0 - resolution: "@ungap/structured-clone@npm:1.2.0" - checksum: 4f656b7b4672f2ce6e272f2427d8b0824ed11546a601d8d5412b9d7704e83db38a8d9f402ecdf2b9063fc164af842ad0ec4a55819f621ed7e7ea4d1efcc74524 - languageName: node - linkType: hard - "@unimodules/core@npm:*": version: 7.2.0 resolution: "@unimodules/core@npm:7.2.0" @@ -7121,29 +6987,6 @@ __metadata: languageName: node linkType: hard -"@veramo/credential-ld@npm:5.1.2": - version: 5.1.2 - resolution: "@veramo/credential-ld@npm:5.1.2" - dependencies: - "@digitalcredentials/ed25519-signature-2020": ^3.0.2 - "@digitalcredentials/ed25519-verification-key-2020": ^4.0.0 - "@digitalcredentials/jsonld": ^5.2.1 - "@digitalcredentials/jsonld-signatures": ^9.3.1 - "@digitalcredentials/vc": ^5.0.0 - "@transmute/credentials-context": ^0.7.0-unstable.79 - "@transmute/ed25519-signature-2018": ^0.7.0-unstable.79 - "@transmute/json-web-signature": ^0.7.0-unstable.79 - "@veramo-community/lds-ecdsa-secp256k1-recovery2020": "github:uport-project/EcdsaSecp256k1RecoverySignature2020" - "@veramo/core-types": ^5.1.2 - "@veramo/utils": ^5.1.2 - cross-fetch: ^3.1.5 - debug: ^4.3.3 - did-resolver: ^4.0.1 - uint8arrays: ^3.0.0 - checksum: 26341ebe3c801a714b983183bab27d34cd22821201ce801db3514fd0062562fab849db116c3beccf3dd61154452fc84cda93bb6c04c80f6ac139d351b92ec70b - languageName: node - linkType: hard - "@veramo/credential-ld@npm:^5.1.2": version: 5.6.0 resolution: "@veramo/credential-ld@npm:5.6.0" @@ -7340,20 +7183,6 @@ __metadata: languageName: node linkType: hard -"@veramo/selective-disclosure@npm:5.1.2": - version: 5.1.2 - resolution: "@veramo/selective-disclosure@npm:5.1.2" - dependencies: - "@veramo/core-types": ^5.1.2 - "@veramo/message-handler": ^5.1.2 - "@veramo/utils": ^5.1.2 - debug: ^4.3.3 - did-jwt: ^6.9.0 - uuid: ^9.0.0 - checksum: 0d51f55b824d7763d46688e2ae77de5f6ccee340b462f208ebbd6158dcc724f3ceb2fe6c9d8c7b480e22ce03fb72cb0151b2c981e6cbfeea4e32ad1840e6b6f8 - languageName: node - linkType: hard - "@veramo/utils@npm:^5.1.2, @veramo/utils@npm:^5.6.0": version: 5.6.0 resolution: "@veramo/utils@npm:5.6.0" @@ -7577,33 +7406,6 @@ __metadata: languageName: node linkType: hard -"@yarnpkg/fslib@npm:^3.0.2": - version: 3.1.0 - resolution: "@yarnpkg/fslib@npm:3.1.0" - dependencies: - tslib: ^2.4.0 - checksum: 5274c63731cb30283a93e1446d6796b890fc56c55ed046156b2963a527465bc3add091a1e7f471b7533c8b1aa67b8532960e64589787014dee2cf3d97a9304f6 - languageName: node - linkType: hard - -"@yarnpkg/plugin-workspace-tools@npm:^4.1.0": - version: 4.1.0 - resolution: "@yarnpkg/plugin-workspace-tools@npm:4.1.0" - dependencies: - "@yarnpkg/fslib": ^3.0.2 - clipanion: ^4.0.0-rc.2 - micromatch: ^4.0.2 - p-limit: ^2.2.0 - tslib: ^2.4.0 - typanion: ^3.14.0 - peerDependencies: - "@yarnpkg/cli": ^4.1.0 - "@yarnpkg/core": ^4.0.3 - "@yarnpkg/plugin-git": ^3.0.0 - checksum: 8ee82796e1f86267827bf9fd25b07e63914732817fdcf8debe9d60e8e1ead87f79c8fb7b9bc60a78e097a1920579fb044b8f37aa28a3b5e7902893fc7e712957 - languageName: node - linkType: hard - "JSONStream@npm:^1.0.3": version: 1.3.5 resolution: "JSONStream@npm:1.3.5" @@ -9233,13 +9035,6 @@ __metadata: languageName: node linkType: hard -"builtin-modules@npm:^3.3.0": - version: 3.3.0 - resolution: "builtin-modules@npm:3.3.0" - checksum: db021755d7ed8be048f25668fe2117620861ef6703ea2c65ed2779c9e3636d5c3b82325bd912244293959ff3ae303afa3471f6a15bf5060c103e4cc3a839749d - languageName: node - linkType: hard - "builtin-status-codes@npm:^3.0.0": version: 3.0.0 resolution: "builtin-status-codes@npm:3.0.0" @@ -9696,17 +9491,6 @@ __metadata: languageName: node linkType: hard -"clipanion@npm:^4.0.0-rc.2": - version: 4.0.0-rc.4 - resolution: "clipanion@npm:4.0.0-rc.4" - dependencies: - typanion: ^3.8.0 - peerDependencies: - typanion: "*" - checksum: a92aa03b24eb89292b7bda570973c164fff16a1c5ba4c4abdd1b0dd6110a57651752114ec9f5cfc29e2040213e514b3220142a2316c4fc4e659ba423caa296c7 - languageName: node - linkType: hard - "clipboardy@npm:^4.0.0": version: 4.0.0 resolution: "clipboardy@npm:4.0.0" @@ -11981,7 +11765,7 @@ __metadata: languageName: node linkType: hard -"eslint-config-prettier@npm:^9.0.0, eslint-config-prettier@npm:^9.1.0": +"eslint-config-prettier@npm:^9.1.0": version: 9.1.0 resolution: "eslint-config-prettier@npm:9.1.0" peerDependencies: @@ -12078,7 +11862,7 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-import@npm:^2.27.5, eslint-plugin-import@npm:^2.28.1, eslint-plugin-import@npm:^2.29.1": +"eslint-plugin-import@npm:^2.27.5, eslint-plugin-import@npm:^2.29.1": version: 2.31.0 resolution: "eslint-plugin-import@npm:2.31.0" dependencies: @@ -12125,43 +11909,6 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-jest@npm:^27.4.0": - version: 27.9.0 - resolution: "eslint-plugin-jest@npm:27.9.0" - dependencies: - "@typescript-eslint/utils": ^5.10.0 - peerDependencies: - "@typescript-eslint/eslint-plugin": ^5.0.0 || ^6.0.0 || ^7.0.0 - eslint: ^7.0.0 || ^8.0.0 - jest: "*" - peerDependenciesMeta: - "@typescript-eslint/eslint-plugin": - optional: true - jest: - optional: true - checksum: e2a4b415105408de28ad146818fcc6f4e122f6a39c6b2216ec5c24a80393f1390298b20231b0467bc5fd730f6e24b05b89e1a6a3ce651fc159aa4174ecc233d0 - languageName: node - linkType: hard - -"eslint-plugin-jsdoc@npm:^46.8.1": - version: 46.10.1 - resolution: "eslint-plugin-jsdoc@npm:46.10.1" - dependencies: - "@es-joy/jsdoccomment": ~0.41.0 - are-docs-informative: ^0.0.2 - comment-parser: 1.4.1 - debug: ^4.3.4 - escape-string-regexp: ^4.0.0 - esquery: ^1.5.0 - is-builtin-module: ^3.2.1 - semver: ^7.5.4 - spdx-expression-parse: ^4.0.0 - peerDependencies: - eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 - checksum: e3a658f72de9ac1c6d98fc1e406e4f1295f3f2a64da9ea977ba8bbb9ea93890945d0d4230dd50a1436ac8a935c4b3a49a02a5dae170810ba7fe6d46522dd17eb - languageName: node - linkType: hard - "eslint-plugin-jsdoc@npm:^50.2.2": version: 50.3.1 resolution: "eslint-plugin-jsdoc@npm:50.3.1" @@ -12243,21 +11990,6 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-prettier@npm:^4.2.1": - version: 4.2.1 - resolution: "eslint-plugin-prettier@npm:4.2.1" - dependencies: - prettier-linter-helpers: ^1.0.0 - peerDependencies: - eslint: ">=7.28.0" - prettier: ">=2.0.0" - peerDependenciesMeta: - eslint-config-prettier: - optional: true - checksum: b9e839d2334ad8ec7a5589c5cb0f219bded260839a857d7a486997f9870e95106aa59b8756ff3f37202085ebab658de382b0267cae44c3a7f0eb0bcc03a4f6d6 - languageName: node - linkType: hard - "eslint-plugin-prettier@npm:^5.2.1": version: 5.2.1 resolution: "eslint-plugin-prettier@npm:5.2.1" @@ -12334,7 +12066,7 @@ __metadata: languageName: node linkType: hard -"eslint-scope@npm:^7.1.1, eslint-scope@npm:^7.2.2": +"eslint-scope@npm:^7.1.1": version: 7.2.2 resolution: "eslint-scope@npm:7.2.2" dependencies: @@ -12367,7 +12099,7 @@ __metadata: languageName: node linkType: hard -"eslint-visitor-keys@npm:^3.3.0, eslint-visitor-keys@npm:^3.4.0, eslint-visitor-keys@npm:^3.4.1, eslint-visitor-keys@npm:^3.4.3": +"eslint-visitor-keys@npm:^3.3.0, eslint-visitor-keys@npm:^3.4.0, eslint-visitor-keys@npm:^3.4.1": version: 3.4.3 resolution: "eslint-visitor-keys@npm:3.4.3" checksum: 36e9ef87fca698b6fd7ca5ca35d7b2b6eeaaf106572e2f7fd31c12d3bfdaccdb587bba6d3621067e5aece31c8c3a348b93922ab8f7b2cbc6aaab5e1d89040c60 @@ -12498,54 +12230,6 @@ __metadata: languageName: node linkType: hard -"eslint@npm:^8.38.0": - version: 8.57.1 - resolution: "eslint@npm:8.57.1" - dependencies: - "@eslint-community/eslint-utils": ^4.2.0 - "@eslint-community/regexpp": ^4.6.1 - "@eslint/eslintrc": ^2.1.4 - "@eslint/js": 8.57.1 - "@humanwhocodes/config-array": ^0.13.0 - "@humanwhocodes/module-importer": ^1.0.1 - "@nodelib/fs.walk": ^1.2.8 - "@ungap/structured-clone": ^1.2.0 - ajv: ^6.12.4 - chalk: ^4.0.0 - cross-spawn: ^7.0.2 - debug: ^4.3.2 - doctrine: ^3.0.0 - escape-string-regexp: ^4.0.0 - eslint-scope: ^7.2.2 - eslint-visitor-keys: ^3.4.3 - espree: ^9.6.1 - esquery: ^1.4.2 - esutils: ^2.0.2 - fast-deep-equal: ^3.1.3 - file-entry-cache: ^6.0.1 - find-up: ^5.0.0 - glob-parent: ^6.0.2 - globals: ^13.19.0 - graphemer: ^1.4.0 - ignore: ^5.2.0 - imurmurhash: ^0.1.4 - is-glob: ^4.0.0 - is-path-inside: ^3.0.3 - js-yaml: ^4.1.0 - json-stable-stringify-without-jsonify: ^1.0.1 - levn: ^0.4.1 - lodash.merge: ^4.6.2 - minimatch: ^3.1.2 - natural-compare: ^1.4.0 - optionator: ^0.9.3 - strip-ansi: ^6.0.1 - text-table: ^0.2.0 - bin: - eslint: bin/eslint.js - checksum: e2489bb7f86dd2011967759a09164e65744ef7688c310bc990612fc26953f34cc391872807486b15c06833bdff737726a23e9b4cdba5de144c311377dc41d91b - languageName: node - linkType: hard - "esm@npm:^3.2.22": version: 3.2.25 resolution: "esm@npm:3.2.25" @@ -12587,7 +12271,7 @@ __metadata: languageName: node linkType: hard -"espree@npm:^9.5.1, espree@npm:^9.6.0, espree@npm:^9.6.1": +"espree@npm:^9.5.1, espree@npm:^9.6.0": version: 9.6.1 resolution: "espree@npm:9.6.1" dependencies: @@ -12618,7 +12302,7 @@ __metadata: languageName: node linkType: hard -"esquery@npm:^1.4.0, esquery@npm:^1.4.2, esquery@npm:^1.5.0, esquery@npm:^1.6.0": +"esquery@npm:^1.4.0, esquery@npm:^1.4.2, esquery@npm:^1.6.0": version: 1.6.0 resolution: "esquery@npm:1.6.0" dependencies: @@ -13029,7 +12713,7 @@ __metadata: languageName: node linkType: hard -"fast-xml-parser@npm:^4.1.3, fast-xml-parser@npm:^4.4.1": +"fast-xml-parser@npm:^4.4.1": version: 4.5.0 resolution: "fast-xml-parser@npm:4.5.0" dependencies: @@ -15122,15 +14806,6 @@ __metadata: languageName: node linkType: hard -"is-builtin-module@npm:^3.2.1": - version: 3.2.1 - resolution: "is-builtin-module@npm:3.2.1" - dependencies: - builtin-modules: ^3.3.0 - checksum: e8f0ffc19a98240bda9c7ada84d846486365af88d14616e737d280d378695c8c448a621dcafc8332dbf0fcd0a17b0763b845400709963fa9151ddffece90ae88 - languageName: node - linkType: hard - "is-callable@npm:^1.1.3, is-callable@npm:^1.1.4, is-callable@npm:^1.2.7": version: 1.2.7 resolution: "is-callable@npm:1.2.7" @@ -15468,15 +15143,6 @@ __metadata: languageName: node linkType: hard -"is-svg@npm:^4.4.0": - version: 4.4.0 - resolution: "is-svg@npm:4.4.0" - dependencies: - fast-xml-parser: ^4.1.3 - checksum: cd5a0ba1af653e4897721913b0b80de968fa5b19eb1a592412f4672d3a1203935d183c2a9dbf61d68023739ee43d3761ea795ae1a9f618c6098a9e89eacdd256 - languageName: node - linkType: hard - "is-symbol@npm:^1.0.2, is-symbol@npm:^1.0.3": version: 1.0.4 resolution: "is-symbol@npm:1.0.4" @@ -16303,6 +15969,13 @@ __metadata: languageName: node linkType: hard +"js-sha256@npm:^0.11.0": + version: 0.11.0 + resolution: "js-sha256@npm:0.11.0" + checksum: 742d34a0c6eb15247309f1c74889b5a51df01a96e4307375b420fbe973f2f25585012b4d3c8fa52a1b18546153d12587e6463bb725dc1bc58686da03e892c334 + languageName: node + linkType: hard + "js-sha3@npm:0.8.0, js-sha3@npm:^0.8.0": version: 0.8.0 resolution: "js-sha3@npm:0.8.0" @@ -16354,13 +16027,6 @@ __metadata: languageName: node linkType: hard -"jsdoc-type-pratt-parser@npm:~4.0.0": - version: 4.0.0 - resolution: "jsdoc-type-pratt-parser@npm:4.0.0" - checksum: af0629c9517e484be778d8564440fec8de5b7610e0c9c88a3ba4554321364faf72b46689c8d8845faa12c0718437a9ed97e231977efc0f2d50e8a2dbad807eb3 - languageName: node - linkType: hard - "jsdoc-type-pratt-parser@npm:~4.1.0": version: 4.1.0 resolution: "jsdoc-type-pratt-parser@npm:4.1.0" @@ -17326,7 +16992,7 @@ __metadata: languageName: node linkType: hard -"micromatch@npm:^4.0.2, micromatch@npm:^4.0.4, micromatch@npm:^4.0.5": +"micromatch@npm:^4.0.4, micromatch@npm:^4.0.5": version: 4.0.8 resolution: "micromatch@npm:4.0.8" dependencies: @@ -17911,6 +17577,15 @@ __metadata: languageName: node linkType: hard +"node-addon-api@npm:^5.0.0": + version: 5.1.0 + resolution: "node-addon-api@npm:5.1.0" + dependencies: + node-gyp: latest + checksum: 2508bd2d2981945406243a7bd31362fc7af8b70b8b4d65f869c61731800058fb818cc2fd36c8eac714ddd0e568cc85becf5e165cebbdf7b5024d5151bbc75ea1 + languageName: node + linkType: hard + "node-addon-api@npm:^6.1.0": version: 6.1.0 resolution: "node-addon-api@npm:6.1.0" @@ -18389,7 +18064,7 @@ __metadata: languageName: node linkType: hard -"optionator@npm:^0.9.1, optionator@npm:^0.9.3": +"optionator@npm:^0.9.1": version: 0.9.4 resolution: "optionator@npm:0.9.4" dependencies: @@ -19432,7 +19107,7 @@ __metadata: languageName: node linkType: hard -"prettier-plugin-packagejson@npm:^2.4.5, prettier-plugin-packagejson@npm:^2.5.0, prettier-plugin-packagejson@npm:^2.5.2": +"prettier-plugin-packagejson@npm:^2.5.0, prettier-plugin-packagejson@npm:^2.5.2": version: 2.5.3 resolution: "prettier-plugin-packagejson@npm:2.5.3" dependencies: @@ -19456,7 +19131,7 @@ __metadata: languageName: node linkType: hard -"prettier@npm:^3.0.3, prettier@npm:^3.3.3": +"prettier@npm:^3.3.3": version: 3.3.3 resolution: "prettier@npm:3.3.3" bin: @@ -19609,7 +19284,7 @@ __metadata: languageName: node linkType: hard -"protobufjs@npm:^7.2.5, protobufjs@npm:^7.4.0": +"protobufjs@npm:^7.2.5": version: 7.4.0 resolution: "protobufjs@npm:7.4.0" dependencies: @@ -20766,6 +20441,18 @@ __metadata: languageName: node linkType: hard +"secp256k1@npm:^5.0.0": + version: 5.0.0 + resolution: "secp256k1@npm:5.0.0" + dependencies: + elliptic: ^6.5.4 + node-addon-api: ^5.0.0 + node-gyp: latest + node-gyp-build: ^4.2.0 + checksum: a0719dff4687c38d385b5e0b7e811c51a4ea24893128be9d097aee99f879eb0ea52582590deb15a49da627a3db23c6b028ad5c9c6ac1fca92ce760153b8cf21c + languageName: node + linkType: hard + "secure-json-parse@npm:^2.4.0": version: 2.7.0 resolution: "secure-json-parse@npm:2.7.0" @@ -21877,13 +21564,6 @@ __metadata: languageName: node linkType: hard -"superstruct@npm:^1.0.3": - version: 1.0.4 - resolution: "superstruct@npm:1.0.4" - checksum: 2e070994cc4998a753c3f0215449d6de01ffb8180e4f46527f559ffbc2ebcc40fcf428f545ccd355921ef2920db7d138a96258ae35c788e6c24b2aa8bb1695cb - languageName: node - linkType: hard - "supports-color@npm:^5.3.0": version: 5.5.0 resolution: "supports-color@npm:5.5.0" @@ -22461,13 +22141,6 @@ __metadata: languageName: node linkType: hard -"typanion@npm:^3.14.0, typanion@npm:^3.8.0": - version: 3.14.0 - resolution: "typanion@npm:3.14.0" - checksum: fc0590d02c13c659eb1689e8adf7777e6c00dc911377e44cd36fe1b1271cfaca71547149f12cdc275058c0de5562a14e5273adbae66d47e6e0320e36007f5912 - languageName: node - linkType: hard - "type-check@npm:^0.4.0, type-check@npm:~0.4.0": version: 0.4.0 resolution: "type-check@npm:0.4.0" @@ -22631,7 +22304,7 @@ __metadata: languageName: node linkType: hard -"typescript@npm:^5.2.2, typescript@npm:^5.6.2": +"typescript@npm:^5.6.2": version: 5.6.3 resolution: "typescript@npm:5.6.3" bin: @@ -22641,7 +22314,7 @@ __metadata: languageName: node linkType: hard -"typescript@patch:typescript@^5.2.2#~builtin, typescript@patch:typescript@^5.6.2#~builtin": +"typescript@patch:typescript@^5.6.2#~builtin": version: 5.6.3 resolution: "typescript@patch:typescript@npm%3A5.6.3#~builtin::version=5.6.3&hash=7ad353" bin: