{"_id":"0g-wagmi","_rev":"4-bb68d0c03aec92638a9300b3a29b7aba","name":"0g-wagmi","dist-tags":{"latest":"1.0.3"},"versions":{"1.0.0":{"name":"0g-wagmi","version":"1.0.0","keywords":["0g","wagmi","ethereum","web3","hooks"],"author":{"name":"Chomtana"},"license":"MIT","_id":"0g-wagmi@1.0.0","maintainers":[{"name":"chomtana","email":"Chomtana001@gmail.com"}],"homepage":"https://github.com/Chomtana/0g-wagmi#readme","bugs":{"url":"https://github.com/Chomtana/0g-wagmi/issues"},"dist":{"shasum":"494f4662a02535c87803ca1ddcd146eb28a7f373","tarball":"https://registry.npmjs.org/0g-wagmi/-/0g-wagmi-1.0.0.tgz","fileCount":23,"integrity":"sha512-GPSvoj7VTNZywU+kjx6Kgh5JvZ5G/ZSVTLeymorpnprjVyTYGsdvDOkCnDJ4WmOSrRdiFvyymd/SX9n6Quab4A==","signatures":[{"sig":"MEUCIQCSUMKk0FsXgsQYs3/sCPapNk84Hovy7xyWaydip2NgQAIgM9pK8fmLYuIGzV9nEVrvW4FlZJsfkyEAPEz7DAPTqtI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":154577},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"16f4a28abbfe674603715572aee7caa54dba3aa3","scripts":{"dev":"tsup --watch","test":"echo \"Error: no test specified\" && exit 1","build":"tsup"},"_npmUser":{"name":"chomtana","email":"Chomtana001@gmail.com"},"repository":{"url":"git+https://github.com/Chomtana/0g-wagmi.git","type":"git"},"_npmVersion":"10.9.2","description":"Wagmi hooks for 0G Compute Network","directories":{},"_nodeVersion":"22.17.0","dependencies":{},"_hasShrinkwrap":false,"packageManager":"pnpm@10.11.0","devDependencies":{"tsup":"^8.3.6","viem":"^2.37.8","react":"^19.1.0","wagmi":"^2.17.5","ethers":"^6.13.4","typescript":"^5.8.3","@types/react":"^19.1.2","@tanstack/react-query":"^5.62.14","@0glabs/0g-serving-broker":"^0.4.4"},"peerDependencies":{"viem":">=2.0.0","react":">=18","wagmi":">=2.0.0","ethers":">=6.13.0","@tanstack/react-query":">=5.0.0","@0glabs/0g-serving-broker":"^0.4.4"},"_npmOperationalInternal":{"tmp":"tmp/0g-wagmi_1.0.0_1759413920621_0.3582380244165644","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"0g-wagmi","version":"1.0.1","keywords":["0g","wagmi","ethereum","web3","hooks"],"author":{"name":"Chomtana"},"license":"MIT","_id":"0g-wagmi@1.0.1","maintainers":[{"name":"chomtana","email":"Chomtana001@gmail.com"}],"homepage":"https://github.com/Chomtana/0g-wagmi#readme","bugs":{"url":"https://github.com/Chomtana/0g-wagmi/issues"},"dist":{"shasum":"a4e2500ce1a04c329119bd60418efda2761a3f3e","tarball":"https://registry.npmjs.org/0g-wagmi/-/0g-wagmi-1.0.1.tgz","fileCount":23,"integrity":"sha512-nv89alCSlheD64FFA/BK4Hmzy2JKp3hhpKjIqj3CcDRCoKiOWGuHr9IKqA2IB8I4Ix8/a/++Xy3YmYHLf2mcCQ==","signatures":[{"sig":"MEYCIQDmKq5A0/m0OuhoRVaGsSmuNdU1yXAhLD1zuTVhgnlxiwIhAMsaDxcXeQPt4zfgOZONHpw8mgKfSHTOxkq2e6nhEUtZ","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":155719},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"e078c530b353ae4c722b0406b6e01f31267b2234","scripts":{"dev":"tsup --watch","test":"echo \"Error: no test specified\" && exit 1","build":"tsup"},"_npmUser":{"name":"chomtana","email":"Chomtana001@gmail.com"},"repository":{"url":"git+https://github.com/Chomtana/0g-wagmi.git","type":"git"},"_npmVersion":"10.9.2","description":"Wagmi hooks for 0G Compute Network","directories":{},"_nodeVersion":"22.17.0","dependencies":{},"_hasShrinkwrap":false,"packageManager":"pnpm@10.11.0","devDependencies":{"tsup":"^8.3.6","viem":"^2.37.8","react":"^19.1.0","wagmi":"^2.17.5","ethers":"^6.13.4","typescript":"^5.8.3","@types/react":"^19.1.2","@tanstack/react-query":"^5.62.14","@0glabs/0g-serving-broker":"^0.4.4"},"peerDependencies":{"viem":">=2.0.0","react":">=18","wagmi":">=2.0.0","ethers":">=6.13.0","@tanstack/react-query":">=5.0.0","@0glabs/0g-serving-broker":"^0.4.4"},"_npmOperationalInternal":{"tmp":"tmp/0g-wagmi_1.0.1_1759415006390_0.7805140045162924","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"0g-wagmi","version":"1.0.2","keywords":["0g","wagmi","ethereum","web3","hooks"],"author":{"name":"Chomtana"},"license":"MIT","_id":"0g-wagmi@1.0.2","maintainers":[{"name":"chomtana","email":"Chomtana001@gmail.com"}],"homepage":"https://github.com/Chomtana/0g-wagmi#readme","bugs":{"url":"https://github.com/Chomtana/0g-wagmi/issues"},"dist":{"shasum":"95ced0f19c7d045c70a6124aae881992ccb65d1b","tarball":"https://registry.npmjs.org/0g-wagmi/-/0g-wagmi-1.0.2.tgz","fileCount":27,"integrity":"sha512-0xah6VQbpk7YJRaXpEJdEmH0zGVDha2pzjgtBFqhjxapGiIDE0EfszrLyK9CbXpP6DTGHqJg8lC0QMuU15kdlQ==","signatures":[{"sig":"MEUCIFTfHnyRha7RAzQbaXsVvwZdo7DLKrQoRqVxyRIUo9nHAiEAtHAic8/NRwIEjvMSCLIzoiKGubZRCM0H7u40alRWrI8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":248464},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"87b19e4a847754e7dc72bf644f62c86dfcbc2e1c","scripts":{"dev":"tsup --watch","test":"echo \"Error: no test specified\" && exit 1","build":"tsup"},"_npmUser":{"name":"chomtana","email":"Chomtana001@gmail.com"},"repository":{"url":"git+https://github.com/Chomtana/0g-wagmi.git","type":"git"},"_npmVersion":"10.9.2","description":"Wagmi hooks for 0G Compute Network","directories":{},"_nodeVersion":"22.17.0","dependencies":{},"_hasShrinkwrap":false,"packageManager":"pnpm@10.11.0","devDependencies":{"tsup":"^8.3.6","viem":"^2.37.8","react":"^19.1.0","wagmi":"^2.17.5","ethers":"^6.13.4","typescript":"^5.8.3","@types/react":"^19.1.2","@0glabs/0g-ts-sdk":"^0.3.2","@tanstack/react-query":"^5.62.14","@0glabs/0g-serving-broker":"^0.5.4"},"peerDependencies":{"viem":">=2.0.0","react":">=18","wagmi":">=2.0.0","ethers":">=6.13.0","@0glabs/0g-ts-sdk":"^0.3.2","@tanstack/react-query":">=5.0.0","@0glabs/0g-serving-broker":"^0.5.4"},"_npmOperationalInternal":{"tmp":"tmp/0g-wagmi_1.0.2_1760917933540_0.3166224542184195","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"0g-wagmi","version":"1.0.3","description":"Wagmi hooks for 0G Compute Network","main":"./dist/index.js","module":"./dist/index.mjs","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"repository":{"type":"git","url":"git+https://github.com/Chomtana/0g-wagmi.git"},"scripts":{"build":"tsup","dev":"tsup --watch","test":"echo \"Error: no test specified\" && exit 1"},"keywords":["0g","wagmi","ethereum","web3","hooks"],"author":{"name":"Chomtana"},"license":"MIT","packageManager":"pnpm@10.11.0","peerDependencies":{"@0glabs/0g-serving-broker":"^0.5.4","@0glabs/0g-ts-sdk":"^0.3.2","@tanstack/react-query":">=5.0.0","ethers":">=6.13.0","react":">=18","viem":">=2.0.0","wagmi":">=2.0.0"},"dependencies":{},"devDependencies":{"@0glabs/0g-serving-broker":"^0.5.4","@0glabs/0g-ts-sdk":"^0.3.2","@tanstack/react-query":"^5.62.14","@types/react":"^19.1.2","ethers":"^6.13.4","react":"^19.1.0","tsup":"^8.3.6","typescript":"^5.8.3","viem":"^2.37.8","wagmi":"^2.17.5"},"_id":"0g-wagmi@1.0.3","gitHead":"cadbc6e3faf5d894f9de66d3e79441f2187c9bcc","bugs":{"url":"https://github.com/Chomtana/0g-wagmi/issues"},"homepage":"https://github.com/Chomtana/0g-wagmi#readme","_nodeVersion":"22.17.0","_npmVersion":"10.9.2","dist":{"integrity":"sha512-v4yDT3/qP8ix6pv9K+lkxaS3mID2xvWpAxqw/VPzZT5mdjryrqVsCXzbfMRxOs3z2i5XvVEdoPpui4meIH6gEA==","shasum":"20300c9edb478f000cc3ee77fb8f3c60605f43ba","tarball":"https://registry.npmjs.org/0g-wagmi/-/0g-wagmi-1.0.3.tgz","fileCount":31,"unpackedSize":341982,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIBow9qyF0dvJH3x9ZiiPdAIULBvlPNj/wDFntsUnEUrXAiEAwo5dcrUMyEUKrfD+cxkXZlWhqNYnSm4TqckeUgwxrJ0="}]},"_npmUser":{"name":"chomtana","email":"Chomtana001@gmail.com"},"directories":{},"maintainers":[{"name":"chomtana","email":"Chomtana001@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/0g-wagmi_1.0.3_1762274183757_0.2273871143247861"},"_hasShrinkwrap":false}},"time":{"created":"2025-10-02T14:05:20.476Z","modified":"2025-11-04T16:36:24.121Z","1.0.0":"2025-10-02T14:05:20.842Z","1.0.1":"2025-10-02T14:23:26.568Z","1.0.2":"2025-10-19T23:52:13.746Z","1.0.3":"2025-11-04T16:36:23.937Z"},"bugs":{"url":"https://github.com/Chomtana/0g-wagmi/issues"},"author":{"name":"Chomtana"},"license":"MIT","homepage":"https://github.com/Chomtana/0g-wagmi#readme","keywords":["0g","wagmi","ethereum","web3","hooks"],"repository":{"type":"git","url":"git+https://github.com/Chomtana/0g-wagmi.git"},"description":"Wagmi hooks for 0G Compute Network","maintainers":[{"name":"chomtana","email":"Chomtana001@gmail.com"}],"readme":"# 0G Wagmi SDK\n\nA monorepo containing wagmi hooks for interacting with the 0G Compute Network.\n\n## Packages\n\n- **`0g-wagmi`** - Core SDK with React hooks for 0G Network integration\n- **`examples`** - Example React application demonstrating the 0g-wagmi SDK usage\n- **`contracts`** - Smart contracts for Intelligent NFTs (iNFTs) with deployment scripts\n\n## 0g-wagmi SDK Usage\n\n### Installation\n```bash\nnpm install 0g-wagmi wagmi viem @tanstack/react-query ethers @0glabs/0g-serving-broker\n```\n\n### Quick Reference\n\n| Category | Hook | Description |\n|----------|------|-------------|\n| **AI Inference** | `use0gChat` | Interact with AI models (streaming & non-streaming) |\n| | `use0gServices` | List available AI services |\n| | `use0gServiceMetadata` | Get service metadata for a provider |\n| | `use0gBroker` | Get underlying broker instance |\n| **Broker Balance** | `use0gBalance` | Query broker balance |\n| | `use0gAddFunds` | Add funds to broker |\n| | `use0gWithdrawFunds` | Withdraw funds from broker |\n| | `use0gInferenceBalance` | Query inference balance for provider |\n| | `use0gInferenceAddFunds` | Add funds to specific provider |\n| **Storage** | `use0gStorageUpload` | Upload files to 0G Storage |\n| | `use0gStorageDownload` | Download files from 0G Storage |\n| | `use0gStorageFile` | Create 0G file objects & compute merkle root |\n| **Key-Value** | `use0gKeyValue` | Store and retrieve key-value pairs |\n| **iNFT** | `use0gInftMint` | Mint intelligent NFTs with AI metadata |\n| | `use0gInftList` | List user's iNFTs |\n| | `use0gInftMetadata` | Fetch and decrypt iNFT metadata |\n| **Utilities** | `useEthersSigner` | Convert wagmi client to ethers signer |\n\n### Available Hooks\n\n## AI Inference Hooks\n\n#### `use0gChat` (Non-streaming)\nInteract with AI models on the 0G network:\n\n```tsx\nimport ReactMarkdown from \"react-markdown\";\nimport remarkMath from \"remark-math\";\nimport remarkGfm from \"remark-gfm\";\nimport rehypeKatex from \"rehype-katex\";\nimport rehypeRaw from \"rehype-raw\";\nimport \"katex/dist/katex.min.css\";\nimport { use0gChat } from '0g-wagmi'\n\nfunction ChatComponent({ providerAddress }: { providerAddress: string }) {\n  const { chat, isLoading, error } = use0gChat(providerAddress)\n  const [question, setQuestion] = useState('')\n  const [response, setResponse] = useState('')\n\n  const handleSubmit = async () => {\n    try {\n      const answer = await chat(question)\n      setResponse(answer)\n    } catch (err) {\n      console.error('Chat error:', err)\n    }\n  }\n\n  return (\n    <div>\n      <input \n        value={question}\n        onChange={(e) => setQuestion(e.target.value)}\n        placeholder=\"Ask a question...\"\n      />\n      <button onClick={handleSubmit} disabled={isLoading}>\n        {isLoading ? 'Processing...' : 'Send'}\n      </button>\n\n      <div>Response:</div>\n      <div>\n        <ReactMarkdown\n          remarkPlugins={[remarkMath, remarkGfm]}\n          rehypePlugins={[rehypeKatex, rehypeRaw]}\n        >\n          {response}\n        </ReactMarkdown>\n      </div>\n\n      {error && <div>Error: {error}</div>}\n    </div>\n  )\n}\n```\n\nIn non-streaming mode, the user only receives the final response once the AI has completed all of its processing. The answer is delivered in full at the end, without showing the AI’s intermediate reasoning or thought process.\n\n#### `use0gChat` (Streaming)\nInteract with AI models on the 0G network with a streaming response by passing a callback function `(response, reason) => { ... }` in addition to the chat messages:\n\n```tsx\nimport ReactMarkdown from \"react-markdown\";\nimport remarkMath from \"remark-math\";\nimport remarkGfm from \"remark-gfm\";\nimport rehypeKatex from \"rehype-katex\";\nimport rehypeRaw from \"rehype-raw\";\nimport \"katex/dist/katex.min.css\";\nimport { use0gChat } from '0g-wagmi'\n\nfunction ChatComponent({ providerAddress }: { providerAddress: string }) {\n  const { chat, isLoading, error } = use0gChat(providerAddress)\n  const [question, setQuestion] = useState('')\n  const [response, setResponse] = useState('')\n  const [reason, setReason] = useState('')\n\n  const handleSubmit = async () => {\n    try {\n      const answer = await chat(question, (answer: string, reason: string) => {\n        setResponse(answer)\n        setReason(reason)\n      })\n    } catch (err) {\n      console.error('Chat error:', err)\n    }\n  }\n\n  return (\n    <div>\n      <input \n        value={question}\n        onChange={(e) => setQuestion(e.target.value)}\n        placeholder=\"Ask a question...\"\n      />\n      <button onClick={handleSubmit} disabled={isLoading}>\n        {isLoading ? 'Processing...' : 'Send'}\n      </button>\n\n      <div>Thinking Reason:</div>\n      <div>\n        <ReactMarkdown\n          remarkPlugins={[remarkMath, remarkGfm]}\n          rehypePlugins={[rehypeKatex, rehypeRaw]}\n        >\n          {reason}\n        </ReactMarkdown>\n      </div>\n\n      <div>Response:</div>\n      <div>\n        <ReactMarkdown\n          remarkPlugins={[remarkMath, remarkGfm]}\n          rehypePlugins={[rehypeKatex, rehypeRaw]}\n        >\n          {response}\n        </ReactMarkdown>\n      </div>\n\n      {error && <div>Error: {error}</div>}\n    </div>\n  )\n}\n```\n\nIn streaming mode, the AI begins sending partial responses as soon as processing starts. Instead of waiting for the full computation to finish, the user can see **both the answer and thinking reason** unfold in real time.\n\n#### Passing a series of chat messages\n\nThe `chat` function also supports multi-turn conversations. Simply pass in your conversation as an array of `ChatMessage` objects (`ChatMessage[]`):\n\n```tsx\nimport ReactMarkdown from \"react-markdown\";\nimport remarkMath from \"remark-math\";\nimport remarkGfm from \"remark-gfm\";\nimport rehypeKatex from \"rehype-katex\";\nimport rehypeRaw from \"rehype-raw\";\nimport \"katex/dist/katex.min.css\";\nimport { use0gChat, ChatMessage } from '0g-wagmi'\n\nfunction ChatWithHistory({ providerAddress }: { providerAddress: string }) {\n  const { chat, isLoading, error } = use0gChat(providerAddress)\n  const [messages, setMessages] = useState<ChatMessage[]>([\n    { role: \"system\", content: \"You are a helpful assistant.\" },\n    { role: \"user\", content: \"Hello, who won the World Cup in 2018?\" },\n    { role: \"assistant\", content: \"France won the 2018 FIFA World Cup.\" }\n  ])\n  const [question, setQuestion] = useState(\"\")\n  const [response, setResponse] = useState(\"\")\n  const [reason, setReason] = useState(\"\")\n\n  const handleSubmit = async () => {\n    try {\n      // Add the new user message to the conversation\n      const updatedMessages = [...messages, { role: \"user\", content: question }]\n      setMessages(updatedMessages)\n\n      // Pass the full history to the chat function\n      await chat(updatedMessages, (answer: string, reason: string) => {\n        setResponse(answer)\n        setReason(reason)\n      })\n    } catch (err) {\n      console.error(\"Chat error:\", err)\n    }\n  }\n\n  return (\n    <div>\n      <input \n        value={question}\n        onChange={(e) => setQuestion(e.target.value)}\n        placeholder=\"Ask a question...\"\n      />\n      <button onClick={handleSubmit} disabled={isLoading}>\n        {isLoading ? \"Processing...\" : \"Send\"}\n      </button>\n\n      <div>Thinking Reason:</div>\n      <div>\n        <ReactMarkdown\n          remarkPlugins={[remarkMath, remarkGfm]}\n          rehypePlugins={[rehypeKatex, rehypeRaw]}\n        >\n          {reason}\n        </ReactMarkdown>\n      </div>\n\n      <div>Response:</div>\n      <div>\n        <ReactMarkdown\n          remarkPlugins={[remarkMath, remarkGfm]}\n          rehypePlugins={[rehypeKatex, rehypeRaw]}\n        >\n          {response}\n        </ReactMarkdown>\n      </div>\n\n      {error && <div>Error: {error}</div>}\n    </div>\n  )\n}\n```\n\n#### `use0gBalance`\nQuery balance from the 0G broker:\n\n```tsx\nimport { use0gBalance } from '0g-wagmi'\n\nfunction BalanceComponent() {\n  const { balance, isLoading, refetch } = use0gBalance({\n    enabled: true,\n    refetchInterval: 30000, // Refetch every 30 seconds\n  })\n\n  if (isLoading) return <div>Loading...</div>\n  \n  return (\n    <div>\n      <p>Total: {balance ? (Number(balance.totalBalance) / 1e18).toFixed(6) : '0'} OG</p>\n      <p>Available: {balance ? (Number(balance.availableBalance) / 1e18).toFixed(6) : '0'} OG</p>\n      <button onClick={() => refetch()}>Refresh</button>\n    </div>\n  )\n}\n```\n\n#### `use0gAddFunds`\nAdd funds to the 0G broker:\n\n```tsx\nimport { use0gAddFunds } from '0g-wagmi'\n\nfunction AddFundsComponent() {\n  const { addFunds, isLoading } = use0gAddFunds({\n    onSuccess: (txHash) => {\n      console.log('Transaction successful:', txHash)\n    },\n    onError: (error) => {\n      console.error('Transaction failed:', error)\n    },\n  })\n\n  return (\n    <button \n      onClick={() => addFunds('0.1')}\n      disabled={isLoading}\n    >\n      {isLoading ? 'Adding...' : 'Add 0.1 OG'}\n    </button>\n  )\n}\n```\n\n#### `use0gWithdrawFunds`\nWithdraw funds from the 0G broker:\n\n```tsx\nimport { use0gWithdrawFunds } from '0g-wagmi'\n\nfunction WithdrawComponent() {\n  const { withdrawFunds, isLoading } = use0gWithdrawFunds({\n    onSuccess: (txHash) => {\n      console.log('Withdrawal successful:', txHash)\n    },\n    onError: (error) => {\n      console.error('Withdrawal failed:', error)\n    },\n  })\n\n  return (\n    <button \n      onClick={() => withdrawFunds('0.05')}\n      disabled={isLoading}\n    >\n      {isLoading ? 'Withdrawing...' : 'Withdraw 0.05 OG'}\n    </button>\n  )\n}\n```\n\n#### `use0gServices`\nList available AI services on the 0G network:\n\n```tsx\nimport { use0gServices } from '0g-wagmi'\n\nfunction ServicesComponent() {\n  const { services, isLoading, error } = use0gServices()\n\n  if (isLoading) return <div>Loading services...</div>\n  if (error) return <div>Error loading services</div>\n  \n  return (\n    <div>\n      {services?.map((service, index) => (\n        <div key={index}>\n          <h3>{service.model}</h3>\n          <p>Provider: {service.provider}</p>\n          <p>Input Price: {service.inputPrice.toString()} per 1M tokens</p>\n          <p>Output Price: {service.outputPrice.toString()} per 1M tokens</p>\n        </div>\n      ))}\n    </div>\n  )\n}\n```\n\n#### `use0gInferenceBalance`\nQuery inference-specific balance for a provider:\n\n```tsx\nimport { use0gInferenceBalance } from '0g-wagmi'\n\nfunction InferenceBalanceComponent({ providerAddress }: { providerAddress: string }) {\n  const { balance, isLoading, error, refetch } = use0gInferenceBalance(providerAddress)\n\n  if (isLoading) return <div>Loading balance...</div>\n  if (error) return <div>Error loading balance</div>\n  \n  return (\n    <div>\n      <p>Allocated Credit: {balance ? (Number(balance) / 1e18).toFixed(6) : '0'} OG</p>\n      <button onClick={() => refetch()}>Refresh</button>\n    </div>\n  )\n}\n```\n\n#### `use0gInferenceAddFunds`\nAdd funds to a specific inference provider:\n\n```tsx\nimport { use0gInferenceAddFunds } from '0g-wagmi'\n\nfunction AddInferenceFundsComponent({ providerAddress }: { providerAddress: string }) {\n  const { addFunds, isLoading } = use0gInferenceAddFunds()\n\n  const handleAddFunds = async () => {\n    try {\n      await addFunds(providerAddress, '0.1')\n      console.log('Funds added successfully')\n    } catch (err) {\n      console.error('Failed to add funds:', err)\n    }\n  }\n\n  return (\n    <button onClick={handleAddFunds} disabled={isLoading}>\n      {isLoading ? 'Adding...' : 'Add 0.1 OG to Provider'}\n    </button>\n  )\n}\n```\n\n#### `use0gBroker`\nGet the underlying 0G broker instance:\n\n```tsx\nimport { use0gBroker } from '0g-wagmi'\n\nfunction BrokerComponent() {\n  const { broker, isLoading, error } = use0gBroker()\n\n  if (isLoading) return <div>Initializing broker...</div>\n  if (error) return <div>Error: {error.message}</div>\n  if (!broker) return <div>Connect wallet to continue</div>\n\n  // Use broker directly for advanced operations\n  return <div>Broker initialized</div>\n}\n```\n\n#### `use0gServiceMetadata`\nGet detailed metadata for a specific service provider:\n\n```tsx\nimport { use0gServiceMetadata } from '0g-wagmi'\n\nfunction ServiceMetadataComponent({ providerAddress }: { providerAddress: string }) {\n  const { metadata, modelName, endpoint, isLoading, error } = use0gServiceMetadata(providerAddress)\n\n  if (isLoading) return <div>Loading service metadata...</div>\n  if (error) return <div>Error loading metadata</div>\n\n  return (\n    <div>\n      <h3>Service Details</h3>\n      <p>Model: {modelName}</p>\n      <p>Endpoint: {endpoint}</p>\n    </div>\n  )\n}\n```\n\n## Storage Hooks\n\n#### `use0gStorageUpload`\nUpload files to 0G Storage:\n\n```tsx\nimport { use0gStorageUpload } from '0g-wagmi'\n\nfunction UploadComponent() {\n  const [file, setFile] = useState<File | null>(null)\n  const { upload, isLoading, data, error, isSuccess } = use0gStorageUpload({\n    onSuccess: (result) => {\n      console.log('File uploaded successfully!')\n      console.log('Root Hash:', result.rootHash)\n      console.log('Transaction:', result.txHash)\n    },\n    onError: (err) => {\n      console.error('Upload failed:', err)\n    },\n  })\n\n  const handleUpload = async () => {\n    if (!file) return\n    try {\n      await upload(file)\n    } catch (err) {\n      console.error('Upload error:', err)\n    }\n  }\n\n  return (\n    <div>\n      <input\n        type=\"file\"\n        onChange={(e) => setFile(e.target.files?.[0] || null)}\n      />\n      <button onClick={handleUpload} disabled={!file || isLoading}>\n        {isLoading ? 'Uploading...' : 'Upload to 0G Storage'}\n      </button>\n\n      {isSuccess && data && (\n        <div>\n          <p>Root Hash: {data.rootHash}</p>\n          <p>Transaction: {data.txHash}</p>\n        </div>\n      )}\n\n      {error && <div>Error: {error.message}</div>}\n    </div>\n  )\n}\n```\n\n#### `use0gStorageDownload`\nDownload files from 0G Storage:\n\n```tsx\nimport { use0gStorageDownload } from '0g-wagmi'\n\nfunction DownloadComponent() {\n  const [rootHash, setRootHash] = useState('')\n  const { download, downloadAndSave, isLoading, data, error } = use0gStorageDownload({\n    onSuccess: (result) => {\n      console.log('File downloaded:', result.fileName)\n      console.log('Size:', result.fileData.byteLength, 'bytes')\n    },\n  })\n\n  const handleDownload = async () => {\n    if (!rootHash) return\n    try {\n      // Option 1: Download and get the data\n      const result = await download(rootHash, 'my-file.txt')\n\n      // Option 2: Download and automatically save to user's computer\n      // await downloadAndSave(rootHash, 'my-file.txt')\n    } catch (err) {\n      console.error('Download error:', err)\n    }\n  }\n\n  return (\n    <div>\n      <input\n        type=\"text\"\n        placeholder=\"Enter root hash\"\n        value={rootHash}\n        onChange={(e) => setRootHash(e.target.value)}\n      />\n      <button onClick={handleDownload} disabled={!rootHash || isLoading}>\n        {isLoading ? 'Downloading...' : 'Download from 0G Storage'}\n      </button>\n\n      {data && (\n        <div>\n          <p>File: {data.fileName}</p>\n          <p>Size: {(data.fileData.byteLength / 1024).toFixed(2)} KB</p>\n        </div>\n      )}\n\n      {error && <div>Error: {error.message}</div>}\n    </div>\n  )\n}\n```\n\n#### `use0gStorageFile`\nCreate 0G file objects and compute merkle root hash from browser files:\n\n```tsx\nimport { use0gStorageFile } from '0g-wagmi'\n\nfunction FileInfoComponent() {\n  const [file, setFile] = useState<File | null>(null)\n  const { file: zgFile, rootHash, error, isLoading } = use0gStorageFile(file)\n\n  return (\n    <div>\n      <input\n        type=\"file\"\n        onChange={(e) => setFile(e.target.files?.[0] || null)}\n      />\n\n      {isLoading && <div>Computing merkle root...</div>}\n\n      {rootHash && (\n        <div>\n          <p>File ready for upload</p>\n          <p>Root Hash: {rootHash}</p>\n        </div>\n      )}\n\n      {error && <div>Error: {error.message}</div>}\n    </div>\n  )\n}\n```\n\n## Key-Value Storage\n\n#### `use0gKeyValue`\nStore and retrieve key-value pairs on 0G Network:\n\n```tsx\nimport { use0gKeyValue } from '0g-wagmi'\n\nfunction KeyValueComponent() {\n  const streamId = 'your-stream-id'\n  const {\n    setValue,\n    getValue,\n    cachedValues,\n    isSettingValue,\n    setSuccess\n  } = use0gKeyValue({\n    streamId,\n    onSetSuccess: (result) => {\n      console.log('Value set successfully!')\n      console.log('Transaction:', result.txHash)\n    },\n  })\n\n  // Set a value\n  const handleSet = async () => {\n    try {\n      await setValue('myKey', 'myValue')\n    } catch (err) {\n      console.error('Set error:', err)\n    }\n  }\n\n  // Get a value\n  const MyValueDisplay = () => {\n    const { data: value, isLoading } = getValue('myKey')\n\n    if (isLoading) return <div>Loading...</div>\n    return <div>Value: {value || 'Not set'}</div>\n  }\n\n  return (\n    <div>\n      <button onClick={handleSet} disabled={isSettingValue}>\n        {isSettingValue ? 'Setting...' : 'Set Value'}\n      </button>\n\n      <MyValueDisplay />\n\n      {/* Access cached values */}\n      <div>Cached: {cachedValues['myKey'] || 'Not in cache'}</div>\n    </div>\n  )\n}\n```\n\n## Intelligent NFT (iNFT) Hooks\n\n#### `use0gInftMint`\nMint intelligent NFTs with encrypted metadata stored on 0G Storage:\n\n```tsx\nimport { use0gInftMint, InftMetadata } from '0g-wagmi'\n\nfunction MintInftComponent() {\n  const { mint, isLoading, data, error, isSuccess } = use0gInftMint({\n    onSuccess: (result) => {\n      console.log('iNFT minted!')\n      console.log('Token ID:', result.tokenId)\n      console.log('Metadata Hash:', result.metadataHash)\n    },\n  })\n\n  const handleMint = async () => {\n    const metadata: InftMetadata = {\n      name: 'My AI Agent',\n      description: 'An intelligent agent with unique capabilities',\n      aiModel: 'GPT-4',\n      image: 'https://example.com/image.png',\n      modelWeights: 'ipfs://weights-hash',\n      configuration: {\n        temperature: 0.7,\n        maxTokens: 2048,\n      },\n      attributes: [\n        { trait_type: 'Type', value: 'Conversational' },\n        { trait_type: 'Intelligence', value: 95 },\n      ],\n    }\n\n    try {\n      await mint(metadata)\n    } catch (err) {\n      console.error('Mint error:', err)\n    }\n  }\n\n  return (\n    <div>\n      <button onClick={handleMint} disabled={isLoading}>\n        {isLoading ? 'Minting...' : 'Mint iNFT'}\n      </button>\n\n      {isSuccess && data && (\n        <div>\n          <p>Token ID: {data.tokenId}</p>\n          <p>Metadata Hash: {data.metadataHash}</p>\n          <p>Transaction: {data.txHash}</p>\n        </div>\n      )}\n\n      {error && <div>Error: {error.message}</div>}\n    </div>\n  )\n}\n```\n\n#### `use0gInftList`\nList all iNFTs owned by the connected wallet:\n\n```tsx\nimport { use0gInftList } from '0g-wagmi'\n\nfunction MyInftsComponent() {\n  const { infts, isLoading, refetch } = use0gInftList({\n    enabled: true,\n  })\n\n  if (isLoading) return <div>Loading iNFTs...</div>\n\n  return (\n    <div>\n      <h2>My iNFTs ({infts.length})</h2>\n      <button onClick={() => refetch()}>Refresh</button>\n\n      {infts.map((inft) => (\n        <div key={inft.tokenId}>\n          <p>Token ID: {inft.tokenId}</p>\n          <p>Metadata Hash: {inft.metadataHash}</p>\n          <p>Owner: {inft.owner}</p>\n          <p>Minted: {new Date(inft.mintedAt).toLocaleDateString()}</p>\n        </div>\n      ))}\n    </div>\n  )\n}\n```\n\n#### `use0gInftMetadata`\nFetch and decrypt iNFT metadata from 0G Storage:\n\n```tsx\nimport { use0gInftMetadata } from '0g-wagmi'\n\nfunction InftMetadataComponent({ metadataHash }: { metadataHash: string }) {\n  const { data: metadata, isLoading, error } = use0gInftMetadata({\n    metadataHash,\n    enabled: !!metadataHash,\n  })\n\n  if (isLoading) return <div>Loading metadata...</div>\n  if (error) return <div>Error: {error.message}</div>\n  if (!metadata) return null\n\n  return (\n    <div>\n      <h3>{metadata.name}</h3>\n      <p>{metadata.description}</p>\n\n      {metadata.aiModel && <p>AI Model: {metadata.aiModel}</p>}\n\n      {metadata.image && (\n        <img src={metadata.image} alt={metadata.name} />\n      )}\n\n      {metadata.attributes && (\n        <div>\n          <h4>Attributes:</h4>\n          {metadata.attributes.map((attr, i) => (\n            <span key={i}>\n              {attr.trait_type}: {attr.value}\n            </span>\n          ))}\n        </div>\n      )}\n    </div>\n  )\n}\n```\n\n## Utility Hooks\n\n#### `useEthersSigner`\nConvert wagmi wallet client to ethers.js signer (useful for advanced integrations):\n\n```tsx\nimport { useEthersSigner } from '0g-wagmi'\nimport { ethers } from 'ethers'\n\nfunction CustomContractComponent() {\n  const signer = useEthersSigner()\n\n  const interactWithContract = async () => {\n    if (!signer) return\n\n    // Use signer with ethers.js contracts\n    const contract = new ethers.Contract(contractAddress, abi, signer)\n    const tx = await contract.someFunction()\n    await tx.wait()\n  }\n\n  return (\n    <button onClick={interactWithContract} disabled={!signer}>\n      Interact with Contract\n    </button>\n  )\n}\n```\n\n## Polyfills\n\nThe `@0glabs/0g-serving-broker` package depends on several Node.js server-side modules that are not available in the browser. To prevent build errors, make sure to exclude these modules from the Vite build process by creating `app/empty.js` and updating your configuration as shown below. You also need to include a Buffer polyfill.\n\n### app/empty.js\n\n```javascript\nconst unsupported = (name) => (..._args) => {\n  throw new Error(`child_process.${name} is not supported in this environment`);\n};\n\n// Functions\nexport const spawn = unsupported(\"spawn\");\nexport const exec = unsupported(\"exec\");\nexport const execFile = unsupported(\"execFile\");\nexport const fork = unsupported(\"fork\");\nexport const execSync = unsupported(\"execSync\");\nexport const spawnSync = unsupported(\"spawnSync\");\nexport const execFileSync = unsupported(\"execFileSync\");\n\n// Classes / symbols that libraries sometimes reference\nexport class ChildProcess {}\nexport const forkOpts = {}; // placeholder sometimes used in examples\n\n// Default export with the same members (helps with `import cp from 'child_process'`)\nexport default {\n  spawn,\n  exec,\n  execFile,\n  fork,\n  execSync,\n  spawnSync,\n  execFileSync,\n  ChildProcess,\n  forkOpts,\n};\n```\n\n### vite.config.ts\n\n```typescript\nexport default defineConfig({\n  ...,\n  resolve: {\n    alias: {\n      child_process: \"/src/empty.js\",\n      \"fs/promises\": \"/src/empty.js\",\n      fs: \"/src/empty.js\",\n      path: \"/src/empty.js\",\n    },\n  },\n  define: {\n    global: \"globalThis\",\n  },\n  optimizeDeps: {\n    include: [\"buffer\"],\n  },\n});\n```\n\n### package.json\nInstall `buffer` package\n\n## iNFT Smart Contracts\n\nThis repository includes complete smart contract infrastructure for Intelligent NFTs (iNFTs). See the dedicated documentation:\n\n- **[Quick Start Guide](./INFT_QUICKSTART.md)** - Get started in 5 minutes\n- **[Integration Guide](./INFT_INTEGRATION.md)** - Complete API reference and examples\n- **[Contract Documentation](./packages/contracts/README.md)** - Smart contract details and deployment\n\n### iNFT Features\n\n- 🤖 **AI-Powered NFTs** - Store AI models, weights, and configurations\n- 🔐 **Encrypted Metadata** - Secure storage on 0G Network\n- 🎨 **ERC-721 Compatible** - Works with existing NFT infrastructure\n- 📦 **Full Type Safety** - TypeScript support throughout\n- 🚀 **Production Ready** - Audited OpenZeppelin contracts\n\nTo deploy the iNFT contract:\n\n```bash\ncd packages/contracts\npnpm install\ncp .env.example .env\n# Edit .env with your private key\npnpm deploy\n```\n\nSee [INFT_QUICKSTART.md](./INFT_QUICKSTART.md) for detailed instructions.\n\n## Development\n\n1. **Install dependencies:**\n   ```bash\n   pnpm install\n   ```\n\n2. **Build the SDK and examples:**\n   ```bash\n   pnpm build\n   ```\n\n3. **Set up environment variables for the example app:**\n   ```bash\n   cp packages/examples/.env.example packages/examples/.env\n   ```\n\n   Edit `packages/examples/.env` and add your Reown (WalletConnect) project ID:\n   ```\n   REOWN_PROJECT_ID=your_project_id_here\n   ```\n\n   Optionally, add your deployed iNFT contract address:\n   ```\n   VITE_INFT_CONTRACT_ADDRESS=0x_your_contract_address\n   ```\n\n   Get your project ID from [Reown Cloud](https://cloud.reown.com/)\n\n4. **Run the example app:**\n   ```bash\n   pnpm dev\n   ```\n\n   The app will be available at `http://localhost:5173` (or next available port)\n\n## Examples\n\nThe examples package demonstrates all available hooks:\n\n- **AI Inference** - Chat with AI models on 0G Network\n- **Storage** - Upload and download files to/from 0G Storage\n- **Key-Value** - Store and retrieve key-value pairs\n- **iNFT** - Mint and manage intelligent NFTs\n- **Broker Management** - Add/withdraw funds, check balances\n\nNavigate through the tabs in the demo app to explore each feature.\n\n## Additional Resources\n\n- [0G Network Documentation](https://docs.0g.ai)\n- [0G iNFT Integration Docs](https://docs.0g.ai/developer-hub/building-on-0g/inft/integration)\n- [Reown (WalletConnect) Setup](https://cloud.reown.com/)\n\n## License\n\nMIT","readmeFilename":"README.md"}