diff --git a/apps/remix-ide/contracts/ballot.sol b/apps/remix-ide/contracts/ballot.sol index 1ebc747b44..aa49825fac 100644 --- a/apps/remix-ide/contracts/ballot.sol +++ b/apps/remix-ide/contracts/ballot.sol @@ -101,6 +101,7 @@ contract Ballot { Voter storage sender = voters[msg.sender]; require(sender.weight != 0, "Has no right to vote"); require(!sender.voted, "Already voted."); + require(proposal < proposals.length, "Invalid proposal index."); sender.voted = true; sender.vote = proposal; diff --git a/apps/remix-ide/src/app/plugins/solcoderAI.tsx b/apps/remix-ide/src/app/plugins/solcoderAI.tsx index 81478a40be..609c47032e 100644 --- a/apps/remix-ide/src/app/plugins/solcoderAI.tsx +++ b/apps/remix-ide/src/app/plugins/solcoderAI.tsx @@ -47,6 +47,12 @@ export class SolCoder extends Plugin { this.solgpt_chat_history = [] } + pushChatHistory(prompt, result){ + const chat:ChatEntry = [prompt, result.data[0]] + this.solgpt_chat_history.push(chat) + if (this.solgpt_chat_history.length > this.max_history){this.solgpt_chat_history.shift()} + } + async code_generation(prompt): Promise { this.emit("aiInfering") this.call('layout', 'maximizeTerminal') @@ -105,9 +111,7 @@ export class SolCoder extends Plugin { } if (result) { this.call('terminal', 'log', { type: 'aitypewriterwarning', value: result.data[0] }) - const chat:ChatEntry = [prompt, result.data[0]] - this.solgpt_chat_history.push(chat) - if (this.solgpt_chat_history.length >this.max_history){this.solgpt_chat_history.shift()} + this.pushChatHistory(prompt, result) } else if (result.error) { this.call('terminal', 'log', { type: 'aitypewriterwarning', value: "Error on request" }) } @@ -134,6 +138,7 @@ export class SolCoder extends Plugin { ).json() if (result) { this.call('terminal', 'log', { type: 'aitypewriterwarning', value: result.data[0] }) + this.pushChatHistory(prompt, result) } return result.data[0] } catch (e) { @@ -250,6 +255,7 @@ export class SolCoder extends Plugin { ).json() if (result) { this.call('terminal', 'log', { type: 'aitypewriterwarning', value: result.data[0] }) + this.pushChatHistory(prompt, result) } return result.data[0] } catch (e) { diff --git a/apps/remix-ide/src/app/tabs/locales/en/editor.json b/apps/remix-ide/src/app/tabs/locales/en/editor.json index 33643eb0bb..f68c83026f 100644 --- a/apps/remix-ide/src/app/tabs/locales/en/editor.json +++ b/apps/remix-ide/src/app/tabs/locales/en/editor.json @@ -21,7 +21,7 @@ "editor.formatCode": "Format Code", "editor.generateDocumentation": "Generate documentation for this function", "editor.generateDocumentation2": "Generate documentation for the function \"{name}\"", - "editor.generateDocumentationByAI": "solidity code: {content}\n Generate the documentation for the function {currentFunction} using the Doxygen style syntax", + "editor.generateDocumentationByAI": "solidity code: {content}\n Generate the natspec documentation for the function {currentFunction} using the docstring style syntax. Only use docstring supported tags", "editor.explainFunction": "Explain this function", "editor.explainFunctionSol": "Explain this code", "editor.explainFunction2": "Explain the function \"{name}\"", diff --git a/libs/remix-simulator/src/methods/accounts.ts b/libs/remix-simulator/src/methods/accounts.ts index 5151499d9f..61766e1631 100644 --- a/libs/remix-simulator/src/methods/accounts.ts +++ b/libs/remix-simulator/src/methods/accounts.ts @@ -1,11 +1,17 @@ +import { signTypedData, SignTypedDataVersion, TypedMessage, MessageTypes } from '@metamask/eth-sig-util' import { privateToAddress, toChecksumAddress, isValidPrivate, Address, toBytes, bytesToHex, Account } from '@ethereumjs/util' import { privateKeyToAccount } from 'web3-eth-accounts' import { toBigInt } from 'web3-utils' import * as crypto from 'crypto' +type AccountType = { + nonce: number, + privateKey: Uint8Array +} + export class Web3Accounts { - accounts: Record - accountsKeys: Record + accounts: Record + accountsKeys: Record vmContext constructor (vmContext) { @@ -73,7 +79,9 @@ export class Web3Accounts { eth_accounts: this.eth_accounts.bind(this), eth_getBalance: this.eth_getBalance.bind(this), eth_sign: this.eth_sign.bind(this), - eth_chainId: this.eth_chainId.bind(this) + eth_chainId: this.eth_chainId.bind(this), + eth_signTypedData: this.eth_signTypedData_v4.bind(this), // default call is using V4 + eth_signTypedData_v4: this.eth_signTypedData_v4.bind(this) } } @@ -108,4 +116,49 @@ export class Web3Accounts { eth_chainId (_payload, cb) { return cb(null, '0x539') // 0x539 is hex of 1337 } + + eth_signTypedData_v4 (payload, cb) { + const address: string = payload.params[0] + const typedData: TypedMessage = payload.params[1] + + try { + if (this.accounts[toChecksumAddress(address)] == null) { + throw new Error("cannot sign data; no private key"); + } + + if (typeof typedData === "string") { + throw new Error("cannot sign data; string sent, expected object"); + } + + if (!typedData.types) { + throw new Error("cannot sign data; types missing"); + } + + if (!typedData.types.EIP712Domain) { + throw new Error("cannot sign data; EIP712Domain definition missing"); + } + + if (!typedData.domain) { + throw new Error("cannot sign data; domain missing"); + } + + if (!typedData.primaryType) { + throw new Error("cannot sign data; primaryType missing"); + } + + if (!typedData.message) { + throw new Error("cannot sign data; message missing"); + } + + const ret = signTypedData({ + privateKey: Buffer.from(this.accounts[toChecksumAddress(address)].privateKey), + data: typedData, + version: SignTypedDataVersion.V4 + }) + + cb(null, ret) + } catch (e) { + cb(e.message) + } + } } diff --git a/libs/remix-simulator/src/provider.ts b/libs/remix-simulator/src/provider.ts index 27918a4359..b6c52345fe 100644 --- a/libs/remix-simulator/src/provider.ts +++ b/libs/remix-simulator/src/provider.ts @@ -11,7 +11,6 @@ import { Transactions } from './methods/transactions' import { Debug } from './methods/debug' import { VMContext } from './vm-context' import { Web3PluginBase } from 'web3' -import { Block } from '@ethereumjs/block' export interface JSONRPCRequestPayload { params: any[]; @@ -109,11 +108,11 @@ export class Provider { callback(new Error('unknown method ' + payload.method)) } - sendAsync (payload: JSONRPCRequestPayload, callback: (err: Error, result?: JSONRPCResponsePayload) => void) { + async sendAsync (payload: JSONRPCRequestPayload, callback?: (err: Error, result?: JSONRPCResponsePayload) => void) : Promise { return new Promise((resolve,reject)=>{ const cb = (err, result) => { if (typeof callback==='function'){ - callback(err,result) + return callback(err, result) } if (err){ return reject(err) @@ -125,7 +124,12 @@ export class Provider { } send (payload, callback) { - return this.sendAsync(payload,callback) + this.sendAsync(payload, callback) + } + + async request (payload: JSONRPCRequestPayload) : Promise { + const ret = await this.sendAsync(payload) + return ret.result } isConnected () { diff --git a/libs/remix-simulator/test/accounts.ts b/libs/remix-simulator/test/accounts.ts index cb923e209a..17635383fc 100644 --- a/libs/remix-simulator/test/accounts.ts +++ b/libs/remix-simulator/test/accounts.ts @@ -39,4 +39,40 @@ describe('Accounts', () => { assert.deepEqual(typeof signature === 'string' ? signature.length : signature.signature.length, 132) }) }) + + describe('eth_signTypedData', () => { + it('should sign typed data', async () => { + const accounts: string[] = await web3.eth.getAccounts() + const typedData = { + domain: { + chainId: 1, + name: "Example App", + verifyingContract: "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC", + version: "1", + }, + message: { + prompt: "Welcome! In order to authenticate to this website, sign this request and your public address will be sent to the server in a verifiable way.", + createdAt: 1718570375196, + }, + primaryType: 'AuthRequest', + types: { + EIP712Domain: [ + { name: 'name', type: 'string' }, + { name: 'version', type: 'string' }, + { name: 'chainId', type: 'uint256' }, + { name: 'verifyingContract', type: 'address' }, + ], + AuthRequest: [ + { name: 'prompt', type: 'string' }, + { name: 'createdAt', type: 'uint256' }, + ], + }, + }; + const result = await web3.currentProvider.request({ + method: 'eth_signTypedData', + params: [accounts[0], typedData] + }) + assert.equal(result, '0x248d23de0e23231370db8aa21ad5908ca90c33ae2b8c611b906674bda6b1a8b85813f945c2ea896316e240089029619ab3d801a1b098c199bd462dd8026349da1c') + }) + }) }) diff --git a/libs/remix-ui/editor/src/lib/providers/documentationProvider.ts b/libs/remix-ui/editor/src/lib/providers/documentationProvider.ts new file mode 100644 index 0000000000..3998ce8fb3 --- /dev/null +++ b/libs/remix-ui/editor/src/lib/providers/documentationProvider.ts @@ -0,0 +1,37 @@ +/* eslint-disable no-control-regex */ +import { EditorUIProps, monacoTypes } from '@remix-ui/editor'; + +export class RemixSolidityDocumentationProvider implements monacoTypes.languages.InlineCompletionsProvider{ + props:EditorUIProps + monaco:any + completion:string + + constructor(completion: any){ + this.completion = completion + } + + async provideInlineCompletions(model: monacoTypes.editor.ITextModel, position: monacoTypes.Position, context: monacoTypes.languages.InlineCompletionContext, token: monacoTypes.CancellationToken): Promise> { + const item: monacoTypes.languages.InlineCompletion = { + insertText: this.completion + }; + return { + items: [item], + enableForwardStability: true + } + } + + handleItemDidShow?(completions: monacoTypes.languages.InlineCompletions, item: monacoTypes.languages.InlineCompletion, updatedInsertText: string): void { + + } + handlePartialAccept?(completions: monacoTypes.languages.InlineCompletions, item: monacoTypes.languages.InlineCompletion, acceptedCharacters: number): void { + + } + freeInlineCompletions(completions: monacoTypes.languages.InlineCompletions): void { + + } + groupId?: string; + yieldsToGroupIds?: string[]; + toString?(): string { + throw new Error('Method not implemented.'); + } +} \ No newline at end of file diff --git a/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx b/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx index 6f5518826b..7805223b87 100644 --- a/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx +++ b/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx @@ -16,6 +16,7 @@ import { retrieveNodesAtPosition } from './helpers/retrieveNodesAtPosition' import { RemixHoverProvider } from './providers/hoverProvider' import { RemixReferenceProvider } from './providers/referenceProvider' import { RemixCompletionProvider } from './providers/completionProvider' +import { RemixSolidityDocumentationProvider } from './providers/documentationProvider' import { RemixHighLightProvider } from './providers/highlightProvider' import { RemixDefinitionProvider } from './providers/definitionProvider' import { RemixCodeActionProvider } from './providers/codeActionProvider' @@ -23,6 +24,7 @@ import './remix-ui-editor.css' import { circomLanguageConfig, circomTokensProvider } from './syntaxes/circom' import { IPosition } from 'monaco-editor' import { RemixInLineCompletionProvider } from './providers/inlineCompletionProvider' +import { providers } from 'ethers' const _paq = (window._paq = window._paq || []) enum MarkerSeverity { @@ -174,6 +176,8 @@ export const EditorUI = (props: EditorUIProps) => { const currentFunction = useRef('') const currentFileRef = useRef('') const currentUrlRef = useRef('') + let currenFunctionNode = useRef('') + // const currentDecorations = useRef({ sourceAnnotationsPerFile: {}, markerPerFile: {} }) // decorations that are currently in use by the editor // const registeredDecorations = useRef({}) // registered decorations @@ -713,6 +717,12 @@ export const EditorUI = (props: EditorUIProps) => { } let gptGenerateDocumentationAction + const extractNatspecComments = (codeString: string): string => { + const natspecCommentRegex = /\/\*\*[\s\S]*?\*\//g; + const comments = codeString.match(natspecCommentRegex); + return comments ? comments[0] : ""; + } + const executeGptGenerateDocumentationAction = { id: 'generateDocumentation', label: intl.formatMessage({ id: 'editor.generateDocumentation' }), @@ -723,10 +733,46 @@ export const EditorUI = (props: EditorUIProps) => { monacoRef.current.KeyMod.CtrlCmd | monacoRef.current.KeyCode.KeyD ], run: async () => { + const unsupportedDocTags = ['@title'] // these tags are not supported by the current docstring parser const file = await props.plugin.call('fileManager', 'getCurrentFile') const content = await props.plugin.call('fileManager', 'readFile', file) const message = intl.formatMessage({ id: 'editor.generateDocumentationByAI' }, { content, currentFunction: currentFunction.current }) - await props.plugin.call('solcoder', 'code_explaining', message) + const cm = await props.plugin.call('solcoder', 'code_explaining', message) + + const natSpecCom = "\n" + extractNatspecComments(cm) + const cln = await props.plugin.call('codeParser', "getLineColumnOfNode", currenFunctionNode) + const range = new monacoRef.current.Range(cln.start.line, cln.start.column, cln.start.line, cln.start.column) + + const lines = natSpecCom.split('\n') + const newNatSpecCom = [] + + for (let i = 0; i < lines.length; i++) { + let cont = false + + for (let j = 0; j < unsupportedDocTags.length; j++) { + if (lines[i].includes(unsupportedDocTags[j])) { + cont = true + break + } + } + if (cont) {continue} + + if (i <= 1) { newNatSpecCom.push(' '.repeat(cln.start.column) + lines[i].trimStart()) } + else { newNatSpecCom.push(' '.repeat(cln.start.column + 1) + lines[i].trimStart()) } + } + + // TODO: activate the provider to let the user accept the documentation suggestion + // const provider = new RemixSolidityDocumentationProvider(natspecCom) + // monacoRef.current.languages.registerInlineCompletionsProvider('solidity', provider) + + editor.executeEdits('clipboard', [ + { + range: range, + text: newNatSpecCom.join('\n'), + forceMoveMarkers: true, + }, + ]); + _paq.push(['trackEvent', 'ai', 'solcoder', 'generateDocumentation']) }, } @@ -845,6 +891,8 @@ export const EditorUI = (props: EditorUIProps) => { const functionImpl = nodesAtPosition.find((node) => node.kind === 'function') if (functionImpl) { currentFunction.current = functionImpl.name + currenFunctionNode = functionImpl + executeGptGenerateDocumentationAction.label = intl.formatMessage({ id: 'editor.generateDocumentation2' }, { name: functionImpl.name }) gptGenerateDocumentationAction = editor.addAction(executeGptGenerateDocumentationAction) executegptExplainFunctionAction.label = intl.formatMessage({ id: 'editor.explainFunction2' }, { name: functionImpl.name }) diff --git a/package.json b/package.json index 4de5d00c80..e49a728d3c 100644 --- a/package.json +++ b/package.json @@ -100,6 +100,7 @@ "@floating-ui/react": "^0.26.15", "@gradio/client": "^0.10.1", "@isomorphic-git/lightning-fs": "^4.4.1", + "@metamask/eth-sig-util": "^7.0.2", "@microlink/react-json-view": "^1.23.0", "@openzeppelin/contracts": "^5.0.0", "@openzeppelin/upgrades-core": "^1.30.0", @@ -364,6 +365,7 @@ "webpack-cli": "^4.10.0" }, "resolutions": { + "@metamask/eth-sig-util/@ethereumjs/util": "^8.1.0", "@types/react": "^18.2.0", "@ethereumjs/blockchain": "7.2.0", "@ethereumjs/block": "5.2.0", diff --git a/yarn.lock b/yarn.lock index 0a9d3258c2..c5ea40bc83 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2379,6 +2379,15 @@ "@ethereumjs/rlp" "^5.0.2" ethereum-cryptography "^2.1.3" +"@ethereumjs/util@^8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/util/-/util-8.1.0.tgz#299df97fb6b034e0577ce9f94c7d9d1004409ed4" + integrity sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA== + dependencies: + "@ethereumjs/rlp" "^4.0.1" + ethereum-cryptography "^2.0.0" + micro-ftch "^0.3.1" + "@ethereumjs/verkle@^0.0.2": version "0.0.2" resolved "https://registry.yarnpkg.com/@ethereumjs/verkle/-/verkle-0.0.2.tgz#1c3c3d23e859e15b61c3d60a125962e761f3e135" @@ -4025,6 +4034,14 @@ dependencies: cross-spawn "^7.0.1" +"@metamask/abi-utils@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@metamask/abi-utils/-/abi-utils-2.0.2.tgz#ad394e9cb8a95ac177cad942daadd88a246c0de8" + integrity sha512-B/A1dY/w4F/t6cDHUscklO6ovb/ztFsrsTXFd8QlqSByk/vyy+QbPE3VVpmmyI/7RX+PA1AJcvBdzCIz+r9dVQ== + dependencies: + "@metamask/utils" "^8.0.0" + superstruct "^1.0.3" + "@metamask/eth-json-rpc-provider@^1.0.0": version "1.0.1" resolved "https://registry.yarnpkg.com/@metamask/eth-json-rpc-provider/-/eth-json-rpc-provider-1.0.1.tgz#3fd5316c767847f4ca107518b611b15396a5a32c" @@ -4045,6 +4062,18 @@ tweetnacl "^1.0.3" tweetnacl-util "^0.15.1" +"@metamask/eth-sig-util@^7.0.2": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@metamask/eth-sig-util/-/eth-sig-util-7.0.2.tgz#741de634b0d6ca96ce1ee3d064ac6a27756d8d21" + integrity sha512-DhTDMNEtED0ihIc4Tysm6qUJTvArCdgSTeeJWdo526W/cAk5mrSAvEYYgv8idAiBumDtcPWGimMTaB7MvY64bg== + dependencies: + "@ethereumjs/util" "^8.1.0" + "@metamask/abi-utils" "^2.0.2" + "@metamask/utils" "^8.1.0" + "@scure/base" "~1.1.3" + ethereum-cryptography "^2.1.2" + tweetnacl "^1.0.3" + "@metamask/json-rpc-engine@^7.0.0": version "7.3.2" resolved "https://registry.yarnpkg.com/@metamask/json-rpc-engine/-/json-rpc-engine-7.3.2.tgz#e8f0695811619eef7b7c894ba5cf782db9f1c2cb" @@ -4072,6 +4101,11 @@ resolved "https://registry.yarnpkg.com/@metamask/safe-event-emitter/-/safe-event-emitter-3.0.0.tgz#8c2b9073fe0722d48693143b0dc8448840daa3bd" integrity sha512-j6Z47VOmVyGMlnKXZmL0fyvWfEYtKWCA9yGZkU3FCsGZUT5lHGmvaV9JA5F2Y+010y7+ROtR3WMXIkvl/nVzqQ== +"@metamask/superstruct@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@metamask/superstruct/-/superstruct-3.0.0.tgz#0200d0a627522904a7e0fd751dcc6fb863cefacb" + integrity sha512-TOm+Lt/lCJk9j/3QT2LucrPewRmqI7/GKT+blK2IIOAkBMS+9TmeNjd2Y+TlfpSSYstaYsGZyz1XwpiTCg6RLA== + "@metamask/utils@^5.0.1": version "5.0.2" resolved "https://registry.yarnpkg.com/@metamask/utils/-/utils-5.0.2.tgz#140ba5061d90d9dac0280c19cab101bc18c8857c" @@ -4083,6 +4117,21 @@ semver "^7.3.8" superstruct "^1.0.3" +"@metamask/utils@^8.0.0": + version "8.5.0" + resolved "https://registry.yarnpkg.com/@metamask/utils/-/utils-8.5.0.tgz#ddd0d4012d5191809404c97648a837ea9962cceb" + integrity sha512-I6bkduevXb72TIM9q2LRO63JSsF9EXduh3sBr9oybNX2hNNpr/j1tEjXrsG0Uabm4MJ1xkGAQEMwifvKZIkyxQ== + 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" + "@metamask/utils@^8.1.0", "@metamask/utils@^8.3.0": version "8.3.0" resolved "https://registry.yarnpkg.com/@metamask/utils/-/utils-8.3.0.tgz#a20de447aeb9ffb75924d822a186a597033984b6" @@ -4234,6 +4283,13 @@ dependencies: "@noble/hashes" "1.3.3" +"@noble/curves@1.4.0", "@noble/curves@~1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.4.0.tgz#f05771ef64da724997f69ee1261b2417a49522d6" + integrity sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg== + dependencies: + "@noble/hashes" "1.4.0" + "@noble/hashes@1.2.0", "@noble/hashes@~1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.2.0.tgz#a3150eeb09cc7ab207ebf6d7b9ad311a9bdbed12" @@ -4249,6 +4305,11 @@ resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.3.tgz#39908da56a4adc270147bb07968bf3b16cfe1699" integrity sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA== +"@noble/hashes@1.4.0", "@noble/hashes@~1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.4.0.tgz#45814aa329f30e4fe0ba49426f49dfccdd066426" + integrity sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg== + "@noble/secp256k1@1.7.1", "@noble/secp256k1@~1.7.0": version "1.7.1" resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.1.tgz#b251c70f824ce3ca7f8dc3df08d58f005cc0507c" @@ -5575,6 +5636,11 @@ resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938" integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA== +"@scure/base@~1.1.3", "@scure/base@~1.1.6": + version "1.1.6" + resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.6.tgz#8ce5d304b436e4c84f896e0550c83e4d88cb917d" + integrity sha512-ok9AWwhcgYuGG3Zfhyqg+zwl+Wn5uE+dwC0NV/2qQkx4dABbb/bx96vWu8NSj+BNjjSjno+JRYRjle1jV08k3g== + "@scure/bip32@1.1.5": version "1.1.5" resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.1.5.tgz#d2ccae16dcc2e75bc1d75f5ef3c66a338d1ba300" @@ -5602,6 +5668,15 @@ "@noble/hashes" "~1.3.2" "@scure/base" "~1.1.4" +"@scure/bip32@1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.4.0.tgz#4e1f1e196abedcef395b33b9674a042524e20d67" + integrity sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg== + dependencies: + "@noble/curves" "~1.4.0" + "@noble/hashes" "~1.4.0" + "@scure/base" "~1.1.6" + "@scure/bip39@1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.1.1.tgz#b54557b2e86214319405db819c4b6a370cf340c5" @@ -5626,6 +5701,14 @@ "@noble/hashes" "~1.3.2" "@scure/base" "~1.1.4" +"@scure/bip39@1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.3.0.tgz#0f258c16823ddd00739461ac31398b4e7d6a18c3" + integrity sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ== + dependencies: + "@noble/hashes" "~1.4.0" + "@scure/base" "~1.1.6" + "@sentry/core@5.30.0": version "5.30.0" resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.30.0.tgz#6b203664f69e75106ee8b5a2fe1d717379b331f3" @@ -13744,6 +13827,16 @@ ethereum-cryptography@^2.0.0: "@scure/bip32" "1.3.0" "@scure/bip39" "1.2.0" +ethereum-cryptography@^2.1.2: + version "2.2.0" + resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-2.2.0.tgz#06e2d9c0d89f98ffc6a83818f55bf85afecd50dc" + integrity sha512-hsm9JhfytIf8QME/3B7j4bc8V+VdTU+Vas1aJlvIS96ffoNAosudXvGoEvWmc7QZYdkC8mrMJz9r0fcbw7GyCA== + dependencies: + "@noble/curves" "1.4.0" + "@noble/hashes" "1.4.0" + "@scure/bip32" "1.4.0" + "@scure/bip39" "1.3.0" + ethereum-cryptography@^2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-2.1.3.tgz#1352270ed3b339fe25af5ceeadcf1b9c8e30768a" @@ -20235,6 +20328,11 @@ methods@~1.1.2: resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= +micro-ftch@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/micro-ftch/-/micro-ftch-0.3.1.tgz#6cb83388de4c1f279a034fb0cf96dfc050853c5f" + integrity sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg== + micromark-core-commonmark@^1.0.0, micromark-core-commonmark@^1.0.1: version "1.0.6" resolved "https://registry.yarnpkg.com/micromark-core-commonmark/-/micromark-core-commonmark-1.0.6.tgz#edff4c72e5993d93724a3c206970f5a15b0585ad" @@ -29076,6 +29174,11 @@ uuid@^8.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== +uuid@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" + integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== + uvu@^0.5.0: version "0.5.6" resolved "https://registry.yarnpkg.com/uvu/-/uvu-0.5.6.tgz#2754ca20bcb0bb59b64e9985e84d2e81058502df"