{
content={{
title: 'Send Failed Transaction',
description:
- "Send a failed transaction with a predefined payload. It will be simulated using Tenderly Simulation API. Don't confirm it!",
+ 'Send a failed transaction with a predefined payload. It will be simulated using Tenderly Simulation API. Do not confirm it!',
data: (
{
content={{
title: 'Send Any Transaction',
description:
- "Send a transaction with a custom payload. It will be simulated using Tenderly Simulation API. Don't confirm it!",
+ 'Send a transaction with a custom payload. It will be simulated using Tenderly Simulation API. Do not confirm it!',
data: (
@@ -295,17 +302,9 @@ const Index = () => {
5 USDC to demo.eth. Copy it and click on the{' '}
Send Transaction button.
-
- {JSON.stringify(successfulTx, null, 2)}
-
+
+ {JSON.stringify(successfulTxPayload, null, 2)}
+
=> {
params: {
snapId: defaultSnapOrigin,
request: {
- method: 'update_tenderly_credentials',
+ method: CustomRequestMethod.UPDATE_TENDERLY_CREDENTIALS,
},
},
});
@@ -74,12 +75,31 @@ export const sendTenderlyTransaction = async (): Promise => {
params: {
snapId: defaultSnapOrigin,
request: {
- method: 'send_tenderly_transaction',
+ method: CustomRequestMethod.SEND_TENDERLY_TRANSACTION,
},
},
});
};
+/**
+ * Sends a transaction using the Ethereum provider's `eth_sendTransaction` JSON-RPC method.
+ * The transaction data is taken from the input parameter.
+ *
+ * @param data - The data of the transaction to be sent. This should be an object containing
+ * the relevant transaction data such as the `to` address, the `value`, the `gas`,
+ * the `gasPrice`, and the `data` (for contract interactions).
+ * @returns A Promise that resolves to the transaction hash if the transaction
+ * submission was successful, or rejects with an error if something went wrong.
+ * @throws Will throw an error if no accounts are available or if the Ethereum provider's request fails.
+ * @example
+ * // ERC20 Transfer - sending 1 USDC to demo.eth
+ * sendTransaction({
+ * to: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
+ * value: '0x0',
+ * data: '0xa9059cbb000000000000000000000000fc43f5f9dd45258b3aff31bdbe6561d97e8b71de00000000000000000000000000000000000000000000000000000000000f4240',
+ * }).then(txHash => console.log(txHash))
+ * .catch(error => console.error(error));
+ */
export const sendTransaction = async (data: any): Promise => {
try {
const [from] = (await window.ethereum.request({
diff --git a/packages/snap/jest.config.js b/packages/snap/jest.config.js
new file mode 100644
index 0000000..f0a22c3
--- /dev/null
+++ b/packages/snap/jest.config.js
@@ -0,0 +1,6 @@
+module.exports = {
+ preset: '@metamask/snaps-jest',
+ transform: {
+ '^.+\\.(t|j)sx?$': 'ts-jest',
+ },
+};
diff --git a/packages/snap/package.json b/packages/snap/package.json
index 0e462d5..a83ef09 100644
--- a/packages/snap/package.json
+++ b/packages/snap/package.json
@@ -28,6 +28,7 @@
"dependencies": {
"@metamask/snaps-types": "^0.32.2",
"@metamask/snaps-ui": "^0.32.2",
+ "@metamask/utils": "^6.2.0",
"buffer": "^6.0.3"
},
"devDependencies": {
diff --git a/packages/snap/snap.manifest.json b/packages/snap/snap.manifest.json
index 62556b6..f6223cb 100644
--- a/packages/snap/snap.manifest.json
+++ b/packages/snap/snap.manifest.json
@@ -7,7 +7,7 @@
"url": "https://github.com/Tenderly/tenderly-metamask-snap-simulate-asset-changes.git"
},
"source": {
- "shasum": "9Qy94W81xSy0NVW/77DwofrhrQtavXsgyZnvgA6Icbs=",
+ "shasum": "OXuq1oRKZP51I/dTk9HMvOce1cS9gRkyQXt+lVWpQq4=",
"location": {
"npm": {
"filePath": "dist/bundle.js",
diff --git a/packages/snap/src/constants.ts b/packages/snap/src/constants.ts
new file mode 100644
index 0000000..dce910f
--- /dev/null
+++ b/packages/snap/src/constants.ts
@@ -0,0 +1,6 @@
+enum CustomRequestMethod {
+ UPDATE_TENDERLY_CREDENTIALS = 'update_tenderly_credentials',
+ SEND_TENDERLY_TRANSACTION = 'send_tenderly_transaction',
+}
+
+export { CustomRequestMethod };
diff --git a/packages/snap/src/index.ts b/packages/snap/src/index.ts
index 608c57e..721eded 100644
--- a/packages/snap/src/index.ts
+++ b/packages/snap/src/index.ts
@@ -9,6 +9,7 @@ import {
handleSendTenderlyTransaction,
simulate,
} from './tenderly';
+import { CustomRequestMethod } from './constants';
/**
* Handle incoming JSON-RPC requests, sent through `wallet_invokeSnap`.
@@ -22,15 +23,25 @@ import {
*/
export const onRpcRequest: OnRpcRequestHandler = ({ origin, request }) => {
switch (request.method) {
- case 'update_tenderly_credentials':
+ case CustomRequestMethod.UPDATE_TENDERLY_CREDENTIALS:
return handleUpdateTenderlyCredentials(origin);
- case 'send_tenderly_transaction':
+ case CustomRequestMethod.SEND_TENDERLY_TRANSACTION:
return handleSendTenderlyTransaction(origin);
default:
throw new Error(`Method ${request.method} not supported.`);
}
};
+/**
+ * Handles transactions by providing insights before a transaction is signed.
+ * This function is a required export for a snap that wishes to interact with MetaMask transactions.
+ * Whenever there's a contract interaction and a transaction is submitted through MetaMask, this method is invoked.
+ * The raw unsigned transaction payload is passed as an argument to this handler method.
+ *
+ * @param args - The request handler args as object.
+ * @param args.transaction - The transaction to handle.
+ * @param args.transactionOrigin - The transaction origin.
+ */
export const onTransaction: OnTransactionHandler = async ({
transaction,
transactionOrigin,
@@ -44,7 +55,10 @@ export const onTransaction: OnTransactionHandler = async ({
};
}
- const simulationResponse = await simulate(transaction, transactionOrigin);
+ const simulationResponse = await simulate(
+ transaction,
+ transactionOrigin || '',
+ );
return {
content: {
diff --git a/packages/snap/src/tenderly/credentials-access.ts b/packages/snap/src/tenderly/credentials-access.ts
index 59d7753..906ba80 100644
--- a/packages/snap/src/tenderly/credentials-access.ts
+++ b/packages/snap/src/tenderly/credentials-access.ts
@@ -2,15 +2,15 @@ import { panel, text, heading } from '@metamask/snaps-ui';
import { requestSnapPrompt } from './utils';
export type TenderlyCredentials = {
+ accountId: string;
projectId: string;
- userId: string;
- accessKey: string;
+ accessToken: string;
};
/**
* Fetches the credentials associated with Tenderly project.
*
- * @param origin - The origin of the request
+ * @param origin - The origin of the request.
*/
export async function fetchCredentials(
origin: string,
@@ -33,7 +33,7 @@ export async function fetchCredentials(
/**
* Updates the credentials associated with Tenderly project.
*
- * @param origin - The origin of the request
+ * @param origin - The origin of the request.
*/
export async function handleUpdateTenderlyCredentials(origin: string) {
const tenderlyAccess = await requestNewTenderlyCredentials(origin);
@@ -50,7 +50,7 @@ export async function handleUpdateTenderlyCredentials(origin: string) {
/**
* Requests the new Tenderly credentials.
*
- * @param origin - The origin of the request
+ * @param origin - The origin of the request.
*/
async function requestNewTenderlyCredentials(
origin: string,
@@ -61,31 +61,31 @@ async function requestNewTenderlyCredentials(
throw new Error('Request for new Tenderly access failed; missing input');
}
- const [userId, projectId, accessKey] = credentialsRaw.split('@');
+ const [accountId, projectId, accessToken] = credentialsRaw.split('@');
- if (!userId || !projectId || !accessKey) {
+ if (!accountId || !projectId || !accessToken) {
throw new Error('Request for new Tenderly access failed; invalid input');
}
return {
- userId,
+ accountId,
projectId,
- accessKey,
+ accessToken,
};
}
/**
* Requests the Tenderly credentials.
*
- * @param origin - The origin of the request
+ * @param origin - The origin of the request.
*/
async function requestCredentials(origin: string): Promise {
return requestSnapPrompt(
panel([
heading(`${origin} wants to add credentials from Tenderly`),
text('Enter your Tenderly credentials in format:'),
- text('**{user_id}@{project_id}@{access_key}**'),
+ text('**{account_id}@{project_id}@{access_token}**'),
]),
- 'userId@projectId@accessKey',
+ 'accountId@projectId@accessToken',
);
}
diff --git a/packages/snap/src/tenderly/formatter.ts b/packages/snap/src/tenderly/formatter.ts
index 25014cf..4c3b7ff 100644
--- a/packages/snap/src/tenderly/formatter.ts
+++ b/packages/snap/src/tenderly/formatter.ts
@@ -10,9 +10,13 @@ import { arrMakeUnique, makeAddressFormatters } from './utils';
import { TenderlyCredentials } from './credentials-access';
/**
+ * This function receives the raw data and credentials of a Tenderly project simulation,
+ * calls the individual formatter functions for each relevant section
+ * (like balance changes, output value, asset changes, etc.) and returns a panel with all the formatted outputs.
*
- * @param data
- * @param credentials
+ * @param data - Simulation API data.
+ * @param credentials - Tenderly credentials object.
+ * @returns Panel with formatted values.
*/
export function formatResponse(
data: any,
@@ -40,10 +44,13 @@ export function formatResponse(
}
/**
+ * This function generates a panel showing balance changes for each account involved in the transaction.
+ * If there are no balance changes, it simply informs the user.
*
- * @param data
- * @param options0
- * @param options0.formatAddress
+ * @param data - Simulation API data.
+ * @param formatters - Formatters value from makeAddressFormatters().
+ * @param formatters.formatAddress - Function that formats an address.
+ * @returns Panel outputs with balance diff.
*/
function formatBalanceDiff(data: any, { formatAddress }: any): Component[] {
const panelOutputs: Component[] = [heading('Balance changes:')];
@@ -69,10 +76,13 @@ function formatBalanceDiff(data: any, { formatAddress }: any): Component[] {
}
/**
+ * This function creates a panel that presents the output values of the transaction, if any exist.
+ * It also decodes the output, if possible.
*
- * @param data
- * @param options0
- * @param options0.formatAddressesWithinStr
+ * @param data - Simulation API data.
+ * @param formatters - Formatters value from makeAddressFormatters().
+ * @param formatters.formatAddressesWithinStr - Function that formats an address within a string.
+ * @returns Panel outputs with decoded values.
*/
function formatOutputValue(
data: any,
@@ -105,8 +115,11 @@ function formatOutputValue(
}
/**
+ * This function formats a panel to show any changes to assets, differentiating between ERC20, ERC721, and other changes.
+ * If there are no changes, it informs the user.
*
- * @param data
+ * @param data - Simulation API data.
+ * @returns Panel outputs with asset changes.
*/
function formatAssetChanges(data: any): Component[] {
const panelOutputs: Component[] = [heading('Asset Changes:')];
@@ -179,9 +192,12 @@ function formatAssetChanges(data: any): Component[] {
}
/**
+ * This function creates a panel that lists any changes to storage that occurred during the transaction.
+ * It uniquely formats addresses and nested data structures for clarity.
*
- * @param data
- * @param formatters
+ * @param data - Simulation API data.
+ * @param formatters - Formatters value from makeAddressFormatters().
+ * @returns Panel outputs with storage changes.
*/
function formatStorageChanges(data: any, formatters: any): Component[] {
const { formatAddress, formatAddressesWithinStr } = formatters;
@@ -201,7 +217,6 @@ function formatStorageChanges(data: any, formatters: any): Component[] {
const storageChanges = stateDiff.filter((d: any) => d.address === contract);
storageChanges.forEach((diff: any) => {
- // todo: support raw format here!
if (diff.soltype) {
panelOutputs.push(
text(`â–¸ **${diff.soltype.name}[${diff.soltype.type}]:**`),
@@ -223,9 +238,12 @@ function formatStorageChanges(data: any, formatters: any): Component[] {
}
/**
+ * This function presents the event logs, if they exist, for each transaction.
+ * The logs are formatted for readability and include input values.
*
- * @param data
- * @param formatters
+ * @param data - Simulation API data.
+ * @param formatters - Formatters value from makeAddressFormatters().
+ * @returns Panel outputs with event logs.
*/
function formatEventLogs(data: any, formatters: any): Component[] {
const { formatAddress, formatAddressesWithinStr } = formatters;
@@ -264,14 +282,18 @@ function formatEventLogs(data: any, formatters: any): Component[] {
}
/**
+ * This function produces a formatted visual hierarchy of call traces, showing nested calls recursively.
*
- * @param data
+ * @param data - Simulation API data.
+ * @returns Panel outputs with call trace.
*/
function formatCallTrace(data: any): Component[] {
/**
+ * ShowS nested calls recursively.
*
- * @param calls
- * @param iter
+ * @param calls - Trace calls.
+ * @param iter - Indentation.
+ * @returns Call trace lines.
*/
function formatCallsRecursive(calls: any, iter = 0): Component[] {
let lines: Component[] = [];
@@ -300,15 +322,17 @@ function formatCallTrace(data: any): Component[] {
}
/**
+ * This function returns a link to the full details of the simulation on the Tenderly Dashboard, and a separate shareable link.
*
- * @param data
- * @param credentials
+ * @param data - Simulation API data.
+ * @param credentials - Tenderly credentials object.
+ * @returns Panel with simulation outputs.
*/
export function formatSimulationUrl(
data: any,
credentials: TenderlyCredentials,
): Component[] {
- const simulationUrl = `https://dashboard.tenderly.co/${credentials.userId}/${credentials.projectId}/simulator/${data.simulation?.id}`;
+ const simulationUrl = `https://dashboard.tenderly.co/${credentials.accountId}/${credentials.projectId}/simulator/${data.simulation?.id}`;
const sharedSimulationUrl = `https://dashboard.tenderly.co/shared/simulation/${data.simulation?.id}`;
return [
diff --git a/packages/snap/src/tenderly/simulation.ts b/packages/snap/src/tenderly/simulation.ts
index 0636d2a..91cbe3a 100644
--- a/packages/snap/src/tenderly/simulation.ts
+++ b/packages/snap/src/tenderly/simulation.ts
@@ -7,7 +7,7 @@ import { hex2int, requestSnapPrompt } from './utils';
/**
* Updates the credentials associated with Tenderly project.
*
- * @param origin - The origin of the request
+ * @param origin - The origin of the request.
*/
export async function handleSendTenderlyTransaction(origin: string) {
return requestSnapPrompt(
@@ -20,8 +20,13 @@ export async function handleSendTenderlyTransaction(origin: string) {
}
/**
+ * This is the main function that handles the simulation of a transaction.
+ * It fetches the credentials required for the Tenderly simulation, submits the transaction data to the Tenderly API,
+ * handles any errors returned by the API, and if there are no errors,
+ * formats the response received from the Tenderly API for output.
*
- * @param transactionOrigin
+ * @param transaction - The transaction to simulate.
+ * @param transactionOrigin - The origin of the transaction.
*/
export async function simulate(
transaction: { [key: string]: Json },
@@ -30,7 +35,7 @@ export async function simulate(
const credentials = await fetchCredentials(transactionOrigin);
if (!credentials) {
- return panel([text('🚨 Tenderly access key updated. Please try again.')]);
+ return panel([text('🚨 Tenderly access token updated. Please try again.')]);
}
const simulationResponse = await submitSimulation(transaction, credentials);
@@ -40,8 +45,12 @@ export async function simulate(
}
/**
+ * This function sends a request to the Tenderly API to simulate a transaction.
+ * It prepares the transaction data, sends it to the API, and if the simulation is successful,
+ * it makes the simulation publicly accessible.
*
- * @param credentials
+ * @param transaction - The transaction to simulate.
+ * @param credentials - Tenderly credentials object.
*/
async function submitSimulation(
transaction: { [key: string]: Json },
@@ -49,7 +58,7 @@ async function submitSimulation(
) {
const chainId = await ethereum.request({ method: 'eth_chainId' });
const response = await fetch(
- `https://api.tenderly.co/api/v1/account/${credentials.userId}/project/${credentials.projectId}/simulate`,
+ `https://api.tenderly.co/api/v1/account/${credentials.accountId}/project/${credentials.projectId}/simulate`,
{
method: 'POST',
body: JSON.stringify({
@@ -68,7 +77,7 @@ async function submitSimulation(
}),
headers: {
'Content-Type': 'application/json',
- 'X-Access-Key': credentials.accessKey,
+ 'X-Access-Key': credentials.accessToken,
},
},
);
@@ -78,12 +87,12 @@ async function submitSimulation(
// Make the simulation publicly accessible
if (parsedResponse?.simulation?.id) {
await fetch(
- `https://api.tenderly.co/api/v1/account/${credentials.userId}/project/${credentials.projectId}/simulations/${parsedResponse.simulation.id}/share`,
+ `https://api.tenderly.co/api/v1/account/${credentials.accountId}/project/${credentials.projectId}/simulations/${parsedResponse.simulation.id}/share`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
- 'X-Access-Key': credentials.accessKey,
+ 'X-Access-Key': credentials.accessToken,
},
},
);
@@ -93,9 +102,13 @@ async function submitSimulation(
}
/**
+ * This function handles any errors that might occur during the simulation of the transaction.
+ * It checks if a transaction or error message is included in the data returned from the simulation,
+ * and if an error is found, it creates a formatted error response.
*
- * @param data
- * @param credentials
+ * @param data - Simulation API response.
+ * @param credentials - Tenderly credentials object.
+ * @returns Panel - MetaMask Snap panel.
*/
function catchError(data: any, credentials: TenderlyCredentials): Panel | null {
if (!data.transaction) {
diff --git a/packages/snap/src/tenderly/utils.ts b/packages/snap/src/tenderly/utils.ts
index b64a19a..d599968 100644
--- a/packages/snap/src/tenderly/utils.ts
+++ b/packages/snap/src/tenderly/utils.ts
@@ -2,8 +2,10 @@ import { Panel } from '@metamask/snaps-ui';
import { Json } from '@metamask/utils';
/**
+ * Converts hex value to integer.
*
- * @param hex
+ * @param hex - Hex value.
+ * @returns Integer value.
*/
export function hex2int(hex: string | Json): number | null {
return hex ? parseInt(hex.toString(), 16) : null;
@@ -16,7 +18,7 @@ export function hex2int(hex: string | Json): number | null {
* @param r
*/
export function strReplaceAll(o: string, s: string, r: string): string {
- return o.replace(new RegExp(s, 'g'), r);
+ return o.replace(new RegExp(s, 'gu'), r);
}
/**
diff --git a/yarn.lock b/yarn.lock
index b7f7fed..bdfab62 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1599,6 +1599,16 @@ __metadata:
languageName: node
linkType: hard
+"@ethereumjs/common@npm:^3.2.0":
+ version: 3.2.0
+ resolution: "@ethereumjs/common@npm:3.2.0"
+ dependencies:
+ "@ethereumjs/util": ^8.1.0
+ crc-32: ^1.2.0
+ checksum: cb9cc11f5c868cb577ba611cebf55046e509218bbb89b47ccce010776dafe8256d70f8f43fab238aec74cf71f62601cd5842bc03a83261200802de365732a14b
+ languageName: node
+ linkType: hard
+
"@ethereumjs/rlp@npm:^4.0.1":
version: 4.0.1
resolution: "@ethereumjs/rlp@npm:4.0.1"
@@ -1627,6 +1637,18 @@ __metadata:
languageName: node
linkType: hard
+"@ethereumjs/tx@npm:^4.1.2":
+ version: 4.2.0
+ resolution: "@ethereumjs/tx@npm:4.2.0"
+ dependencies:
+ "@ethereumjs/common": ^3.2.0
+ "@ethereumjs/rlp": ^4.0.1
+ "@ethereumjs/util": ^8.1.0
+ ethereum-cryptography: ^2.0.0
+ checksum: 87a3f5f2452cfbf6712f8847525a80c213210ed453c211c793c5df801fe35ecef28bae17fadd222fcbdd94277478a47e52d2b916a90a6b30cda21f1e0cdaee42
+ languageName: node
+ linkType: hard
+
"@ethereumjs/util@npm:^8.0.5":
version: 8.0.5
resolution: "@ethereumjs/util@npm:8.0.5"
@@ -1638,6 +1660,17 @@ __metadata:
languageName: node
linkType: hard
+"@ethereumjs/util@npm:^8.1.0":
+ version: 8.1.0
+ resolution: "@ethereumjs/util@npm:8.1.0"
+ dependencies:
+ "@ethereumjs/rlp": ^4.0.1
+ ethereum-cryptography: ^2.0.0
+ micro-ftch: ^0.3.1
+ checksum: 9ae5dee8f12b0faf81cd83f06a41560e79b0ba96a48262771d897a510ecae605eb6d84f687da001ab8ccffd50f612ae50f988ef76e6312c752897f462f3ac08d
+ languageName: node
+ linkType: hard
+
"@ethersproject/abstract-provider@npm:^5.7.0":
version: 5.7.0
resolution: "@ethersproject/abstract-provider@npm:5.7.0"
@@ -2785,6 +2818,20 @@ __metadata:
languageName: node
linkType: hard
+"@metamask/utils@npm:^6.2.0":
+ version: 6.2.0
+ resolution: "@metamask/utils@npm:6.2.0"
+ dependencies:
+ "@ethereumjs/tx": ^4.1.2
+ "@noble/hashes": ^1.3.1
+ "@types/debug": ^4.1.7
+ debug: ^4.3.4
+ semver: ^7.3.8
+ superstruct: ^1.0.3
+ checksum: 0bc675358ecc09b3bc04da613d73666295d7afa51ff6b8554801585966900b24b8545bd93b8b2e9a17db867ebe421fe884baf3558ec4ca3199fa65504f677c1b
+ languageName: node
+ linkType: hard
+
"@mischnic/json-sourcemap@npm:^0.1.0":
version: 0.1.0
resolution: "@mischnic/json-sourcemap@npm:0.1.0"
@@ -2847,6 +2894,15 @@ __metadata:
languageName: node
linkType: hard
+"@noble/curves@npm:1.1.0, @noble/curves@npm:~1.1.0":
+ version: 1.1.0
+ resolution: "@noble/curves@npm:1.1.0"
+ dependencies:
+ "@noble/hashes": 1.3.1
+ checksum: 2658cdd3f84f71079b4e3516c47559d22cf4b55c23ac8ee9d2b1f8e5b72916d9689e59820e0f9d9cb4a46a8423af5b56dc6bb7782405c88be06a015180508db5
+ languageName: node
+ linkType: hard
+
"@noble/ed25519@npm:^1.6.0":
version: 1.7.3
resolution: "@noble/ed25519@npm:1.7.3"
@@ -2861,6 +2917,13 @@ __metadata:
languageName: node
linkType: hard
+"@noble/hashes@npm:1.3.1, @noble/hashes@npm:^1.3.1, @noble/hashes@npm:~1.3.0, @noble/hashes@npm:~1.3.1":
+ version: 1.3.1
+ resolution: "@noble/hashes@npm:1.3.1"
+ checksum: 7fdefc0f7a0c1ec27acc6ff88841793e3f93ec4ce6b8a6a12bfc0dd70ae6b7c4c82fe305fdfeda1735d5ad4a9eebe761e6693b3d355689c559e91242f4bc95b1
+ languageName: node
+ linkType: hard
+
"@noble/hashes@npm:^1.0.0":
version: 1.3.0
resolution: "@noble/hashes@npm:1.3.0"
@@ -3393,6 +3456,17 @@ __metadata:
languageName: node
linkType: hard
+"@scure/bip32@npm:1.3.1":
+ version: 1.3.1
+ resolution: "@scure/bip32@npm:1.3.1"
+ dependencies:
+ "@noble/curves": ~1.1.0
+ "@noble/hashes": ~1.3.1
+ "@scure/base": ~1.1.0
+ checksum: 394d65f77a40651eba21a5096da0f4233c3b50d422864751d373fcf142eeedb94a1149f9ab1dbb078086dab2d0bc27e2b1afec8321bf22d4403c7df2fea5bfe2
+ languageName: node
+ linkType: hard
+
"@scure/bip39@npm:1.1.1":
version: 1.1.1
resolution: "@scure/bip39@npm:1.1.1"
@@ -3403,6 +3477,16 @@ __metadata:
languageName: node
linkType: hard
+"@scure/bip39@npm:1.2.1":
+ version: 1.2.1
+ resolution: "@scure/bip39@npm:1.2.1"
+ dependencies:
+ "@noble/hashes": ~1.3.0
+ "@scure/base": ~1.1.0
+ checksum: c5bd6f1328fdbeae2dcdd891825b1610225310e5e62a4942714db51066866e4f7bef242c7b06a1b9dcc8043a4a13412cf5c5df76d3b10aa9e36b82e9b6e3eeaa
+ languageName: node
+ linkType: hard
+
"@sideway/address@npm:^4.1.3":
version: 4.1.4
resolution: "@sideway/address@npm:4.1.4"
@@ -3694,6 +3778,7 @@ __metadata:
"@metamask/snaps-cli": ^0.32.2
"@metamask/snaps-types": ^0.32.2
"@metamask/snaps-ui": ^0.32.2
+ "@metamask/utils": ^6.2.0
"@typescript-eslint/eslint-plugin": ^5.33.0
"@typescript-eslint/parser": ^5.33.0
buffer: ^6.0.3
@@ -8603,6 +8688,18 @@ __metadata:
languageName: node
linkType: hard
+"ethereum-cryptography@npm:^2.0.0":
+ version: 2.1.2
+ resolution: "ethereum-cryptography@npm:2.1.2"
+ dependencies:
+ "@noble/curves": 1.1.0
+ "@noble/hashes": 1.3.1
+ "@scure/bip32": 1.3.1
+ "@scure/bip39": 1.2.1
+ checksum: 2e8f7b8cc90232ae838ab6a8167708e8362621404d26e79b5d9e762c7b53d699f7520aff358d9254de658fcd54d2d0af168ff909943259ed27dc4cef2736410c
+ languageName: node
+ linkType: hard
+
"ethereumjs-util@npm:^7.0.10":
version: 7.1.5
resolution: "ethereumjs-util@npm:7.1.5"
@@ -12150,6 +12247,13 @@ __metadata:
languageName: node
linkType: hard
+"micro-ftch@npm:^0.3.1":
+ version: 0.3.1
+ resolution: "micro-ftch@npm:0.3.1"
+ checksum: 0e496547253a36e98a83fb00c628c53c3fb540fa5aaeaf718438873785afd193244988c09d219bb1802984ff227d04938d9571ef90fe82b48bd282262586aaff
+ languageName: node
+ linkType: hard
+
"micromatch@npm:^4.0.4, micromatch@npm:^4.0.5":
version: 4.0.5
resolution: "micromatch@npm:4.0.5"