diff --git a/.npmrc b/.npmrc new file mode 100644 index 00000000..10663593 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +link-workspace-packages: false \ No newline at end of file diff --git a/packages/react-sdk/.eslintrc.cjs b/packages/react-sdk/.eslintrc.cjs new file mode 100644 index 00000000..f2fa9300 --- /dev/null +++ b/packages/react-sdk/.eslintrc.cjs @@ -0,0 +1,8 @@ +module.exports = { + parserOptions: { + project: "./tsconfig.json", + tsconfigRootDir: __dirname, + EXPERIMENTAL_useProjectService: true, + }, + extends: ["@story-protocol/eslint-config"], +}; diff --git a/packages/react-sdk/README.MD b/packages/react-sdk/README.MD new file mode 100644 index 00000000..33dee23c --- /dev/null +++ b/packages/react-sdk/README.MD @@ -0,0 +1,78 @@ +# Story Protocol React SDK + +The react-sdk is a library that provides a set of hooks to interact with the SDK. It is designed to be used in a React application. + +## How to use Story Protocol SDK in Your Project + +### Generate React SDK + +1. Install the dependencies + +```bash +pnpm install +``` + +2. Update the `@story-protocol/core-sdk` package version in the `packages/react-sdk/package.json` file to the latest version. + +3. Generate the SDK + +```bash +pnpm run generate +``` + +This SDK is generated using the command `pnpm run generate`. The source code resides in the `packages/sdk` directory and the generated SDK can be found in the `packages/react-sdk` folder. + +### How to use Story Protocol React SDK in Your Project + +- Install Story Protocol React SDK + +```bash +pnpm install +``` + +- Import the provider in your React application + +```typescript +import { StoryProvider } from "@story-protocol/react-sdk"; +const client = StoryClient.newClient(config); + + +; +``` + +- Use the hooks in your components + +```typescript +import { useIpAsset } from "@story-protocol/react-sdk"; +const { data, error, loading, register } = useIpAsset(); +register({ nftContract: "0x1234", tokenId: "1" }); +``` + +### How To Build and Test Story Protocol React SDK for local testing + +- Install yalc + +```bash +npm install -g yalc +``` + +- For manual testing of the react-sdk, set up a separate web project. The guide below uses `yalc` to link the `react-sdk` locally, enabling its installation and import for testing. + +Under the `typescript-sdk/packages/react-sdk` directory: + +- Execute `npm run build` to build your latest code. +- Run `yalc publish`. You should see a message like `@story-protocol/react-sdk@ published in store.` (Note: The version number may vary). +- To set up your testing environment (e.g., a new Next.js project), use `yalc add @story-protocol/react-sdk@` (ensure the version number is updated accordingly). + +- Run `pnpm install`. This installs `@story-protocol/react-sdk@` with your local changes. + +### Steps to Refresh the Changes + +Under the `typescript-sdk/packages/react-sdk` directory: + +- Execute `npm run build` to build your latest code. +- Run `yalc push`. + +In your testing environment: + +- Run `yalc update` to pull the latest changes. diff --git a/packages/react-sdk/generator/index.js b/packages/react-sdk/generator/index.js new file mode 100644 index 00000000..c2338613 --- /dev/null +++ b/packages/react-sdk/generator/index.js @@ -0,0 +1,124 @@ +const ejs = require("ejs"); +const fs = require("fs"); +const path = require("path"); +const ts = require("typescript"); +const resourcesFolder = path.resolve(__dirname, "../../core-sdk/src/resources"); +const resourceTemplate = require("./templates/resource"); +const indexTemplate = require("./templates/index"); + +console.log("🚀🚀 React SDK generator started!"); +console.log(); +const isPrimitiveType = (type) => { + return [ + "string", + "number", + "boolean", + "symbol", + "undefined", + "null", + "bigint", + "string|bigint|number", + ].includes(type); +}; +const isViemType = (type) => { + return ["Hex", "Address"].includes(type); +}; +const visit = (file) => { + let program = ts.createProgram([file], { allowJs: true }); + const sourceFile = program.getSourceFile(file); + const checker = ts.createProgram([sourceFile.fileName], {}).getTypeChecker(); + const publicMethods = []; + ts.forEachChild(sourceFile, (node) => { + if (ts.isClassDeclaration(node)) { + for (const member of node.members) { + if ( + ts.isMethodDeclaration(member) && + (member.modifiers?.some( + (m) => m.kind === ts.SyntaxKind.PublicKeyword + ) ?? + true) && + member.name && + ts.isIdentifier(member.name) + ) { + const requests = []; + const methodSignature = program + .getTypeChecker() + .getSignatureFromDeclaration(member); + member.parameters.forEach((parameter) => { + requests.push({ + name: parameter.name.escapedText, + type: parameter.type.getText(), + }); + }); + const method = { + name: member.name.text, + requests, + responseType: member.type + ?.getText() + .replace("Promise<", "") + .replace(">", ""), + comments: + ts + .getLeadingCommentRanges(sourceFile.text, member.pos) + ?.map((range) => + sourceFile.text.substring(range.pos, range.end).trim() + ) || [], + }; + publicMethods.push(method); + } + } + } + }); + return publicMethods; +}; +let fileNames = []; +fs.readdirSync(resourcesFolder).forEach((file) => { + let sources = []; + const fileName = + file.replace(".ts", "").charAt(0).toUpperCase() + + file.replace(".ts", "").slice(1); + fileNames.push(fileName); + const methods = visit(path.resolve(resourcesFolder, file)); + const methodNames = methods.map((method) => method.name); + const types = methods.reduce( + (acc, curr) => + acc.concat( + curr.requests.map((item) => item.type), + curr.responseType + ), + [] + ); + + sources.push( + ejs.render(resourceTemplate.startTemplate, { + types: [ + ...new Set( + types + .filter((type) => !isPrimitiveType(type)) + .filter((type) => !isViemType(type)) + ), + ], + name: fileName, + methodNames, + viemTypes: [...new Set(types.filter((type) => isViemType(type)))], + }) + ); + const methodTemplates = methods.map((method) => { + return ejs.render(resourceTemplate.methodTemplate, { + method: method, + fileName: file.replace(".ts", ""), + comments: method.comments, + }); + }); + + sources = sources.concat( + methodTemplates, + ejs.render(resourceTemplate.endTemplate, { methodNames, name: fileName }) + ); + fs.writeFileSync(`src/resources/use${fileName}.ts`, sources.join("\n")); +}); + +const indexSource = ejs.render(indexTemplate, { resources: fileNames }); +fs.writeFileSync("src/index.ts", indexSource); + +console.log("👍👍 React SDK templates generated successfully!"); diff --git a/packages/react-sdk/generator/templates/index.js b/packages/react-sdk/generator/templates/index.js new file mode 100644 index 00000000..4410fa15 --- /dev/null +++ b/packages/react-sdk/generator/templates/index.js @@ -0,0 +1,7 @@ +const indexTemplate = ` +export { StoryProvider } from "./StoryProtocolContext"; +<% resources.forEach((resource) => {%> +export { default as use<%=resource %> } from "./resources/use<%=resource %>"; +<%})%> +`; +module.exports = indexTemplate; diff --git a/packages/react-sdk/generator/templates/resource.js b/packages/react-sdk/generator/templates/resource.js new file mode 100644 index 00000000..0bc69e71 --- /dev/null +++ b/packages/react-sdk/generator/templates/resource.js @@ -0,0 +1,44 @@ +const methodTemplate = `<%=comments%>\nconst <%=method.name %> = async (<% method.requests.forEach((item, index)=> { %> + <%= item.name %>: <%= item.type %><%= index === method.requests.length - 1 ? '' : ',' %> + <% }); %>): Promise<<%- method.responseType %>> => { + try { + setLoadings((prev) => ({ ...prev, <%=method.name %>: true })); + setErrors((prev) => ({ ...prev, <%=method.name %>: null })); + const response = await client.<%= fileName%>.<%=method.name %>(<% method.requests.forEach((item,index)=>{%> + <%=item.name %><%=index === method.requests.length - 1 ? '' : ',' %> + <% })%>); + setLoadings((prev ) => ({ ...prev, <%=method.name %>: false })); + return response; + }catch(e){ + if(e instanceof Error){ + setErrors((prev) => ({ ...prev, <%=method.name %>: e.message })); + setLoadings((prev) => ({ ...prev, <%=method.name %>: false })); + } + throw new Error(\`unhandled error type\`); + } + }; + `; + +const startTemplate = `import { <% types.forEach((type,index)=>{%>\n<%=type %><%= index===types.length-1?'':','%><%})%> + } from "@story-protocol/core-sdk"; + <% if (viemTypes.length > 0) { %> + import { <% viemTypes.forEach((type, index) => { %>\n<%= type %><%= index === viemTypes.length - 1 ? '' : ',' %><% }) %> + } from "viem"; + <% } %> + + import { useState } from "react"; + import { useStoryContext } from "../StoryProtocolContext"; + const use<%=name %> = () => { + const client = useStoryContext(); + const [loadings,setLoadings] = useState>({<% methodNames.forEach((name,index)=>{%><%=name %>: false<%=index === methodNames.length - 1 ? '' : ',' %> <%})%>}); + const [errors,setErrors] = useState>({ <% methodNames.forEach((name,index)=>{%><%=name %>: null<%=index === methodNames.length - 1 ? '' : ',' %><%})%> }); + `; + +const endTemplate = `return { + loadings, + errors, + <% methodNames.forEach((name,index)=>{%><%=name %><%=index === methodNames.length - 1 ? '' : ',' %> + <%})%> + };}\nexport default use<%=name %>;`; + +module.exports = { startTemplate, endTemplate, methodTemplate }; diff --git a/packages/react-sdk/package.json b/packages/react-sdk/package.json new file mode 100644 index 00000000..54794067 --- /dev/null +++ b/packages/react-sdk/package.json @@ -0,0 +1,75 @@ +{ + "name": "@story-protocol/react-sdk", + "version": "1.0.0-rc.14", + "description": "The Story Protocol React SDK", + "main": "dist/story-protocol-react-sdk.cjs.js", + "module": "dist/story-protocol-react-sdk.esm.js", + "exports": { + ".": { + "module": "./dist/story-protocol-react-sdk.esm.js", + "default": "./dist/story-protocol-react-sdk.cjs.js" + }, + "./package.json": "./package.json" + }, + "scripts": { + "generator": "node ./generator/index.js && npm run fix", + "build": "pnpm run fix && preconstruct build", + "fix": "pnpm run format:fix && pnpm run lint:fix", + "format": "prettier --check .", + "format:fix": "prettier --write .", + "lint:fix": "pnpm run lint --fix", + "lint": "eslint ./src", + "tsc": "tsc --noEmit" + }, + "sideEffects": false, + "files": [ + "dist/**/*" + ], + "preconstruct": { + "entrypoints": [ + "index.ts" + ], + "exports": true, + "externals": [ + "react", + "@story-protocol/core-sdk" + ] + }, + "keywords": [ + "story-protocol", + "react", + "sdk", + "react hooks" + ], + "babel": { + "presets": [ + "@babel/preset-env", + "@babel/preset-typescript", + [ + "@babel/preset-react", + { + "runtime": "automatic" + } + ] + ] + }, + "license": "MIT", + "dependencies": { + "@story-protocol/core-sdk": "1.0.0-rc.14", + "ejs": "^3.1.10", + "react": "^18.3.1", + "viem": "^2.8.12" + }, + "devDependencies": { + "@babel/preset-env": "^7.22.20", + "@babel/preset-react": "^7.24.7", + "@babel/preset-typescript": "^7.23.0", + "@preconstruct/cli": "^2.8.1", + "@story-protocol/eslint-config": "workspace:*", + "@story-protocol/prettier-config": "workspace:*", + "@story-protocol/tsconfig": "workspace:*", + "@types/react": "^18.3.3", + "ts-node": "^10.9.1", + "typescript": "^5.4.5" + } +} diff --git a/packages/react-sdk/src/index.ts b/packages/react-sdk/src/index.ts new file mode 100644 index 00000000..ae398ee2 --- /dev/null +++ b/packages/react-sdk/src/index.ts @@ -0,0 +1,15 @@ +export { StoryProvider } from "./StoryProtocolContext"; + +export { default as useDispute } from "./resources/useDispute"; + +export { default as useIpAccount } from "./resources/useIpAccount"; + +export { default as useIpAsset } from "./resources/useIpAsset"; + +export { default as useLicense } from "./resources/useLicense"; + +export { default as useNftClient } from "./resources/useNftClient"; + +export { default as usePermission } from "./resources/usePermission"; + +export { default as useRoyalty } from "./resources/useRoyalty"; diff --git a/packages/react-sdk/src/resources/useDispute.ts b/packages/react-sdk/src/resources/useDispute.ts new file mode 100644 index 00000000..e4bbc07c --- /dev/null +++ b/packages/react-sdk/src/resources/useDispute.ts @@ -0,0 +1,126 @@ +import { + RaiseDisputeRequest, + RaiseDisputeResponse, + CancelDisputeRequest, + CancelDisputeResponse, + ResolveDisputeRequest, + ResolveDisputeResponse, +} from "@story-protocol/core-sdk"; +import { useState } from "react"; + +import { useStoryContext } from "../StoryProtocolContext"; + +const useDispute = () => { + const client = useStoryContext(); + const [loadings, setLoadings] = useState>({ + raiseDispute: false, + cancelDispute: false, + resolveDispute: false, + }); + const [errors, setErrors] = useState>({ + raiseDispute: null, + cancelDispute: null, + resolveDispute: null, + }); + + /** + * Raises a dispute on a given ipId + * @param request - The request object containing necessary data to raise a dispute. + * @param request.targetIpId - The IP ID that is the target of the dispute. + * @param request.arbitrationPolicy - The address of the arbitration policy. + * @param request.linkToDisputeEvidence - The link to the dispute evidence. + * @param request.targetTag - The target tag of the dispute. + * @param request.calldata - Optional calldata to initialize the policy. + * @param request.txOptions - Optional transaction options. + * @returns A Promise that resolves to a RaiseDisputeResponse containing the transaction hash. + * @throws `NotRegisteredIpId` if targetIpId is not registered in the IPA Registry. + * @throws `NotWhitelistedDisputeTag` if targetTag is not whitelisted. + * @throws `ZeroLinkToDisputeEvidence` if linkToDisputeEvidence is empty + * @calls raiseDispute(address _targetIpId, string memory _linkToDisputeEvidence, bytes32 _targetTag, bytes calldata _data) external nonReentrant returns (uint256) { + * @emits DisputeRaised (disputeId_, targetIpId, msg.sender, arbitrationPolicy, linkToDisputeEvidence, targetTag, calldata); + */ + const raiseDispute = async ( + request: RaiseDisputeRequest + ): Promise => { + try { + setLoadings((prev) => ({ ...prev, raiseDispute: true })); + setErrors((prev) => ({ ...prev, raiseDispute: null })); + const response = await client.dispute.raiseDispute(request); + setLoadings((prev) => ({ ...prev, raiseDispute: false })); + return response; + } catch (e) { + if (e instanceof Error) { + setErrors((prev) => ({ ...prev, raiseDispute: e.message })); + setLoadings((prev) => ({ ...prev, raiseDispute: false })); + } + throw new Error(`unhandled error type`); + } + }; + + /** + * Cancels an ongoing dispute + * @param request - The request object containing details to cancel the dispute. + * @param request.disputeId The ID of the dispute to be cancelled. + * @param request.calldata Optional additional data used in the cancellation process. + * @returns A Promise that resolves to a CancelDisputeResponse containing the transaction hash. + * @throws NotInDisputeState, if the currentTag of the Dispute is not being disputed + * @throws NotDisputeInitiator, if the transaction executor is not the one that initiated the dispute + * @throws error if the Dispute's ArbitrationPolicy contract is not valid + * @calls cancelDispute(uint256 _disputeId, bytes calldata _data) external nonReentrant { + * @emits DisputeCancelled (_disputeId, _data); + */ + const cancelDispute = async ( + request: CancelDisputeRequest + ): Promise => { + try { + setLoadings((prev) => ({ ...prev, cancelDispute: true })); + setErrors((prev) => ({ ...prev, cancelDispute: null })); + const response = await client.dispute.cancelDispute(request); + setLoadings((prev) => ({ ...prev, cancelDispute: false })); + return response; + } catch (e) { + if (e instanceof Error) { + setErrors((prev) => ({ ...prev, cancelDispute: e.message })); + setLoadings((prev) => ({ ...prev, cancelDispute: false })); + } + throw new Error(`unhandled error type`); + } + }; + + /** + * Resolves a dispute after it has been judged + * @param request - The request object containing details to resolve the dispute. + * @param request.disputeId The ID of the dispute to be resolved. + * @param request.data The data to resolve the dispute. + * @returns A Promise that resolves to a ResolveDisputeResponse. + * @throws NotAbleToResolve, if currentTag is still in dispute (i.e still needs a judgement to be set) + * @throws NotDisputeInitiator, if the transaction executor is not the one that initiated the dispute + * @emits DisputeResolved (_disputeId) + */ + const resolveDispute = async ( + request: ResolveDisputeRequest + ): Promise => { + try { + setLoadings((prev) => ({ ...prev, resolveDispute: true })); + setErrors((prev) => ({ ...prev, resolveDispute: null })); + const response = await client.dispute.resolveDispute(request); + setLoadings((prev) => ({ ...prev, resolveDispute: false })); + return response; + } catch (e) { + if (e instanceof Error) { + setErrors((prev) => ({ ...prev, resolveDispute: e.message })); + setLoadings((prev) => ({ ...prev, resolveDispute: false })); + } + throw new Error(`unhandled error type`); + } + }; + + return { + loadings, + errors, + raiseDispute, + cancelDispute, + resolveDispute, + }; +}; +export default useDispute; diff --git a/packages/react-sdk/src/resources/useIpAccount.ts b/packages/react-sdk/src/resources/useIpAccount.ts new file mode 100644 index 00000000..9177757b --- /dev/null +++ b/packages/react-sdk/src/resources/useIpAccount.ts @@ -0,0 +1,111 @@ +import { + IPAccountExecuteRequest, + IPAccountExecuteResponse, + IPAccountExecuteWithSigRequest, + IPAccountExecuteWithSigResponse, + IpAccountImplStateResponse, +} from "@story-protocol/core-sdk"; +import { useState } from "react"; + +import { useStoryContext } from "../StoryProtocolContext"; + +const useIpAccount = () => { + const client = useStoryContext(); + const [loadings, setLoadings] = useState>({ + execute: false, + executeWithSig: false, + getIpAccountNonce: false, + }); + const [errors, setErrors] = useState>({ + execute: null, + executeWithSig: null, + getIpAccountNonce: null, + }); + + /** Executes a transaction from the IP Account. + * @param request - The request object containing necessary data to execute IP Account a transaction. + * @param request.ipId The Ip Id to get ip account. + * @param request.to The recipient of the transaction. + * @param request.value The amount of Ether to send. + * @param request.accountAddress The ipId to send. + * @param request.data The data to send along with the transaction. + * @returns Tx hash for the transaction. + */ + const execute = async ( + request: IPAccountExecuteRequest + ): Promise => { + try { + setLoadings((prev) => ({ ...prev, execute: true })); + setErrors((prev) => ({ ...prev, execute: null })); + const response = await client.ipAccount.execute(request); + setLoadings((prev) => ({ ...prev, execute: false })); + return response; + } catch (e) { + if (e instanceof Error) { + setErrors((prev) => ({ ...prev, execute: e.message })); + setLoadings((prev) => ({ ...prev, execute: false })); + } + throw new Error(`unhandled error type`); + } + }; + + /** Executes a transaction from the IP Account. + * @param request - The request object containing necessary data to execute IP Account a transaction. + * @param request.ipId The Ip Id to get ip account. + * @param request.to The recipient of the transaction. + * @param request.value The amount of Ether to send. + * @param request.data The data to send along with the transaction. + * @param request.signer The signer of the transaction. + * @param request.deadline The deadline of the transaction signature. + * @param request.signature The signature of the transaction, EIP-712 encoded. + * @returns Tx hash for the transaction. + */ + const executeWithSig = async ( + request: IPAccountExecuteWithSigRequest + ): Promise => { + try { + setLoadings((prev) => ({ ...prev, executeWithSig: true })); + setErrors((prev) => ({ ...prev, executeWithSig: null })); + const response = await client.ipAccount.executeWithSig(request); + setLoadings((prev) => ({ ...prev, executeWithSig: false })); + return response; + } catch (e) { + if (e instanceof Error) { + setErrors((prev) => ({ ...prev, executeWithSig: e.message })); + setLoadings((prev) => ({ ...prev, executeWithSig: false })); + } + throw new Error(`unhandled error type`); + } + }; + + /** Returns the IPAccount's internal nonce for transaction ordering. + * @param ipId The IP ID + * @returns The nonce for transaction ordering. + */ + const getIpAccountNonce = async ( + ipId: string + ): Promise => { + try { + setLoadings((prev) => ({ ...prev, getIpAccountNonce: true })); + setErrors((prev) => ({ ...prev, getIpAccountNonce: null })); + const response = await client.ipAccount.getIpAccountNonce(ipId); + setLoadings((prev) => ({ ...prev, getIpAccountNonce: false })); + return response; + } catch (e) { + if (e instanceof Error) { + setErrors((prev) => ({ ...prev, getIpAccountNonce: e.message })); + setLoadings((prev) => ({ ...prev, getIpAccountNonce: false })); + } + throw new Error(`unhandled error type`); + } + }; + + return { + loadings, + errors, + execute, + executeWithSig, + getIpAccountNonce, + }; +}; +export default useIpAccount; diff --git a/packages/react-sdk/src/resources/useIpAsset.ts b/packages/react-sdk/src/resources/useIpAsset.ts new file mode 100644 index 00000000..0a752bf0 --- /dev/null +++ b/packages/react-sdk/src/resources/useIpAsset.ts @@ -0,0 +1,291 @@ +import { + RegisterRequest, + RegisterIpResponse, + RegisterDerivativeRequest, + RegisterDerivativeResponse, + RegisterDerivativeWithLicenseTokensRequest, + RegisterDerivativeWithLicenseTokensResponse, + CreateIpAssetWithPilTermsRequest, + CreateIpAssetWithPilTermsResponse, + RegisterIpAndAttachPilTermsRequest, + RegisterIpAndAttachPilTermsResponse, + RegisterIpAndMakeDerivativeRequest, + RegisterIpAndMakeDerivativeResponse, +} from "@story-protocol/core-sdk"; +import { useState } from "react"; + +import { useStoryContext } from "../StoryProtocolContext"; + +const useIpAsset = () => { + const client = useStoryContext(); + const [loadings, setLoadings] = useState>({ + register: false, + registerDerivative: false, + registerDerivativeWithLicenseTokens: false, + mintAndRegisterIpAssetWithPilTerms: false, + registerIpAndAttachPilTerms: false, + registerDerivativeIp: false, + }); + const [errors, setErrors] = useState>({ + register: null, + registerDerivative: null, + registerDerivativeWithLicenseTokens: null, + mintAndRegisterIpAssetWithPilTerms: null, + registerIpAndAttachPilTerms: null, + registerDerivativeIp: null, + }); + + /** + * Registers an NFT as IP, creating a corresponding IP record. + * @param request - The request object that contains all data needed to register IP. + * @param request.nftContract The address of the NFT. + * @param request.tokenId The token identifier of the NFT. + * @param request.metadata - [Optional] The metadata for the IP. + * @param request.metadata.metadataURI [Optional] The URI of the metadata for the IP. + * @param request.metadata.metadataHash [Optional] The metadata for the IP. + * @param request.metadata.nftMetadataHash [Optional] The metadata for the IP NFT. + * @param request.deadline [Optional] The deadline for the signature in milliseconds, default is 1000ms. + * @param request.txOptions [Optional] The transaction options. + * @returns A Promise that resolves to an object containing the transaction hash and optional IP ID if waitForTxn is set to true. + * @emits IPRegistered (ipId, chainId, tokenContract, tokenId, resolverAddr, metadataProviderAddress, metadata) + */ + const register = async ( + request: RegisterRequest + ): Promise => { + try { + setLoadings((prev) => ({ ...prev, register: true })); + setErrors((prev) => ({ ...prev, register: null })); + const response = await client.ipAsset.register(request); + setLoadings((prev) => ({ ...prev, register: false })); + return response; + } catch (e) { + if (e instanceof Error) { + setErrors((prev) => ({ ...prev, register: e.message })); + setLoadings((prev) => ({ ...prev, register: false })); + } + throw new Error(`unhandled error type`); + } + }; + + /** + * Registers a derivative directly with parent IP's license terms, without needing license tokens, + * and attaches the license terms of the parent IPs to the derivative IP. + * The license terms must be attached to the parent IP before calling this function. + * All IPs attached default license terms by default. + * The derivative IP owner must be the caller or an authorized operator. + * @param request - The request object that contains all data needed to register derivative IP. + * @param request.childIpId The derivative IP ID. + * @param request.parentIpIds The parent IP IDs. + * @param request.licenseTermsIds The IDs of the license terms that the parent IP supports. + * @param request.txOptions [Optional] The transaction options. + * @returns A Promise that resolves to an object containing the transaction hash. + */ + const registerDerivative = async ( + request: RegisterDerivativeRequest + ): Promise => { + try { + setLoadings((prev) => ({ ...prev, registerDerivative: true })); + setErrors((prev) => ({ ...prev, registerDerivative: null })); + const response = await client.ipAsset.registerDerivative(request); + setLoadings((prev) => ({ ...prev, registerDerivative: false })); + return response; + } catch (e) { + if (e instanceof Error) { + setErrors((prev) => ({ ...prev, registerDerivative: e.message })); + setLoadings((prev) => ({ ...prev, registerDerivative: false })); + } + throw new Error(`unhandled error type`); + } + }; + + /** + * Registers a derivative with license tokens. + * the derivative IP is registered with license tokens minted from the parent IP's license terms. + * the license terms of the parent IPs issued with license tokens are attached to the derivative IP. + * the caller must be the derivative IP owner or an authorized operator. + * @param request - The request object that contains all data needed to register derivative license tokens. + * @param request.childIpId The derivative IP ID. + * @param request.licenseTokenIds The IDs of the license tokens. + * @param request.txOptions [Optional] The transaction options. + * @returns A Promise that resolves to an object containing the transaction hash. + */ + const registerDerivativeWithLicenseTokens = async ( + request: RegisterDerivativeWithLicenseTokensRequest + ): Promise => { + try { + setLoadings((prev) => ({ + ...prev, + registerDerivativeWithLicenseTokens: true, + })); + setErrors((prev) => ({ + ...prev, + registerDerivativeWithLicenseTokens: null, + })); + const response = await client.ipAsset.registerDerivativeWithLicenseTokens( + request + ); + setLoadings((prev) => ({ + ...prev, + registerDerivativeWithLicenseTokens: false, + })); + return response; + } catch (e) { + if (e instanceof Error) { + setErrors((prev) => ({ + ...prev, + registerDerivativeWithLicenseTokens: e.message, + })); + setLoadings((prev) => ({ + ...prev, + registerDerivativeWithLicenseTokens: false, + })); + } + throw new Error(`unhandled error type`); + } + }; + + /** + * Mint an NFT from a collection and register it as an IP. + * @param request - The request object that contains all data needed to mint and register ip. + * @param request.nftContract The address of the NFT collection. + * @param request.pilType The type of the PIL. + * @param request.metadata - [Optional] The metadata for the IP. + * @param request.metadata.metadataURI [Optional] The URI of the metadata for the IP. + * @param request.metadata.metadataHash [Optional] The metadata for the IP. + * @param request.metadata.nftMetadataHash [Optional] The metadata for the IP NFT. + * @param request.recipient [Optional] The address of the recipient of the minted NFT. + * @param request.mintingFee [Optional] The fee to be paid when minting a license. + * @param request.commercialRevShare [Optional] Percentage of revenue that must be shared with the licensor. + * @param request.currency [Optional] The ERC20 token to be used to pay the minting fee. the token must be registered in story protocol. + * @param request.txOptions [Optional] The transaction options. + * @returns A Promise that resolves to an object containing the transaction hash and optional IP ID, Token ID, License Terms Id if waitForTxn is set to true. + * @emits IPRegistered (ipId, chainId, tokenContract, tokenId, name, uri, registrationDate) + * @emits LicenseTermsAttached (caller, ipId, licenseTemplate, licenseTermsId) + */ + const mintAndRegisterIpAssetWithPilTerms = async ( + request: CreateIpAssetWithPilTermsRequest + ): Promise => { + try { + setLoadings((prev) => ({ + ...prev, + mintAndRegisterIpAssetWithPilTerms: true, + })); + setErrors((prev) => ({ + ...prev, + mintAndRegisterIpAssetWithPilTerms: null, + })); + const response = await client.ipAsset.mintAndRegisterIpAssetWithPilTerms( + request + ); + setLoadings((prev) => ({ + ...prev, + mintAndRegisterIpAssetWithPilTerms: false, + })); + return response; + } catch (e) { + if (e instanceof Error) { + setErrors((prev) => ({ + ...prev, + mintAndRegisterIpAssetWithPilTerms: e.message, + })); + setLoadings((prev) => ({ + ...prev, + mintAndRegisterIpAssetWithPilTerms: false, + })); + } + throw new Error(`unhandled error type`); + } + }; + + /** + * Register a given NFT as an IP and attach Programmable IP License Terms.R. + * @param request - The request object that contains all data needed to mint and register ip. + * @param request.nftContract The address of the NFT collection. + * @param request.tokenId The ID of the NFT. + * @param request.pilType The type of the PIL. + * @param request.metadata - [Optional] The desired metadata for the newly registered IP. + * @param request.metadata.metadataURI [Optional] The the metadata for the IP hash. + * @param request.metadata.metadataHash [Optional] The metadata for the IP. + * @param request.metadata.nftMetadataHash [Optional] The metadata for the IP NFT. + * @param request.deadline [Optional] The deadline for the signature in milliseconds, default is 1000ms. + * @param request.mintingFee [Optional] The fee to be paid when minting a license. + * @param request.commercialRevShare [Optional] Percentage of revenue that must be shared with the licensor. + * @param request.currency [Optional] The ERC20 token to be used to pay the minting fee. the token must be registered in story protocol. + * @param request.txOptions [Optional] The transaction options. + * @returns A Promise that resolves to an object containing the transaction hash and optional IP ID, License Terms Id if waitForTxn is set to true. + * @emits LicenseTermsAttached (caller, ipId, licenseTemplate, licenseTermsId) + */ + const registerIpAndAttachPilTerms = async ( + request: RegisterIpAndAttachPilTermsRequest + ): Promise => { + try { + setLoadings((prev) => ({ ...prev, registerIpAndAttachPilTerms: true })); + setErrors((prev) => ({ ...prev, registerIpAndAttachPilTerms: null })); + const response = await client.ipAsset.registerIpAndAttachPilTerms( + request + ); + setLoadings((prev) => ({ ...prev, registerIpAndAttachPilTerms: false })); + return response; + } catch (e) { + if (e instanceof Error) { + setErrors((prev) => ({ + ...prev, + registerIpAndAttachPilTerms: e.message, + })); + setLoadings((prev) => ({ + ...prev, + registerIpAndAttachPilTerms: false, + })); + } + throw new Error(`unhandled error type`); + } + }; + + /** + * Register the given NFT as a derivative IP with metadata without using license tokens. + * @param request - The request object that contains all data needed to register derivative IP. + * @param request.nftContract The address of the NFT collection. + * @param request.tokenId The ID of the NFT. + * @param request.derivData The derivative data to be used for registerDerivative. + * @param request.derivData.parentIpIds The IDs of the parent IPs to link the registered derivative IP. + * @param request.derivData.licenseTemplate [Optional] The address of the license template to be used for the linking. + * @param request.derivData.licenseTermsIds The IDs of the license terms to be used for the linking. + * @param request.metadata - [Optional] The desired metadata for the newly registered IP. + * @param request.metadata.metadataURI [Optional] The URI of the metadata for the IP. + * @param request.metadata.metadataHash [Optional] The metadata for the IP. + * @param request.metadata.nftMetadataHash [Optional] The the metadata for the IP NFT. + * @param request.deadline [Optional] The deadline for the signature in milliseconds,default is 1000ms. + * @param request.txOptions [Optional] The transaction options. + * @returns A Promise that resolves to an object containing the transaction hash and optional IP ID if waitForTxn is set to true. + * @emits IPRegistered (ipId, chainId, tokenContract, tokenId, name, uri, registrationDate) + */ + const registerDerivativeIp = async ( + request: RegisterIpAndMakeDerivativeRequest + ): Promise => { + try { + setLoadings((prev) => ({ ...prev, registerDerivativeIp: true })); + setErrors((prev) => ({ ...prev, registerDerivativeIp: null })); + const response = await client.ipAsset.registerDerivativeIp(request); + setLoadings((prev) => ({ ...prev, registerDerivativeIp: false })); + return response; + } catch (e) { + if (e instanceof Error) { + setErrors((prev) => ({ ...prev, registerDerivativeIp: e.message })); + setLoadings((prev) => ({ ...prev, registerDerivativeIp: false })); + } + throw new Error(`unhandled error type`); + } + }; + + return { + loadings, + errors, + register, + registerDerivative, + registerDerivativeWithLicenseTokens, + mintAndRegisterIpAssetWithPilTerms, + registerIpAndAttachPilTerms, + registerDerivativeIp, + }; +}; +export default useIpAsset; diff --git a/packages/react-sdk/src/resources/useLicense.ts b/packages/react-sdk/src/resources/useLicense.ts new file mode 100644 index 00000000..9397cd36 --- /dev/null +++ b/packages/react-sdk/src/resources/useLicense.ts @@ -0,0 +1,236 @@ +import { + RegisterNonComSocialRemixingPILRequest, + RegisterPILResponse, + RegisterCommercialUsePILRequest, + RegisterCommercialRemixPILRequest, + AttachLicenseTermsRequest, + AttachLicenseTermsResponse, + MintLicenseTokensRequest, + MintLicenseTokensResponse, + LicenseTermsId, + PiLicenseTemplateGetLicenseTermsResponse, +} from "@story-protocol/core-sdk"; +import { useState } from "react"; + +import { useStoryContext } from "../StoryProtocolContext"; + +const useLicense = () => { + const client = useStoryContext(); + const [loadings, setLoadings] = useState>({ + registerNonComSocialRemixingPIL: false, + registerCommercialUsePIL: false, + registerCommercialRemixPIL: false, + attachLicenseTerms: false, + mintLicenseTokens: false, + getLicenseTerms: false, + }); + const [errors, setErrors] = useState>({ + registerNonComSocialRemixingPIL: null, + registerCommercialUsePIL: null, + registerCommercialRemixPIL: null, + attachLicenseTerms: null, + mintLicenseTokens: null, + getLicenseTerms: null, + }); + + /** + * Convenient function to register a PIL non commercial social remix license to the registry + * @param request - [Optional] The request object that contains all data needed to register a PIL non commercial social remix license. + * @param request.txOptions [Optional] The transaction options. + * @returns A Promise that resolves to an object containing the optional transaction hash and optional license terms Id. + * @emits LicenseTermsRegistered (licenseTermsId, licenseTemplate, licenseTerms); + */ + const registerNonComSocialRemixingPIL = async ( + request: RegisterNonComSocialRemixingPILRequest + ): Promise => { + try { + setLoadings((prev) => ({ + ...prev, + registerNonComSocialRemixingPIL: true, + })); + setErrors((prev) => ({ ...prev, registerNonComSocialRemixingPIL: null })); + const response = await client.license.registerNonComSocialRemixingPIL( + request + ); + setLoadings((prev) => ({ + ...prev, + registerNonComSocialRemixingPIL: false, + })); + return response; + } catch (e) { + if (e instanceof Error) { + setErrors((prev) => ({ + ...prev, + registerNonComSocialRemixingPIL: e.message, + })); + setLoadings((prev) => ({ + ...prev, + registerNonComSocialRemixingPIL: false, + })); + } + throw new Error(`unhandled error type`); + } + }; + + /** + * Convenient function to register a PIL commercial use license to the registry. + * @param request - The request object that contains all data needed to register a PIL commercial use license. + * @param request.mintingFee The fee to be paid when minting a license. + * @param request.currency The ERC20 token to be used to pay the minting fee and the token must be registered in story protocol. + * @param request.txOptions [Optional] The transaction options. + * @returns A Promise that resolves to an object containing the optional transaction hash and optional license terms Id. + * @emits LicenseTermsRegistered (licenseTermsId, licenseTemplate, licenseTerms); + */ + const registerCommercialUsePIL = async ( + request: RegisterCommercialUsePILRequest + ): Promise => { + try { + setLoadings((prev) => ({ ...prev, registerCommercialUsePIL: true })); + setErrors((prev) => ({ ...prev, registerCommercialUsePIL: null })); + const response = await client.license.registerCommercialUsePIL(request); + setLoadings((prev) => ({ ...prev, registerCommercialUsePIL: false })); + return response; + } catch (e) { + if (e instanceof Error) { + setErrors((prev) => ({ ...prev, registerCommercialUsePIL: e.message })); + setLoadings((prev) => ({ ...prev, registerCommercialUsePIL: false })); + } + throw new Error(`unhandled error type`); + } + }; + + /** + * Convenient function to register a PIL commercial Remix license to the registry. + * @param request - The request object that contains all data needed to register license. + * @param request.mintingFee The fee to be paid when minting a license. + * @param request.commercialRevShare Percentage of revenue that must be shared with the licensor. + * @param request.currency The ERC20 token to be used to pay the minting fee. the token must be registered in story protocol. + * @param request.txOptions [Optional] The transaction options. + * @returns A Promise that resolves to an object containing the optional transaction hash and optional license terms Id. + * @emits LicenseTermsRegistered (licenseTermsId, licenseTemplate, licenseTerms); + */ + const registerCommercialRemixPIL = async ( + request: RegisterCommercialRemixPILRequest + ): Promise => { + try { + setLoadings((prev) => ({ ...prev, registerCommercialRemixPIL: true })); + setErrors((prev) => ({ ...prev, registerCommercialRemixPIL: null })); + const response = await client.license.registerCommercialRemixPIL(request); + setLoadings((prev) => ({ ...prev, registerCommercialRemixPIL: false })); + return response; + } catch (e) { + if (e instanceof Error) { + setErrors((prev) => ({ + ...prev, + registerCommercialRemixPIL: e.message, + })); + setLoadings((prev) => ({ ...prev, registerCommercialRemixPIL: false })); + } + throw new Error(`unhandled error type`); + } + }; + + /** + * Attaches license terms to an IP. + * @param request - The request object that contains all data needed to attach license terms. + * @param request.ipId The address of the IP to which the license terms are attached. + * @param request.licenseTemplate The address of the license template. + * @param request.licenseTermsId The ID of the license terms. + * @param request.txOptions [Optional] The transaction options. + * @returns A Promise that resolves to an object containing the transaction hash. + */ + const attachLicenseTerms = async ( + request: AttachLicenseTermsRequest + ): Promise => { + try { + setLoadings((prev) => ({ ...prev, attachLicenseTerms: true })); + setErrors((prev) => ({ ...prev, attachLicenseTerms: null })); + const response = await client.license.attachLicenseTerms(request); + setLoadings((prev) => ({ ...prev, attachLicenseTerms: false })); + return response; + } catch (e) { + if (e instanceof Error) { + setErrors((prev) => ({ ...prev, attachLicenseTerms: e.message })); + setLoadings((prev) => ({ ...prev, attachLicenseTerms: false })); + } + throw new Error(`unhandled error type`); + } + }; + + /** + * Mints license tokens for the license terms attached to an IP. + * The license tokens are minted to the receiver. + * The license terms must be attached to the IP before calling this function. + * But it can mint license token of default license terms without attaching the default license terms, + * since it is attached to all IPs by default. + * IP owners can mint license tokens for their IPs for arbitrary license terms + * without attaching the license terms to IP. + * It might require the caller pay the minting fee, depending on the license terms or configured by the iP owner. + * The minting fee is paid in the minting fee token specified in the license terms or configured by the IP owner. + * IP owners can configure the minting fee of their IPs or + * configure the minting fee module to determine the minting fee. + * @param request - The request object that contains all data needed to mint license tokens. + * @param request.licensorIpId The licensor IP ID. + * @param request.licenseTemplate The address of the license template. + * @param request.licenseTermsId The ID of the license terms within the license template. + * @param request.amount The amount of license tokens to mint. + * @param request.receiver The address of the receiver. + * @param request.txOptions [Optional] The transaction options. + * @returns A Promise that resolves to an object containing the transaction hash and optional license token IDs if waitForTxn is set to true. + * @emits LicenseTokensMinted (msg.sender, licensorIpId, licenseTemplate, licenseTermsId, amount, receiver, startLicenseTokenId); + */ + const mintLicenseTokens = async ( + request: MintLicenseTokensRequest + ): Promise => { + try { + setLoadings((prev) => ({ ...prev, mintLicenseTokens: true })); + setErrors((prev) => ({ ...prev, mintLicenseTokens: null })); + const response = await client.license.mintLicenseTokens(request); + setLoadings((prev) => ({ ...prev, mintLicenseTokens: false })); + return response; + } catch (e) { + if (e instanceof Error) { + setErrors((prev) => ({ ...prev, mintLicenseTokens: e.message })); + setLoadings((prev) => ({ ...prev, mintLicenseTokens: false })); + } + throw new Error(`unhandled error type`); + } + }; + + /** + * Gets license terms of the given ID. + * @param selectedLicenseTermsId The ID of the license terms. + * @returns A Promise that resolves to an object containing the PILTerms associate with the given ID. + */ + const getLicenseTerms = async ( + selectedLicenseTermsId: LicenseTermsId + ): Promise => { + try { + setLoadings((prev) => ({ ...prev, getLicenseTerms: true })); + setErrors((prev) => ({ ...prev, getLicenseTerms: null })); + const response = await client.license.getLicenseTerms( + selectedLicenseTermsId + ); + setLoadings((prev) => ({ ...prev, getLicenseTerms: false })); + return response; + } catch (e) { + if (e instanceof Error) { + setErrors((prev) => ({ ...prev, getLicenseTerms: e.message })); + setLoadings((prev) => ({ ...prev, getLicenseTerms: false })); + } + throw new Error(`unhandled error type`); + } + }; + + return { + loadings, + errors, + registerNonComSocialRemixingPIL, + registerCommercialUsePIL, + registerCommercialRemixPIL, + attachLicenseTerms, + mintLicenseTokens, + getLicenseTerms, + }; +}; +export default useLicense; diff --git a/packages/react-sdk/src/resources/useNftClient.ts b/packages/react-sdk/src/resources/useNftClient.ts new file mode 100644 index 00000000..9a9fb082 --- /dev/null +++ b/packages/react-sdk/src/resources/useNftClient.ts @@ -0,0 +1,55 @@ +import { + CreateNFTCollectionRequest, + CreateNFTCollectionResponse, +} from "@story-protocol/core-sdk"; +import { useState } from "react"; + +import { useStoryContext } from "../StoryProtocolContext"; + +const useNftClient = () => { + const client = useStoryContext(); + const [loadings, setLoadings] = useState>({ + createNFTCollection: false, + }); + const [errors, setErrors] = useState>({ + createNFTCollection: null, + }); + + /** + * Creates a new SPG NFT Collection. + * @param request - The request object containing necessary data to create a SPG NFT Collection. + * @param request.name - The name of the collection. + * @param request.symbol - The symbol of the collection. + * @param request.maxSupply - The maximum supply of the collection. + * @param request.mintFee - The cost to mint a token. + * @param request.mintFeeToken - The token to mint. + * @param request.owner - The owner of the collection. + * @param request.txOptions - Optional transaction options. + * @returns A Promise that resolves to a CreateNFTCollectionResponse containing the transaction hash and collection address. + * @emits CollectionCreated (nftContract); + */ + const createNFTCollection = async ( + request: CreateNFTCollectionRequest + ): Promise => { + try { + setLoadings((prev) => ({ ...prev, createNFTCollection: true })); + setErrors((prev) => ({ ...prev, createNFTCollection: null })); + const response = await client.nftClient.createNFTCollection(request); + setLoadings((prev) => ({ ...prev, createNFTCollection: false })); + return response; + } catch (e) { + if (e instanceof Error) { + setErrors((prev) => ({ ...prev, createNFTCollection: e.message })); + setLoadings((prev) => ({ ...prev, createNFTCollection: false })); + } + throw new Error(`unhandled error type`); + } + }; + + return { + loadings, + errors, + createNFTCollection, + }; +}; +export default useNftClient; diff --git a/packages/react-sdk/src/resources/usePermission.ts b/packages/react-sdk/src/resources/usePermission.ts new file mode 100644 index 00000000..31b122a1 --- /dev/null +++ b/packages/react-sdk/src/resources/usePermission.ts @@ -0,0 +1,223 @@ +import { + SetPermissionsRequest, + SetPermissionsResponse, + CreateSetPermissionSignatureRequest, + SetAllPermissionsRequest, + SetBatchPermissionsRequest, + CreateBatchPermissionSignatureRequest, +} from "@story-protocol/core-sdk"; +import { useState } from "react"; + +import { useStoryContext } from "../StoryProtocolContext"; + +const usePermission = () => { + const client = useStoryContext(); + const [loadings, setLoadings] = useState>({ + setPermission: false, + createSetPermissionSignature: false, + setAllPermissions: false, + setBatchPermissions: false, + createBatchPermissionSignature: false, + }); + const [errors, setErrors] = useState>({ + setPermission: null, + createSetPermissionSignature: null, + setAllPermissions: null, + setBatchPermissions: null, + createBatchPermissionSignature: null, + }); + + /** + * Sets the permission for a specific function call + * Each policy is represented as a mapping from an IP account address to a signer address to a recipient + * address to a function selector to a permission level. The permission level can be 0 (ABSTAIN), 1 (ALLOW), or + * 2 (DENY). + * By default, all policies are set to 0 (ABSTAIN), which means that the permission is not set. + * The owner of ipAccount by default has all permission. + * address(0) => wildcard + * bytes4(0) => wildcard + * Specific permission overrides wildcard permission. + * @param request - The request object containing necessary data to set `permission`. + * @param request.ipId The IP ID that grants the permission for `signer`. + * @param request.signer The address that can call `to` on behalf of the `ipAccount`. + * @param request.to The address that can be called by the `signer` (currently only modules can be `to`). + * @param request.permission The new permission level. + * @param request.func [Optional] The function selector string of `to` that can be called by the `signer` on behalf of the `ipAccount`. Be default, it allows all functions. + * @param request.txOptions [Optional] The transaction options. + * @returns A Promise that resolves to an object containing the transaction hash. + * @emits PermissionSet (ipAccountOwner, ipAccount, signer, to, func, permission) + */ + const setPermission = async ( + request: SetPermissionsRequest + ): Promise => { + try { + setLoadings((prev) => ({ ...prev, setPermission: true })); + setErrors((prev) => ({ ...prev, setPermission: null })); + const response = await client.permission.setPermission(request); + setLoadings((prev) => ({ ...prev, setPermission: false })); + return response; + } catch (e) { + if (e instanceof Error) { + setErrors((prev) => ({ ...prev, setPermission: e.message })); + setLoadings((prev) => ({ ...prev, setPermission: false })); + } + throw new Error(`unhandled error type`); + } + }; + + /** + * Specific permission overrides wildcard permission with signature. + * @param request - The request object containing necessary data to set permissions. + * @param request.ipId The IP ID that grants the permission for `signer` + * @param request.signer The address that can call `to` on behalf of the `ipAccount` + * @param request.to The address that can be called by the `signer` (currently only modules can be `to`) + * @param request.permission The new permission level. + * @param request.func [Optional] The function selector string of `to` that can be called by the `signer` on behalf of the `ipAccount`. Be default, it allows all functions. + * @param request.deadline [Optional] The deadline for the signature in milliseconds, default is 1000ms. + * @param request.txOptions [Optional] The transaction options. + * @returns A Promise that resolves to an object containing the transaction hash. + * @emits PermissionSet (ipAccountOwner, ipAccount, signer, to, func, permission) + */ + const createSetPermissionSignature = async ( + request: CreateSetPermissionSignatureRequest + ): Promise => { + try { + setLoadings((prev) => ({ ...prev, createSetPermissionSignature: true })); + setErrors((prev) => ({ ...prev, createSetPermissionSignature: null })); + const response = await client.permission.createSetPermissionSignature( + request + ); + setLoadings((prev) => ({ ...prev, createSetPermissionSignature: false })); + return response; + } catch (e) { + if (e instanceof Error) { + setErrors((prev) => ({ + ...prev, + createSetPermissionSignature: e.message, + })); + setLoadings((prev) => ({ + ...prev, + createSetPermissionSignature: false, + })); + } + throw new Error(`unhandled error type`); + } + }; + + /** + * Sets permission to a signer for all functions across all modules. + * @param request - The request object containing necessary data to set all permissions. + * @param request.ipId The IP ID that grants the permission for `signer` + * @param request.signer The address of the signer receiving the permissions. + * @param request.permission The new permission. + * @param request.txOptions [Optional] The transaction options. + * @returns A Promise that resolves to an object containing the transaction hash + * @emits PermissionSet (ipAccountOwner, ipAccount, signer, to, func, permission) + */ + const setAllPermissions = async ( + request: SetAllPermissionsRequest + ): Promise => { + try { + setLoadings((prev) => ({ ...prev, setAllPermissions: true })); + setErrors((prev) => ({ ...prev, setAllPermissions: null })); + const response = await client.permission.setAllPermissions(request); + setLoadings((prev) => ({ ...prev, setAllPermissions: false })); + return response; + } catch (e) { + if (e instanceof Error) { + setErrors((prev) => ({ ...prev, setAllPermissions: e.message })); + setLoadings((prev) => ({ ...prev, setAllPermissions: false })); + } + throw new Error(`unhandled error type`); + } + }; + + /** + * Sets a batch of permissions in a single transaction. + * @param request - The request object containing necessary data to set all permissions. + * @param {Array} request.permissions - An array of `Permission` structure, each representing the permission to be set. + * @param request.permissions[].ipId The IP ID that grants the permission for `signer`. + * @param request.permissions[].signer The address that can call `to` on behalf of the `ipAccount`. + * @param request.permissions[].to The address that can be called by the `signer` (currently only modules can be `to`). + * @param request.permissions[].permission The new permission level. + * @param request.permissions[].func [Optional] The function selector string of `to` that can be called by the `signer` on behalf of the `ipAccount`. Be default, it allows all functions. + * @param request.deadline [Optional] The deadline for the signature in milliseconds, default is 1000ms. + * @param request.txOptions [Optional] The transaction options. + * @returns A Promise that resolves to an object containing the transaction hash + * @emits PermissionSet (ipAccountOwner, ipAccount, signer, to, func, permission) + */ + const setBatchPermissions = async ( + request: SetBatchPermissionsRequest + ): Promise => { + try { + setLoadings((prev) => ({ ...prev, setBatchPermissions: true })); + setErrors((prev) => ({ ...prev, setBatchPermissions: null })); + const response = await client.permission.setBatchPermissions(request); + setLoadings((prev) => ({ ...prev, setBatchPermissions: false })); + return response; + } catch (e) { + if (e instanceof Error) { + setErrors((prev) => ({ ...prev, setBatchPermissions: e.message })); + setLoadings((prev) => ({ ...prev, setBatchPermissions: false })); + } + throw new Error(`unhandled error type`); + } + }; + + /** + * Sets a batch of permissions in a single transaction with signature. + * @param request - The request object containing necessary data to set permissions. + * @param request.ipId The IP ID that grants the permission for `signer` + * @param {Array} request.permissions - An array of `Permission` structure, each representing the permission to be set. + * @param request.permissions[].ipId The IP ID that grants the permission for `signer`. + * @param request.permissions[].signer The address that can call `to` on behalf of the `ipAccount`. + * @param request.permissions[].to The address that can be called by the `signer` (currently only modules can be `to`). + * @param request.permissions[].permission The new permission level. + * @param request.permissions[].func [Optional] The function selector string of `to` that can be called by the `signer` on behalf of the `ipAccount`. Be default, it allows all functions. + * @param request.txOptions [Optional] The transaction options. + * @returns A Promise that resolves to an object containing the transaction hash. + * @emits PermissionSet (ipAccountOwner, ipAccount, signer, to, func, permission) + */ + const createBatchPermissionSignature = async ( + request: CreateBatchPermissionSignatureRequest + ): Promise => { + try { + setLoadings((prev) => ({ + ...prev, + createBatchPermissionSignature: true, + })); + setErrors((prev) => ({ ...prev, createBatchPermissionSignature: null })); + const response = await client.permission.createBatchPermissionSignature( + request + ); + setLoadings((prev) => ({ + ...prev, + createBatchPermissionSignature: false, + })); + return response; + } catch (e) { + if (e instanceof Error) { + setErrors((prev) => ({ + ...prev, + createBatchPermissionSignature: e.message, + })); + setLoadings((prev) => ({ + ...prev, + createBatchPermissionSignature: false, + })); + } + throw new Error(`unhandled error type`); + } + }; + + return { + loadings, + errors, + setPermission, + createSetPermissionSignature, + setAllPermissions, + setBatchPermissions, + createBatchPermissionSignature, + }; +}; +export default usePermission; diff --git a/packages/react-sdk/src/resources/useRoyalty.ts b/packages/react-sdk/src/resources/useRoyalty.ts new file mode 100644 index 00000000..4a7945e6 --- /dev/null +++ b/packages/react-sdk/src/resources/useRoyalty.ts @@ -0,0 +1,211 @@ +import { + CollectRoyaltyTokensRequest, + CollectRoyaltyTokensResponse, + PayRoyaltyOnBehalfRequest, + PayRoyaltyOnBehalfResponse, + ClaimableRevenueRequest, + ClaimableRevenueResponse, + ClaimRevenueRequest, + ClaimRevenueResponse, + SnapshotRequest, + SnapshotResponse, +} from "@story-protocol/core-sdk"; +import { Hex, Address } from "viem"; +import { useState } from "react"; + +import { useStoryContext } from "../StoryProtocolContext"; + +const useRoyalty = () => { + const client = useStoryContext(); + const [loadings, setLoadings] = useState>({ + collectRoyaltyTokens: false, + payRoyaltyOnBehalf: false, + claimableRevenue: false, + claimRevenue: false, + snapshot: false, + getRoyaltyVaultAddress: false, + }); + const [errors, setErrors] = useState>({ + collectRoyaltyTokens: null, + payRoyaltyOnBehalf: null, + claimableRevenue: null, + claimRevenue: null, + snapshot: null, + getRoyaltyVaultAddress: null, + }); + + /** + * Allows ancestors to claim the royalty tokens and any accrued revenue tokens + * @param request - The request object that contains all data needed to collect royalty tokens. + * @param request.parentIpId The ip id of the ancestor to whom the royalty tokens belong to. + * @param request.royaltyVaultIpId The id of the royalty vault. + * @param request.txOptions [Optional] The transaction options. + * @returns A Promise that resolves to an object containing the transaction hash and optional the amount of royalty tokens collected if waitForTxn is set to true. + * @emits RoyaltyTokensCollected (ancestorIpId, royaltyTokensCollected) + */ + const collectRoyaltyTokens = async ( + request: CollectRoyaltyTokensRequest + ): Promise => { + try { + setLoadings((prev) => ({ ...prev, collectRoyaltyTokens: true })); + setErrors((prev) => ({ ...prev, collectRoyaltyTokens: null })); + const response = await client.royalty.collectRoyaltyTokens(request); + setLoadings((prev) => ({ ...prev, collectRoyaltyTokens: false })); + return response; + } catch (e) { + if (e instanceof Error) { + setErrors((prev) => ({ ...prev, collectRoyaltyTokens: e.message })); + setLoadings((prev) => ({ ...prev, collectRoyaltyTokens: false })); + } + throw new Error(`unhandled error type`); + } + }; + + /** + * Allows the function caller to pay royalties to the receiver IP asset on behalf of the payer IP asset. + * @param request - The request object that contains all data needed to pay royalty on behalf. + * @param request.receiverIpId The ipId that receives the royalties. + * @param request.payerIpId The ID of the IP asset that pays the royalties. + * @param request.token The token to use to pay the royalties. + * @param request.amount The amount to pay. + * @param request.txOptions [Optional] The transaction options. + * @returns A Promise that resolves to an object containing the transaction hash. + */ + const payRoyaltyOnBehalf = async ( + request: PayRoyaltyOnBehalfRequest + ): Promise => { + try { + setLoadings((prev) => ({ ...prev, payRoyaltyOnBehalf: true })); + setErrors((prev) => ({ ...prev, payRoyaltyOnBehalf: null })); + const response = await client.royalty.payRoyaltyOnBehalf(request); + setLoadings((prev) => ({ ...prev, payRoyaltyOnBehalf: false })); + return response; + } catch (e) { + if (e instanceof Error) { + setErrors((prev) => ({ ...prev, payRoyaltyOnBehalf: e.message })); + setLoadings((prev) => ({ ...prev, payRoyaltyOnBehalf: false })); + } + throw new Error(`unhandled error type`); + } + }; + + /** + * Calculates the amount of revenue token claimable by a token holder at certain snapshot. + * @param request - The request object that contains all data needed to claim Revenue. + * @param request.royaltyVaultIpId The id of the royalty vault. + * @param request.account The address of the token holder. + * @param request.snapshotId The snapshot id. + * @param request.token The revenue token to claim. + * @param request.txOptions [Optional] The transaction options. + * @returns A Promise that contains the amount of revenue token claimable + */ + const claimableRevenue = async ( + request: ClaimableRevenueRequest + ): Promise => { + try { + setLoadings((prev) => ({ ...prev, claimableRevenue: true })); + setErrors((prev) => ({ ...prev, claimableRevenue: null })); + const response = await client.royalty.claimableRevenue(request); + setLoadings((prev) => ({ ...prev, claimableRevenue: false })); + return response; + } catch (e) { + if (e instanceof Error) { + setErrors((prev) => ({ ...prev, claimableRevenue: e.message })); + setLoadings((prev) => ({ ...prev, claimableRevenue: false })); + } + throw new Error(`unhandled error type`); + } + }; + + /** + * Allows token holders to claim by a list of snapshot ids based on the token balance at certain snapshot + * @param request - The request object that contains all data needed to claim revenue. + * @param request.snapshotIds The list of snapshot ids. + * @param request.royaltyVaultIpId The id of the royalty vault. + * @param request.token The revenue token to claim. + * @param request.account [Optional] The ipId to send. + * @param request.txOptions [Optional] The transaction options. + * @returns A Promise that resolves to an object containing the transaction hash and optional claimableToken if waitForTxn is set to true. + * @emits RevenueTokenClaimed (claimer, token, amount). + */ + const claimRevenue = async ( + request: ClaimRevenueRequest + ): Promise => { + try { + setLoadings((prev) => ({ ...prev, claimRevenue: true })); + setErrors((prev) => ({ ...prev, claimRevenue: null })); + const response = await client.royalty.claimRevenue(request); + setLoadings((prev) => ({ ...prev, claimRevenue: false })); + return response; + } catch (e) { + if (e instanceof Error) { + setErrors((prev) => ({ ...prev, claimRevenue: e.message })); + setLoadings((prev) => ({ ...prev, claimRevenue: false })); + } + throw new Error(`unhandled error type`); + } + }; + + /** + * Snapshots the claimable revenue and royalty token amounts. + * @param request - The request object that contains all data needed to snapshot. + * @param request.royaltyVaultIpId The id of the royalty vault. + * @param request.txOptions [Optional] The transaction options. + * @returns A Promise that resolves to an object containing the transaction hash and optional snapshotId if waitForTxn is set to true. + * @emits SnapshotCompleted (snapshotId, snapshotTimestamp, unclaimedTokens). + */ + const snapshot = async ( + request: SnapshotRequest + ): Promise => { + try { + setLoadings((prev) => ({ ...prev, snapshot: true })); + setErrors((prev) => ({ ...prev, snapshot: null })); + const response = await client.royalty.snapshot(request); + setLoadings((prev) => ({ ...prev, snapshot: false })); + return response; + } catch (e) { + if (e instanceof Error) { + setErrors((prev) => ({ ...prev, snapshot: e.message })); + setLoadings((prev) => ({ ...prev, snapshot: false })); + } + throw new Error(`unhandled error type`); + } + }; + + /** + * Get the royalty vault proxy address of given royaltyVaultIpId. + * @param royaltyVaultIpId the id of the royalty vault. + * @returns A Promise that resolves to an object containing the royalty vault address. + */ + const getRoyaltyVaultAddress = async ( + royaltyVaultIpId: Hex + ): Promise
=> { + try { + setLoadings((prev) => ({ ...prev, getRoyaltyVaultAddress: true })); + setErrors((prev) => ({ ...prev, getRoyaltyVaultAddress: null })); + const response = await client.royalty.getRoyaltyVaultAddress( + royaltyVaultIpId + ); + setLoadings((prev) => ({ ...prev, getRoyaltyVaultAddress: false })); + return response; + } catch (e) { + if (e instanceof Error) { + setErrors((prev) => ({ ...prev, getRoyaltyVaultAddress: e.message })); + setLoadings((prev) => ({ ...prev, getRoyaltyVaultAddress: false })); + } + throw new Error(`unhandled error type`); + } + }; + + return { + loadings, + errors, + collectRoyaltyTokens, + payRoyaltyOnBehalf, + claimableRevenue, + claimRevenue, + snapshot, + getRoyaltyVaultAddress, + }; +}; +export default useRoyalty; diff --git a/packages/react-sdk/src/storyProtocolContext.tsx b/packages/react-sdk/src/storyProtocolContext.tsx new file mode 100644 index 00000000..56d0b62f --- /dev/null +++ b/packages/react-sdk/src/storyProtocolContext.tsx @@ -0,0 +1,20 @@ +import { createContext, useContext, ReactNode } from "react"; +import { StoryClient, StoryConfig } from "@story-protocol/core-sdk"; + +type Props = { + config: StoryConfig; + children: ReactNode; +}; + +const StoryContext = createContext({} as StoryClient); + +const StoryProvider = ({ config, children }: Props) => { + const client = StoryClient.newClient(config); + return ( + {children} + ); +}; +const useStoryContext = (): StoryClient => { + return useContext(StoryContext); +}; +export { useStoryContext, StoryProvider }; diff --git a/packages/react-sdk/tsconfig.json b/packages/react-sdk/tsconfig.json new file mode 100644 index 00000000..e2c07b36 --- /dev/null +++ b/packages/react-sdk/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "@story-protocol/tsconfig/base.json", + "compilerOptions": { + "resolveJsonModule": true, + "module": "ESNext", + "lib": ["dom", "es2015"], + "jsx": "react-jsx" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 87e4a676..9b907b73 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -137,6 +137,52 @@ importers: specifier: ^3.0.0 version: 3.2.5 + packages/react-sdk: + dependencies: + '@story-protocol/core-sdk': + specifier: 1.0.0-rc.14 + version: 1.0.0-rc.14(typescript@5.4.5) + ejs: + specifier: ^3.1.10 + version: 3.1.10 + react: + specifier: ^18.3.1 + version: 18.3.1 + viem: + specifier: ^2.8.12 + version: 2.9.16(typescript@5.4.5)(zod@3.22.4) + devDependencies: + '@babel/preset-env': + specifier: ^7.22.20 + version: 7.24.4(@babel/core@7.24.4) + '@babel/preset-react': + specifier: ^7.24.7 + version: 7.24.7(@babel/core@7.24.4) + '@babel/preset-typescript': + specifier: ^7.23.0 + version: 7.24.1(@babel/core@7.24.4) + '@preconstruct/cli': + specifier: ^2.8.1 + version: 2.8.3 + '@story-protocol/eslint-config': + specifier: workspace:* + version: link:../eslint-config-story + '@story-protocol/prettier-config': + specifier: workspace:* + version: link:../prettier-config + '@story-protocol/tsconfig': + specifier: workspace:* + version: link:../tsconfig + '@types/react': + specifier: ^18.3.3 + version: 18.3.3 + ts-node: + specifier: ^10.9.1 + version: 10.9.2(@types/node@20.12.7)(typescript@5.4.5) + typescript: + specifier: ^5.4.5 + version: 5.4.5 + packages/tsconfig: {} packages/wagmi-generator: @@ -150,10 +196,10 @@ importers: version: 0.0.0-canary-20240313013119(typescript@5.4.5) '@wagmi/connectors': specifier: ^4.1.14 - version: 4.1.25(@wagmi/core@2.6.16)(react-native@0.73.6)(react@18.2.0)(typescript@5.4.5)(viem@2.9.16) + version: 4.1.25(@wagmi/core@2.6.16)(react-native@0.73.6)(react@18.3.1)(typescript@5.4.5)(viem@2.9.16) '@wagmi/core': specifier: ^2.6.5 - version: 2.6.16(react@18.2.0)(typescript@5.4.5)(viem@2.9.16) + version: 2.6.16(react@18.3.1)(typescript@5.4.5)(viem@2.9.16) abitype: specifier: ^1.0.2 version: 1.0.2(typescript@5.4.5) @@ -168,7 +214,7 @@ importers: version: 2.9.16(typescript@5.4.5)(zod@3.22.4) wagmi: specifier: ^2.5.7 - version: 2.5.19(@tanstack/react-query@5.29.2)(react-native@0.73.6)(react@18.2.0)(typescript@5.4.5)(viem@2.9.16) + version: 2.5.19(@tanstack/react-query@5.29.2)(react-native@0.73.6)(react@18.3.1)(typescript@5.4.5)(viem@2.9.16) packages: @@ -195,6 +241,14 @@ packages: picocolors: 1.0.0 dev: true + /@babel/code-frame@7.24.7: + resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/highlight': 7.24.7 + picocolors: 1.0.0 + dev: true + /@babel/compat-data@7.24.4: resolution: {integrity: sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ==} engines: {node: '>=6.9.0'} @@ -233,6 +287,16 @@ packages: jsesc: 2.5.2 dev: true + /@babel/generator@7.24.7: + resolution: {integrity: sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.7 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 2.5.2 + dev: true + /@babel/helper-annotate-as-pure@7.22.5: resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==} engines: {node: '>=6.9.0'} @@ -240,6 +304,13 @@ packages: '@babel/types': 7.24.0 dev: true + /@babel/helper-annotate-as-pure@7.24.7: + resolution: {integrity: sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.7 + dev: true + /@babel/helper-builder-binary-assignment-operator-visitor@7.22.15: resolution: {integrity: sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==} engines: {node: '>=6.9.0'} @@ -308,6 +379,13 @@ packages: engines: {node: '>=6.9.0'} dev: true + /@babel/helper-environment-visitor@7.24.7: + resolution: {integrity: sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.7 + dev: true + /@babel/helper-function-name@7.23.0: resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} engines: {node: '>=6.9.0'} @@ -316,6 +394,14 @@ packages: '@babel/types': 7.24.0 dev: true + /@babel/helper-function-name@7.24.7: + resolution: {integrity: sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.24.7 + '@babel/types': 7.24.7 + dev: true + /@babel/helper-hoist-variables@7.22.5: resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} engines: {node: '>=6.9.0'} @@ -323,6 +409,13 @@ packages: '@babel/types': 7.24.0 dev: true + /@babel/helper-hoist-variables@7.24.7: + resolution: {integrity: sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.7 + dev: true + /@babel/helper-member-expression-to-functions@7.23.0: resolution: {integrity: sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==} engines: {node: '>=6.9.0'} @@ -337,6 +430,16 @@ packages: '@babel/types': 7.24.0 dev: true + /@babel/helper-module-imports@7.24.7: + resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/traverse': 7.24.7 + '@babel/types': 7.24.7 + transitivePeerDependencies: + - supports-color + dev: true + /@babel/helper-module-transforms@7.23.3(@babel/core@7.24.4): resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} engines: {node: '>=6.9.0'} @@ -363,6 +466,11 @@ packages: engines: {node: '>=6.9.0'} dev: true + /@babel/helper-plugin-utils@7.24.7: + resolution: {integrity: sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==} + engines: {node: '>=6.9.0'} + dev: true + /@babel/helper-remap-async-to-generator@7.22.20(@babel/core@7.24.4): resolution: {integrity: sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==} engines: {node: '>=6.9.0'} @@ -408,21 +516,43 @@ packages: '@babel/types': 7.24.0 dev: true + /@babel/helper-split-export-declaration@7.24.7: + resolution: {integrity: sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.7 + dev: true + /@babel/helper-string-parser@7.24.1: resolution: {integrity: sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==} engines: {node: '>=6.9.0'} dev: true + /@babel/helper-string-parser@7.24.7: + resolution: {integrity: sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==} + engines: {node: '>=6.9.0'} + dev: true + /@babel/helper-validator-identifier@7.22.20: resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} engines: {node: '>=6.9.0'} dev: true + /@babel/helper-validator-identifier@7.24.7: + resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} + engines: {node: '>=6.9.0'} + dev: true + /@babel/helper-validator-option@7.23.5: resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} engines: {node: '>=6.9.0'} dev: true + /@babel/helper-validator-option@7.24.7: + resolution: {integrity: sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==} + engines: {node: '>=6.9.0'} + dev: true + /@babel/helper-wrap-function@7.22.20: resolution: {integrity: sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==} engines: {node: '>=6.9.0'} @@ -453,6 +583,16 @@ packages: picocolors: 1.0.0 dev: true + /@babel/highlight@7.24.7: + resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.24.7 + chalk: 2.4.2 + js-tokens: 4.0.0 + picocolors: 1.0.0 + dev: true + /@babel/parser@7.24.4: resolution: {integrity: sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==} engines: {node: '>=6.0.0'} @@ -461,6 +601,14 @@ packages: '@babel/types': 7.24.0 dev: true + /@babel/parser@7.24.7: + resolution: {integrity: sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.24.7 + dev: true + /@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.24.4(@babel/core@7.24.4): resolution: {integrity: sha512-qpl6vOOEEzTLLcsuqYYo8yDtrTocmu2xkGvgNebvPjT9DTtfFYGmgDqY+rBYXNlqL4s9qLDn6xkrJv4RxAPiTA==} engines: {node: '>=6.9.0'} @@ -513,8 +661,8 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.24.4 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-plugin-utils': 7.24.0 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.24.4) '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.4) dev: true @@ -528,7 +676,7 @@ packages: dependencies: '@babel/core': 7.24.4 '@babel/helper-create-class-features-plugin': 7.24.4(@babel/core@7.24.4) - '@babel/helper-plugin-utils': 7.24.0 + '@babel/helper-plugin-utils': 7.24.7 dev: true /@babel/plugin-proposal-export-default-from@7.24.1(@babel/core@7.24.4): @@ -538,7 +686,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.24.4 - '@babel/helper-plugin-utils': 7.24.0 + '@babel/helper-plugin-utils': 7.24.7 '@babel/plugin-syntax-export-default-from': 7.24.1(@babel/core@7.24.4) dev: true @@ -550,7 +698,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.24.4 - '@babel/helper-plugin-utils': 7.24.0 + '@babel/helper-plugin-utils': 7.24.7 '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.4) dev: true @@ -562,7 +710,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.24.4 - '@babel/helper-plugin-utils': 7.24.0 + '@babel/helper-plugin-utils': 7.24.7 '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.4) dev: true @@ -576,7 +724,7 @@ packages: '@babel/compat-data': 7.24.4 '@babel/core': 7.24.4 '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-plugin-utils': 7.24.0 + '@babel/helper-plugin-utils': 7.24.7 '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.4) '@babel/plugin-transform-parameters': 7.24.1(@babel/core@7.24.4) dev: true @@ -589,7 +737,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.24.4 - '@babel/helper-plugin-utils': 7.24.0 + '@babel/helper-plugin-utils': 7.24.7 '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.4) dev: true @@ -601,7 +749,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.24.4 - '@babel/helper-plugin-utils': 7.24.0 + '@babel/helper-plugin-utils': 7.24.7 '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.4) dev: true @@ -659,7 +807,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.24.4 - '@babel/helper-plugin-utils': 7.24.0 + '@babel/helper-plugin-utils': 7.24.7 dev: true /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.24.4): @@ -678,7 +826,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.24.4 - '@babel/helper-plugin-utils': 7.24.0 + '@babel/helper-plugin-utils': 7.24.7 dev: true /@babel/plugin-syntax-import-assertions@7.24.1(@babel/core@7.24.4): @@ -729,6 +877,16 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true + /@babel/plugin-syntax-jsx@7.24.7(@babel/core@7.24.4): + resolution: {integrity: sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.4 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.24.4): resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} peerDependencies: @@ -1001,7 +1159,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.24.4 - '@babel/helper-plugin-utils': 7.24.0 + '@babel/helper-plugin-utils': 7.24.7 '@babel/plugin-syntax-flow': 7.24.1(@babel/core@7.24.4) dev: true @@ -1251,14 +1409,26 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-react-display-name@7.24.1(@babel/core@7.24.4): - resolution: {integrity: sha512-mvoQg2f9p2qlpDQRBC7M3c3XTr0k7cp/0+kFKKO/7Gtu0LSw16eKB+Fabe2bDT/UpsyasTBBkAnbdsLrkD5XMw==} + /@babel/plugin-transform-react-display-name@7.24.7(@babel/core@7.24.4): + resolution: {integrity: sha512-H/Snz9PFxKsS1JLI4dJLtnJgCJRoo0AUm3chP6NYr+9En1JMKloheEiLIhlp5MDVznWo+H3AAC1Mc8lmUEpsgg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.24.4 - '@babel/helper-plugin-utils': 7.24.0 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-transform-react-jsx-development@7.24.7(@babel/core@7.24.4): + resolution: {integrity: sha512-QG9EnzoGn+Qar7rxuW+ZOsbWOt56FvvI93xInqsZDC5fsekx1AlIO4KIJ5M+D0p0SqSH156EpmZyXq630B8OlQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.4 + '@babel/plugin-transform-react-jsx': 7.24.7(@babel/core@7.24.4) + transitivePeerDependencies: + - supports-color dev: true /@babel/plugin-transform-react-jsx-self@7.24.1(@babel/core@7.24.4): @@ -1268,7 +1438,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.24.4 - '@babel/helper-plugin-utils': 7.24.0 + '@babel/helper-plugin-utils': 7.24.7 dev: true /@babel/plugin-transform-react-jsx-source@7.24.1(@babel/core@7.24.4): @@ -1278,21 +1448,34 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.24.4 - '@babel/helper-plugin-utils': 7.24.0 + '@babel/helper-plugin-utils': 7.24.7 dev: true - /@babel/plugin-transform-react-jsx@7.23.4(@babel/core@7.24.4): - resolution: {integrity: sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA==} + /@babel/plugin-transform-react-jsx@7.24.7(@babel/core@7.24.4): + resolution: {integrity: sha512-+Dj06GDZEFRYvclU6k4bme55GKBEWUmByM/eoKuqg4zTNQHiApWRhQph5fxQB2wAEFvRzL1tOEj1RJ19wJrhoA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.24.4 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-module-imports': 7.24.3 - '@babel/helper-plugin-utils': 7.24.0 - '@babel/plugin-syntax-jsx': 7.24.1(@babel/core@7.24.4) - '@babel/types': 7.24.0 + '@babel/helper-annotate-as-pure': 7.24.7 + '@babel/helper-module-imports': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.24.4) + '@babel/types': 7.24.7 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-react-pure-annotations@7.24.7(@babel/core@7.24.4): + resolution: {integrity: sha512-PLgBVk3fzbmEjBJ/u8kFzOqS9tUeDjiaWud/rRym/yjCo/M9cASPlnrd2ZmmZpQT40fOOrvR8jh+n8jikrOhNA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.4 + '@babel/helper-annotate-as-pure': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 dev: true /@babel/plugin-transform-regenerator@7.24.1(@babel/core@7.24.4): @@ -1323,8 +1506,8 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.24.4 - '@babel/helper-module-imports': 7.24.3 - '@babel/helper-plugin-utils': 7.24.0 + '@babel/helper-module-imports': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 babel-plugin-polyfill-corejs2: 0.4.10(@babel/core@7.24.4) babel-plugin-polyfill-corejs3: 0.10.4(@babel/core@7.24.4) babel-plugin-polyfill-regenerator: 0.6.1(@babel/core@7.24.4) @@ -1539,8 +1722,8 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.24.4 - '@babel/helper-plugin-utils': 7.24.0 - '@babel/helper-validator-option': 7.23.5 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/helper-validator-option': 7.24.7 '@babel/plugin-transform-flow-strip-types': 7.24.1(@babel/core@7.24.4) dev: true @@ -1555,6 +1738,23 @@ packages: esutils: 2.0.3 dev: true + /@babel/preset-react@7.24.7(@babel/core@7.24.4): + resolution: {integrity: sha512-AAH4lEkpmzFWrGVlHaxJB7RLH21uPQ9+He+eFLWHmF9IuFQVugz8eAsamaW0DXRrTfco5zj1wWtpdcXJUOfsag==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.4 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/helper-validator-option': 7.24.7 + '@babel/plugin-transform-react-display-name': 7.24.7(@babel/core@7.24.4) + '@babel/plugin-transform-react-jsx': 7.24.7(@babel/core@7.24.4) + '@babel/plugin-transform-react-jsx-development': 7.24.7(@babel/core@7.24.4) + '@babel/plugin-transform-react-pure-annotations': 7.24.7(@babel/core@7.24.4) + transitivePeerDependencies: + - supports-color + dev: true + /@babel/preset-typescript@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-1DBaMmRDpuYQBPWD8Pf/WEwCrtgRHxsZnP4mIy9G/X+hFfbI47Q2G4t1Paakld84+qsk2fSsUPMKg71jkoOOaQ==} engines: {node: '>=6.9.0'} @@ -1603,6 +1803,15 @@ packages: '@babel/types': 7.24.0 dev: true + /@babel/template@7.24.7: + resolution: {integrity: sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.24.7 + '@babel/parser': 7.24.7 + '@babel/types': 7.24.7 + dev: true + /@babel/traverse@7.24.1: resolution: {integrity: sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==} engines: {node: '>=6.9.0'} @@ -1621,6 +1830,24 @@ packages: - supports-color dev: true + /@babel/traverse@7.24.7: + resolution: {integrity: sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.24.7 + '@babel/generator': 7.24.7 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-function-name': 7.24.7 + '@babel/helper-hoist-variables': 7.24.7 + '@babel/helper-split-export-declaration': 7.24.7 + '@babel/parser': 7.24.7 + '@babel/types': 7.24.7 + debug: 4.3.4(supports-color@8.1.1) + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: true + /@babel/types@7.24.0: resolution: {integrity: sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==} engines: {node: '>=6.9.0'} @@ -1630,6 +1857,15 @@ packages: to-fast-properties: 2.0.0 dev: true + /@babel/types@7.24.7: + resolution: {integrity: sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.24.7 + '@babel/helper-validator-identifier': 7.24.7 + to-fast-properties: 2.0.0 + dev: true + /@bcoe/v8-coverage@0.2.3: resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} dev: true @@ -1880,7 +2116,7 @@ packages: resolution: {integrity: sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==} dev: true - /@emotion/react@11.11.4(react@18.2.0): + /@emotion/react@11.11.4(react@18.3.1): resolution: {integrity: sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==} peerDependencies: '@types/react': '*' @@ -1893,11 +2129,11 @@ packages: '@emotion/babel-plugin': 11.11.0 '@emotion/cache': 11.11.0 '@emotion/serialize': 1.1.4 - '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.2.0) + '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.3.1) '@emotion/utils': 1.2.1 '@emotion/weak-memoize': 0.3.1 hoist-non-react-statics: 3.3.2 - react: 18.2.0 + react: 18.3.1 dev: true /@emotion/serialize@1.1.4: @@ -1914,7 +2150,7 @@ packages: resolution: {integrity: sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==} dev: true - /@emotion/styled@11.11.5(@emotion/react@11.11.4)(react@18.2.0): + /@emotion/styled@11.11.5(@emotion/react@11.11.4)(react@18.3.1): resolution: {integrity: sha512-/ZjjnaNKvuMPxcIiUkf/9SHoG4Q196DRl1w82hQ3WCsjo1IUR8uaGWrC6a87CrYAW0Kb/pK7hk8BnLgLRi9KoQ==} peerDependencies: '@emotion/react': ^11.0.0-rc.0 @@ -1927,23 +2163,23 @@ packages: '@babel/runtime': 7.24.4 '@emotion/babel-plugin': 11.11.0 '@emotion/is-prop-valid': 1.2.2 - '@emotion/react': 11.11.4(react@18.2.0) + '@emotion/react': 11.11.4(react@18.3.1) '@emotion/serialize': 1.1.4 - '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.2.0) + '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.3.1) '@emotion/utils': 1.2.1 - react: 18.2.0 + react: 18.3.1 dev: true /@emotion/unitless@0.8.1: resolution: {integrity: sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==} dev: true - /@emotion/use-insertion-effect-with-fallbacks@1.0.1(react@18.2.0): + /@emotion/use-insertion-effect-with-fallbacks@1.0.1(react@18.3.1): resolution: {integrity: sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==} peerDependencies: react: '>=16.8.0' dependencies: - react: 18.2.0 + react: 18.3.1 dev: true /@emotion/utils@1.2.1: @@ -2499,19 +2735,19 @@ packages: /@metamask/sdk-install-modal-web@0.14.1(react-native@0.73.6): resolution: {integrity: sha512-emT8HKbnfVwGhPxyUfMja6DWzvtJvDEBQxqCVx93H0HsyrrOzOC43iGCAosslw6o5h7gOfRKLqWmK8V7jQAS2Q==} dependencies: - '@emotion/react': 11.11.4(react@18.2.0) - '@emotion/styled': 11.11.5(@emotion/react@11.11.4)(react@18.2.0) + '@emotion/react': 11.11.4(react@18.3.1) + '@emotion/styled': 11.11.5(@emotion/react@11.11.4)(react@18.3.1) i18next: 22.5.1 qr-code-styling: 1.6.0-rc.1 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - react-i18next: 13.5.0(i18next@22.5.1)(react-dom@18.2.0)(react-native@0.73.6)(react@18.2.0) + react: 18.3.1 + react-dom: 18.2.0(react@18.3.1) + react-i18next: 13.5.0(i18next@22.5.1)(react-dom@18.2.0)(react-native@0.73.6)(react@18.3.1) transitivePeerDependencies: - '@types/react' - react-native dev: true - /@metamask/sdk@0.14.3(react-native@0.73.6)(react@18.2.0): + /@metamask/sdk@0.14.3(react-native@0.73.6)(react@18.3.1): resolution: {integrity: sha512-BYLs//nY2wioVSih78gOQI6sLIYY3vWkwVqXGYUgkBV+bi49bv+9S0m+hZ2cwiRaxfMYtKs0KvhAQ8weiYwDrg==} peerDependencies: react: ^18.2.0 @@ -2540,10 +2776,10 @@ packages: obj-multiplex: 1.0.0 pump: 3.0.0 qrcode-terminal-nooctal: 0.12.1 - react: 18.2.0 - react-i18next: 13.5.0(i18next@22.5.1)(react-dom@18.2.0)(react-native@0.73.6)(react@18.2.0) - react-native: 0.73.6(@babel/core@7.24.4)(@babel/preset-env@7.24.4)(react@18.2.0) - react-native-webview: 11.26.1(react-native@0.73.6)(react@18.2.0) + react: 18.3.1 + react-i18next: 13.5.0(i18next@22.5.1)(react-dom@18.2.0)(react-native@0.73.6)(react@18.3.1) + react-native: 0.73.6(@babel/core@7.24.4)(@babel/preset-env@7.24.4)(react@18.3.1) + react-native-webview: 11.26.1(react-native@0.73.6)(react@18.3.1) readable-stream: 2.3.8 rollup-plugin-visualizer: 5.12.0 socket.io-client: 4.7.5(bufferutil@4.0.8)(utf-8-validate@6.0.3) @@ -2682,7 +2918,6 @@ packages: /@noble/hashes@1.3.3: resolution: {integrity: sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==} engines: {node: '>= 16'} - dev: true /@noble/hashes@1.4.0: resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} @@ -2911,7 +3146,7 @@ packages: react-native: ^0.0.0-0 || >=0.60 <1.0 dependencies: merge-options: 3.0.4 - react-native: 0.73.6(@babel/core@7.24.4)(@babel/preset-env@7.24.4)(react@18.2.0) + react-native: 0.73.6(@babel/core@7.24.4)(@babel/preset-env@7.24.4)(react@18.3.1) dev: true /@react-native-community/cli-clean@12.3.6: @@ -3130,8 +3365,8 @@ packages: '@babel/plugin-transform-parameters': 7.24.1(@babel/core@7.24.4) '@babel/plugin-transform-private-methods': 7.24.1(@babel/core@7.24.4) '@babel/plugin-transform-private-property-in-object': 7.24.1(@babel/core@7.24.4) - '@babel/plugin-transform-react-display-name': 7.24.1(@babel/core@7.24.4) - '@babel/plugin-transform-react-jsx': 7.23.4(@babel/core@7.24.4) + '@babel/plugin-transform-react-display-name': 7.24.7(@babel/core@7.24.4) + '@babel/plugin-transform-react-jsx': 7.24.7(@babel/core@7.24.4) '@babel/plugin-transform-react-jsx-self': 7.24.1(@babel/core@7.24.4) '@babel/plugin-transform-react-jsx-source': 7.24.1(@babel/core@7.24.4) '@babel/plugin-transform-runtime': 7.24.3(@babel/core@7.24.4) @@ -3140,7 +3375,7 @@ packages: '@babel/plugin-transform-sticky-regex': 7.24.1(@babel/core@7.24.4) '@babel/plugin-transform-typescript': 7.24.4(@babel/core@7.24.4) '@babel/plugin-transform-unicode-regex': 7.24.1(@babel/core@7.24.4) - '@babel/template': 7.24.0 + '@babel/template': 7.24.7 '@react-native/babel-plugin-codegen': 0.73.4(@babel/preset-env@7.24.4) babel-plugin-transform-flow-enums: 0.0.2(@babel/core@7.24.4) react-refresh: 0.14.0 @@ -3155,7 +3390,7 @@ packages: peerDependencies: '@babel/preset-env': ^7.1.6 dependencies: - '@babel/parser': 7.24.4 + '@babel/parser': 7.24.7 '@babel/preset-env': 7.24.4(@babel/core@7.24.4) flow-parser: 0.206.0 glob: 7.2.3 @@ -3255,7 +3490,7 @@ packages: dependencies: invariant: 2.2.4 nullthrows: 1.1.1 - react-native: 0.73.6(@babel/core@7.24.4)(@babel/preset-env@7.24.4)(react@18.2.0) + react-native: 0.73.6(@babel/core@7.24.4)(@babel/preset-env@7.24.4)(react@18.3.1) dev: true /@rollup/plugin-alias@3.1.9(rollup@2.79.1): @@ -3366,7 +3601,7 @@ packages: resolution: {integrity: sha512-N1ZhksgwD3OBlwTv3R6KFEcPojl/W4ElJOeCZdi+vuI5QmTFwLq3OFf2zd2ROpKvxFdgZ6hUpb0dx9bVNEwYCA==} dependencies: '@noble/curves': 1.2.0 - '@noble/hashes': 1.3.2 + '@noble/hashes': 1.3.3 '@scure/base': 1.1.6 /@scure/bip32@1.3.3: @@ -3380,7 +3615,7 @@ packages: /@scure/bip39@1.2.1: resolution: {integrity: sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==} dependencies: - '@noble/hashes': 1.3.2 + '@noble/hashes': 1.3.3 '@scure/base': 1.1.6 /@scure/bip39@1.2.2: @@ -3564,17 +3799,32 @@ packages: '@stablelib/wipe': 1.0.1 dev: true + /@story-protocol/core-sdk@1.0.0-rc.14(typescript@5.4.5): + resolution: {integrity: sha512-7/CLt12G/HHdJazWTg5wDjYUb5oxbVJW2EUEmelP32rhVAHVbR+RhqgDtuM+4ISX+Eg1nbUHGG/dbhwbgBV4+A==} + dependencies: + abitype: 0.10.3(typescript@5.4.5) + axios: 1.6.8 + dotenv: 16.4.5 + viem: 2.9.16(typescript@5.4.5)(zod@3.22.4) + transitivePeerDependencies: + - bufferutil + - debug + - typescript + - utf-8-validate + - zod + dev: false + /@tanstack/query-core@5.29.0: resolution: {integrity: sha512-WgPTRs58hm9CMzEr5jpISe8HXa3qKQ8CxewdYZeVnA54JrPY9B1CZiwsCoLpLkf0dGRZq+LcX5OiJb0bEsOFww==} dev: true - /@tanstack/react-query@5.29.2(react@18.2.0): + /@tanstack/react-query@5.29.2(react@18.3.1): resolution: {integrity: sha512-nyuWILR4u7H5moLGSiifLh8kIqQDLNOHGuSz0rcp+J75fNc8aQLyr5+I2JCHU3n+nJrTTW1ssgAD8HiKD7IFBQ==} peerDependencies: react: ^18.0.0 dependencies: '@tanstack/query-core': 5.29.0 - react: 18.2.0 + react: 18.3.1 dev: true /@tsconfig/node10@1.0.11: @@ -3700,6 +3950,17 @@ packages: resolution: {integrity: sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==} dev: true + /@types/prop-types@15.7.12: + resolution: {integrity: sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==} + dev: true + + /@types/react@18.3.3: + resolution: {integrity: sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==} + dependencies: + '@types/prop-types': 15.7.12 + csstype: 3.1.3 + dev: true + /@types/resolve@1.17.1: resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==} dependencies: @@ -3918,7 +4179,7 @@ packages: - utf-8-validate dev: true - /@wagmi/connectors@4.1.25(@wagmi/core@2.6.16)(react-native@0.73.6)(react@18.2.0)(typescript@5.4.5)(viem@2.9.16): + /@wagmi/connectors@4.1.25(@wagmi/core@2.6.16)(react-native@0.73.6)(react@18.3.1)(typescript@5.4.5)(viem@2.9.16): resolution: {integrity: sha512-4Tot1Gtiv7uhiUAxZ9On37aai35l5S0sV7N2yQSNgzqXe55bAlI0cqyBAIJRvyKwOe1+hzKfoFqYQSaoCgj5Lg==} peerDependencies: '@wagmi/core': 2.6.16 @@ -3929,12 +4190,12 @@ packages: optional: true dependencies: '@coinbase/wallet-sdk': 3.9.1 - '@metamask/sdk': 0.14.3(react-native@0.73.6)(react@18.2.0) + '@metamask/sdk': 0.14.3(react-native@0.73.6)(react@18.3.1) '@safe-global/safe-apps-provider': 0.18.1(typescript@5.4.5) '@safe-global/safe-apps-sdk': 8.1.0(typescript@5.4.5) - '@wagmi/core': 2.6.16(react@18.2.0)(typescript@5.4.5)(viem@2.9.16) - '@walletconnect/ethereum-provider': 2.11.2(react@18.2.0) - '@walletconnect/modal': 2.6.2(react@18.2.0) + '@wagmi/core': 2.6.16(react@18.3.1)(typescript@5.4.5)(viem@2.9.16) + '@walletconnect/ethereum-provider': 2.11.2(react@18.3.1) + '@walletconnect/modal': 2.6.2(react@18.3.1) typescript: 5.4.5 viem: 2.9.16(typescript@5.4.5)(zod@3.22.4) transitivePeerDependencies: @@ -3964,7 +4225,7 @@ packages: - zod dev: true - /@wagmi/core@2.6.16(react@18.2.0)(typescript@5.4.5)(viem@2.9.16): + /@wagmi/core@2.6.16(react@18.3.1)(typescript@5.4.5)(viem@2.9.16): resolution: {integrity: sha512-95r+2CCf4Yz4CWG7UZMALIcGSUfpr9YbZ2HOqmz6gJEBaW9Cf9xUEZj2MXOHZIP+Ri/3CZJtbBEclDot4enZWA==} peerDependencies: '@tanstack/query-core': '>=5.0.0' @@ -3980,7 +4241,7 @@ packages: mipd: 0.0.5(typescript@5.4.5) typescript: 5.4.5 viem: 2.9.16(typescript@5.4.5)(zod@3.22.4) - zustand: 4.4.1(react@18.2.0) + zustand: 4.4.1(react@18.3.1) transitivePeerDependencies: - '@types/react' - bufferutil @@ -4036,14 +4297,14 @@ packages: tslib: 1.14.1 dev: true - /@walletconnect/ethereum-provider@2.11.2(react@18.2.0): + /@walletconnect/ethereum-provider@2.11.2(react@18.3.1): resolution: {integrity: sha512-BUDqee0Uy2rCZVkW5Ao3q6Ado/3fePYnFdryVF+YL6bPhj+xQZ5OfKodl+uvs7Rwq++O5wTX2RqOTzpW7+v+Mg==} dependencies: '@walletconnect/jsonrpc-http-connection': 1.0.7 '@walletconnect/jsonrpc-provider': 1.0.13 '@walletconnect/jsonrpc-types': 1.0.3 '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/modal': 2.6.2(react@18.2.0) + '@walletconnect/modal': 2.6.2(react@18.3.1) '@walletconnect/sign-client': 2.11.2 '@walletconnect/types': 2.11.2 '@walletconnect/universal-provider': 2.11.2 @@ -4166,19 +4427,19 @@ packages: pino: 7.11.0 dev: true - /@walletconnect/modal-core@2.6.2(react@18.2.0): + /@walletconnect/modal-core@2.6.2(react@18.3.1): resolution: {integrity: sha512-cv8ibvdOJQv2B+nyxP9IIFdxvQznMz8OOr/oR/AaUZym4hjXNL/l1a2UlSQBXrVjo3xxbouMxLb3kBsHoYP2CA==} dependencies: - valtio: 1.11.2(react@18.2.0) + valtio: 1.11.2(react@18.3.1) transitivePeerDependencies: - '@types/react' - react dev: true - /@walletconnect/modal-ui@2.6.2(react@18.2.0): + /@walletconnect/modal-ui@2.6.2(react@18.3.1): resolution: {integrity: sha512-rbdstM1HPGvr7jprQkyPggX7rP4XiCG85ZA+zWBEX0dVQg8PpAgRUqpeub4xQKDgY7pY/xLRXSiCVdWGqvG2HA==} dependencies: - '@walletconnect/modal-core': 2.6.2(react@18.2.0) + '@walletconnect/modal-core': 2.6.2(react@18.3.1) lit: 2.8.0 motion: 10.16.2 qrcode: 1.5.3 @@ -4187,11 +4448,11 @@ packages: - react dev: true - /@walletconnect/modal@2.6.2(react@18.2.0): + /@walletconnect/modal@2.6.2(react@18.3.1): resolution: {integrity: sha512-eFopgKi8AjKf/0U4SemvcYw9zlLpx9njVN8sf6DAkowC2Md0gPU/UNEbH1Wwj407pEKnEds98pKWib1NN1ACoA==} dependencies: - '@walletconnect/modal-core': 2.6.2(react@18.2.0) - '@walletconnect/modal-ui': 2.6.2(react@18.2.0) + '@walletconnect/modal-core': 2.6.2(react@18.3.1) + '@walletconnect/modal-ui': 2.6.2(react@18.3.1) transitivePeerDependencies: - '@types/react' - react @@ -4666,6 +4927,10 @@ packages: tslib: 2.6.2 dev: true + /async@3.2.5: + resolution: {integrity: sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==} + dev: false + /asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} dev: false @@ -5725,6 +5990,14 @@ packages: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} dev: true + /ejs@3.1.10: + resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} + engines: {node: '>=0.10.0'} + hasBin: true + dependencies: + jake: 10.9.1 + dev: false + /electron-to-chromium@1.4.735: resolution: {integrity: sha512-pkYpvwg8VyOTQAeBqZ7jsmpCjko1Qc6We1ZtZCjRyYbT5v4AIUKDy5cQTRotQlSSZmMr8jqpEt6JtOj5k7lR7A==} dev: true @@ -6337,6 +6610,12 @@ packages: dependencies: flat-cache: 3.2.0 + /filelist@1.0.4: + resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} + dependencies: + minimatch: 5.0.1 + dev: false + /fill-range@7.0.1: resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} engines: {node: '>=8'} @@ -7308,6 +7587,17 @@ packages: istanbul-lib-report: 3.0.1 dev: true + /jake@10.9.1: + resolution: {integrity: sha512-61btcOHNnLnsOdtLgA5efqQWjnSi/vow5HbI7HMdKKWqvrKR1bLK3BPlJn9gcSaP2ewuamUSMB5XEy76KUIS2w==} + engines: {node: '>=10'} + hasBin: true + dependencies: + async: 3.2.5 + chalk: 4.1.2 + filelist: 1.0.4 + minimatch: 3.1.2 + dev: false + /jest-environment-node@29.7.0: resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -7329,7 +7619,7 @@ packages: resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@babel/code-frame': 7.24.2 + '@babel/code-frame': 7.24.7 '@jest/types': 29.6.3 '@types/stack-utils': 2.0.3 chalk: 4.1.2 @@ -7417,7 +7707,6 @@ packages: /js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - dev: true /js-yaml@3.14.1: resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} @@ -7448,7 +7737,7 @@ packages: '@babel/preset-env': ^7.1.6 dependencies: '@babel/core': 7.24.4 - '@babel/parser': 7.24.4 + '@babel/parser': 7.24.7 '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.24.4) '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6(@babel/core@7.24.4) '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.24.4) @@ -7766,7 +8055,6 @@ packages: hasBin: true dependencies: js-tokens: 4.0.0 - dev: true /loupe@2.3.7: resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} @@ -8002,8 +8290,8 @@ packages: resolution: {integrity: sha512-+OVISBkPNxjD4eEKhblRpBf463nTMk3KMEeYS8Z4xM/z3qujGJGSsWUGRtH27+c6zElaSGtZFiDMshEb8mMKQg==} engines: {node: '>=18'} dependencies: - '@babel/traverse': 7.24.1 - '@babel/types': 7.24.0 + '@babel/traverse': 7.24.7 + '@babel/types': 7.24.7 invariant: 2.2.4 metro-symbolicate: 0.80.8 nullthrows: 1.1.1 @@ -8034,9 +8322,9 @@ packages: engines: {node: '>=18'} dependencies: '@babel/core': 7.24.4 - '@babel/generator': 7.24.4 - '@babel/template': 7.24.0 - '@babel/traverse': 7.24.1 + '@babel/generator': 7.24.7 + '@babel/template': 7.24.7 + '@babel/traverse': 7.24.7 nullthrows: 1.1.1 transitivePeerDependencies: - supports-color @@ -8047,9 +8335,9 @@ packages: engines: {node: '>=18'} dependencies: '@babel/core': 7.24.4 - '@babel/generator': 7.24.4 - '@babel/parser': 7.24.4 - '@babel/types': 7.24.0 + '@babel/generator': 7.24.7 + '@babel/parser': 7.24.7 + '@babel/types': 7.24.7 metro: 0.80.8 metro-babel-transformer: 0.80.8 metro-cache: 0.80.8 @@ -8070,13 +8358,13 @@ packages: engines: {node: '>=18'} hasBin: true dependencies: - '@babel/code-frame': 7.24.2 + '@babel/code-frame': 7.24.7 '@babel/core': 7.24.4 - '@babel/generator': 7.24.4 - '@babel/parser': 7.24.4 - '@babel/template': 7.24.0 - '@babel/traverse': 7.24.1 - '@babel/types': 7.24.0 + '@babel/generator': 7.24.7 + '@babel/parser': 7.24.7 + '@babel/template': 7.24.7 + '@babel/traverse': 7.24.7 + '@babel/types': 7.24.7 accepts: 1.3.8 chalk: 4.1.2 ci-info: 2.0.0 @@ -8192,7 +8480,6 @@ packages: engines: {node: '>=10'} dependencies: brace-expansion: 2.0.1 - dev: true /minimatch@9.0.3: resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} @@ -9105,17 +9392,17 @@ packages: - utf-8-validate dev: true - /react-dom@18.2.0(react@18.2.0): + /react-dom@18.2.0(react@18.3.1): resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} peerDependencies: react: ^18.2.0 dependencies: loose-envify: 1.4.0 - react: 18.2.0 + react: 18.3.1 scheduler: 0.23.0 dev: true - /react-i18next@13.5.0(i18next@22.5.1)(react-dom@18.2.0)(react-native@0.73.6)(react@18.2.0): + /react-i18next@13.5.0(i18next@22.5.1)(react-dom@18.2.0)(react-native@0.73.6)(react@18.3.1): resolution: {integrity: sha512-CFJ5NDGJ2MUyBohEHxljOq/39NQ972rh1ajnadG9BjTk+UXbHLq4z5DKEbEQBDoIhUmmbuS/fIMJKo6VOax1HA==} peerDependencies: i18next: '>= 23.2.3' @@ -9131,9 +9418,9 @@ packages: '@babel/runtime': 7.24.4 html-parse-stringify: 3.0.1 i18next: 22.5.1 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - react-native: 0.73.6(@babel/core@7.24.4)(@babel/preset-env@7.24.4)(react@18.2.0) + react: 18.3.1 + react-dom: 18.2.0(react@18.3.1) + react-native: 0.73.6(@babel/core@7.24.4)(@babel/preset-env@7.24.4)(react@18.3.1) dev: true /react-is@16.13.1: @@ -9148,7 +9435,7 @@ packages: resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} dev: true - /react-native-webview@11.26.1(react-native@0.73.6)(react@18.2.0): + /react-native-webview@11.26.1(react-native@0.73.6)(react@18.3.1): resolution: {integrity: sha512-hC7BkxOpf+z0UKhxFSFTPAM4shQzYmZHoELa6/8a/MspcjEP7ukYKpuSUTLDywQditT8yI9idfcKvfZDKQExGw==} peerDependencies: react: '*' @@ -9156,11 +9443,11 @@ packages: dependencies: escape-string-regexp: 2.0.0 invariant: 2.2.4 - react: 18.2.0 - react-native: 0.73.6(@babel/core@7.24.4)(@babel/preset-env@7.24.4)(react@18.2.0) + react: 18.3.1 + react-native: 0.73.6(@babel/core@7.24.4)(@babel/preset-env@7.24.4)(react@18.3.1) dev: true - /react-native@0.73.6(@babel/core@7.24.4)(@babel/preset-env@7.24.4)(react@18.2.0): + /react-native@0.73.6(@babel/core@7.24.4)(@babel/preset-env@7.24.4)(react@18.3.1): resolution: {integrity: sha512-oqmZe8D2/VolIzSPZw+oUd6j/bEmeRHwsLn1xLA5wllEYsZ5zNuMsDus235ONOnCRwexqof/J3aztyQswSmiaA==} engines: {node: '>=18'} hasBin: true @@ -9196,10 +9483,10 @@ packages: nullthrows: 1.1.1 pretty-format: 26.6.2 promise: 8.3.0 - react: 18.2.0 + react: 18.3.1 react-devtools-core: 4.28.5 react-refresh: 0.14.0 - react-shallow-renderer: 16.15.0(react@18.2.0) + react-shallow-renderer: 16.15.0(react@18.3.1) regenerator-runtime: 0.13.11 scheduler: 0.24.0-canary-efb381bbf-20230505 stacktrace-parser: 0.1.10 @@ -9220,22 +9507,21 @@ packages: engines: {node: '>=0.10.0'} dev: true - /react-shallow-renderer@16.15.0(react@18.2.0): + /react-shallow-renderer@16.15.0(react@18.3.1): resolution: {integrity: sha512-oScf2FqQ9LFVQgA73vr86xl2NaOIX73rh+YFqcOp68CWj56tSfgtGKrEbyhCj0rSijyG9M1CYprTh39fBi5hzA==} peerDependencies: react: ^16.0.0 || ^17.0.0 || ^18.0.0 dependencies: object-assign: 4.1.1 - react: 18.2.0 + react: 18.3.1 react-is: 18.2.0 dev: true - /react@18.2.0: - resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} + /react@18.3.1: + resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} engines: {node: '>=0.10.0'} dependencies: loose-envify: 1.4.0 - dev: true /read-pkg-up@7.0.1: resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} @@ -10596,12 +10882,12 @@ packages: dependencies: punycode: 2.3.1 - /use-sync-external-store@1.2.0(react@18.2.0): + /use-sync-external-store@1.2.0(react@18.3.1): resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: - react: 18.2.0 + react: 18.3.1 dev: true /utf-8-validate@6.0.3: @@ -10665,7 +10951,7 @@ packages: spdx-expression-parse: 3.0.1 dev: true - /valtio@1.11.2(react@18.2.0): + /valtio@1.11.2(react@18.3.1): resolution: {integrity: sha512-1XfIxnUXzyswPAPXo1P3Pdx2mq/pIqZICkWN60Hby0d9Iqb+MEIpqgYVlbflvHdrp2YR/q3jyKWRPJJ100yxaw==} engines: {node: '>=12.20.0'} peerDependencies: @@ -10678,8 +10964,8 @@ packages: optional: true dependencies: proxy-compare: 2.5.1 - react: 18.2.0 - use-sync-external-store: 1.2.0(react@18.2.0) + react: 18.3.1 + use-sync-external-store: 1.2.0(react@18.3.1) dev: true /vary@1.1.2: @@ -10741,7 +11027,7 @@ packages: engines: {node: '>=0.10.0'} dev: true - /wagmi@2.5.19(@tanstack/react-query@5.29.2)(react-native@0.73.6)(react@18.2.0)(typescript@5.4.5)(viem@2.9.16): + /wagmi@2.5.19(@tanstack/react-query@5.29.2)(react-native@0.73.6)(react@18.3.1)(typescript@5.4.5)(viem@2.9.16): resolution: {integrity: sha512-fy6s3qTuXpfrrghhoNXuV92yqOqJI7m/9iLIejHxEYxiddVDTR8BVdkt0BuBQZzoXSAutDkyIlJbtFcpX5dfrQ==} peerDependencies: '@tanstack/react-query': '>=5.0.0' @@ -10752,12 +11038,12 @@ packages: typescript: optional: true dependencies: - '@tanstack/react-query': 5.29.2(react@18.2.0) - '@wagmi/connectors': 4.1.25(@wagmi/core@2.6.16)(react-native@0.73.6)(react@18.2.0)(typescript@5.4.5)(viem@2.9.16) - '@wagmi/core': 2.6.16(react@18.2.0)(typescript@5.4.5)(viem@2.9.16) - react: 18.2.0 + '@tanstack/react-query': 5.29.2(react@18.3.1) + '@wagmi/connectors': 4.1.25(@wagmi/core@2.6.16)(react-native@0.73.6)(react@18.3.1)(typescript@5.4.5)(viem@2.9.16) + '@wagmi/core': 2.6.16(react@18.3.1)(typescript@5.4.5)(viem@2.9.16) + react: 18.3.1 typescript: 5.4.5 - use-sync-external-store: 1.2.0(react@18.2.0) + use-sync-external-store: 1.2.0(react@18.3.1) viem: 2.9.16(typescript@5.4.5)(zod@3.22.4) transitivePeerDependencies: - '@azure/app-configuration' @@ -11099,7 +11385,7 @@ packages: /zod@3.22.4: resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} - /zustand@4.4.1(react@18.2.0): + /zustand@4.4.1(react@18.3.1): resolution: {integrity: sha512-QCPfstAS4EBiTQzlaGP1gmorkh/UL1Leaj2tdj+zZCZ/9bm0WS7sI2wnfD5lpOszFqWJ1DcPnGoY8RDL61uokw==} engines: {node: '>=12.7.0'} peerDependencies: @@ -11114,6 +11400,6 @@ packages: react: optional: true dependencies: - react: 18.2.0 - use-sync-external-store: 1.2.0(react@18.2.0) + react: 18.3.1 + use-sync-external-store: 1.2.0(react@18.3.1) dev: true