{"_id":"@doodlesteam/flooks","_rev":"3-f5851ff03ce3ac339e89ffe0696eaafd","name":"@doodlesteam/flooks","dist-tags":{"latest":"0.1.0"},"versions":{"0.0.2":{"name":"@doodlesteam/flooks","version":"0.0.2","keywords":["react","flow","fcl"],"author":{"name":"Doodles"},"license":"MIT","_id":"@doodlesteam/flooks@0.0.2","maintainers":[{"name":"robo7","email":"lucas@doodles.app"},{"name":"javzzi.doodles","email":"javi@doodles.app"},{"name":"androodles","email":"andrii@doodles.app"},{"name":"frenchloaf","email":"noah@doodles.app"},{"name":"doodleseng","email":"jay@doodles.app"}],"homepage":"https://github.com/Doodles/flooks#readme","bugs":{"url":"https://github.com/Doodles/flooks/issues"},"dist":{"shasum":"b99b76ed7ebbcd81c6b309a04ca8750d974e533a","tarball":"https://registry.npmjs.org/@doodlesteam/flooks/-/flooks-0.0.2.tgz","fileCount":57,"integrity":"sha512-GLsD6kN+d6KZOzeLdAhkuZVcT2r5G17PLhNKj+UQedzG7QOaVoQhllpxY9TbCkbdkWatrpno+RzJwmDX4jayig==","signatures":[{"sig":"MEUCIQDqkc5fw/+97HxX8wSfNLsr/ZH6Jhr9QDnMCTOXhMq4WAIgEIw4cN7YA6VS96nlsqMqeoxk43IqPOQyaWQPTwST6Tg=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":35602},"main":"dist/index.js","type":"commonjs","types":"dist/index.d.ts","gitHead":"40aa3a8247e959a8b29bc6978b00d62357ee0b62","scripts":{"lint":"eslint src test","test":"jest","build":"tsc --project tsconfig.build.json","prebuild":"npm run lint && npm run prettier && npm run test && npm run clean:build","prettier":"prettier src test --check","preversion":"npm install && npm run build","clean:build":"rm -rf ./dist","postversion":"npm publish","release:major":"npm version major","release:minor":"npm version minor","release:patch":"npm version patch","prepublishOnly":"npm run build"},"_npmUser":{"name":"javzzi.doodles","email":"javi@doodles.app"},"repository":{"url":"git+https://github.com/Doodles/flooks.git","type":"git"},"_npmVersion":"9.6.7","description":"Flooks provides React hooks for connecting to the Flow blockchain.","directories":{},"_nodeVersion":"18.17.1","dependencies":{"@onflow/fcl":"^1.6.0","@onflow/typedefs":"^1.1.1","@doodlesteam/floo":"^0.0.4","@tanstack/react-query":"^4.35.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","react":"^18.2.0","eslint":"^8.49.0","ts-jest":"^29.1.1","prettier":"^3.0.0","react-dom":"^18.2.0","@types/jest":"^29.5.4","@types/react":"^18.2.21","@onflow/types":"^1.1.0","@nx/eslint-plugin":"16.5.3","eslint-plugin-react":"^7.33.2","@testing-library/react":"^14.0.0","eslint-config-prettier":"^8.8.0","@typescript-eslint/parser":"5.61.0","eslint-plugin-react-hooks":"^4.6.0","@typescript-eslint/eslint-plugin":"5.61.0","@trivago/prettier-plugin-sort-imports":"^4.2.0"},"peerDependencies":{"react":"^18.2.0","react-dom":"^18.2.0"},"_npmOperationalInternal":{"tmp":"tmp/flooks_0.0.2_1694984539791_0.9138224578604968","host":"s3://npm-registry-packages"}},"0.0.3":{"name":"@doodlesteam/flooks","version":"0.0.3","keywords":["react","flow","fcl"],"author":{"name":"Doodles"},"license":"MIT","_id":"@doodlesteam/flooks@0.0.3","maintainers":[{"name":"robo7","email":"lucas@doodles.app"},{"name":"javzzi.doodles","email":"javi@doodles.app"},{"name":"androodles","email":"andrii@doodles.app"},{"name":"frenchloaf","email":"noah@doodles.app"},{"name":"doodleseng","email":"jay@doodles.app"}],"homepage":"https://github.com/Doodles/flooks#readme","bugs":{"url":"https://github.com/Doodles/flooks/issues"},"dist":{"shasum":"4553aa2a6b9868e389142738a64a093db25af8f9","tarball":"https://registry.npmjs.org/@doodlesteam/flooks/-/flooks-0.0.3.tgz","fileCount":57,"integrity":"sha512-PAS8y3wO6wqZmdgLbGOBCYRv7AVfTOHrUbk1c01zFlyOw3hhE7HaTo5IuUvzTU3jprUd/wv/9jbvKABTdc+hxw==","signatures":[{"sig":"MEYCIQCuEWw4090uLGPCtNDKEn1lrgE0uELSRIOvOjgjt6xHAwIhAIGLwT55JFkrXaeeSS5JXrNQ12sb1Gf7omYrnilgW1Ak","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":44409},"main":"dist/index.js","type":"commonjs","types":"dist/index.d.ts","gitHead":"42f1c4a946f95640033e960d567e22780df57ee0","scripts":{"lint":"eslint src test","test":"jest","build":"tsc --project tsconfig.build.json","prebuild":"npm run lint && npm run prettier && npm run test && npm run clean:build","prettier":"prettier src test --check","preversion":"npm install && npm run build","clean:build":"rm -rf ./dist","postversion":"npm publish","release:major":"npm version major","release:minor":"npm version minor","release:patch":"npm version patch","prepublishOnly":"npm run build"},"_npmUser":{"name":"javzzi.doodles","email":"javi@doodles.app"},"repository":{"url":"git+https://github.com/Doodles/flooks.git","type":"git"},"_npmVersion":"9.6.7","description":"Flooks provides React hooks for connecting to the Flow blockchain.","directories":{},"_nodeVersion":"18.17.1","dependencies":{"@onflow/fcl":"^1.6.0","@onflow/typedefs":"^1.1.1","@doodlesteam/floo":"^0.0.4","@tanstack/react-query":"^4.35.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","react":"^18.2.0","eslint":"^8.49.0","ts-jest":"^29.1.1","prettier":"^3.0.0","react-dom":"^18.2.0","@types/jest":"^29.5.4","@types/react":"^18.2.21","@onflow/types":"^1.1.0","@nx/eslint-plugin":"16.5.3","eslint-plugin-react":"^7.33.2","@testing-library/react":"^14.0.0","eslint-config-prettier":"^8.8.0","@typescript-eslint/parser":"5.61.0","eslint-plugin-react-hooks":"^4.6.0","@typescript-eslint/eslint-plugin":"5.61.0","@trivago/prettier-plugin-sort-imports":"^4.2.0"},"peerDependencies":{"react":"^18.2.0","react-dom":"^18.2.0"},"_npmOperationalInternal":{"tmp":"tmp/flooks_0.0.3_1695168888509_0.6027373165405006","host":"s3://npm-registry-packages"}},"0.1.0":{"name":"@doodlesteam/flooks","version":"0.1.0","keywords":["react","flow","fcl"],"author":{"name":"Doodles"},"license":"MIT","_id":"@doodlesteam/flooks@0.1.0","maintainers":[{"name":"robo7","email":"lucas@doodles.app"},{"name":"javzzi.doodles","email":"javi@doodles.app"},{"name":"androodles","email":"andrii@doodles.app"},{"name":"frenchloaf","email":"noah@doodles.app"},{"name":"doodleseng","email":"jay@doodles.app"}],"homepage":"https://github.com/Doodles/flooks#readme","bugs":{"url":"https://github.com/Doodles/flooks/issues"},"dist":{"shasum":"b0643535424f2190c132ef4db55efd1506ccfd27","tarball":"https://registry.npmjs.org/@doodlesteam/flooks/-/flooks-0.1.0.tgz","fileCount":57,"integrity":"sha512-ocK8cxss8ON4n5ilQpTq6nmO2DbQJ3rAkglbwJF6EaCv54vwzUtvLDVosXIRJ+V4dq4414NGf4zy6BsPwmICSQ==","signatures":[{"sig":"MEYCIQDL3R2Pb8TD7UJ0JePKCqLL6uoXYCdPXL0d+wm28jQntAIhAL7Cbnak2Jj5hKHujHKBoiqCDfsldK7sH1fJ73NWhw7R","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":45513},"main":"dist/index.js","type":"commonjs","types":"dist/index.d.ts","gitHead":"1b141bd7f4642cd89ecdadab83058d320132ffa3","scripts":{"lint":"eslint src test","test":"jest","build":"tsc --project tsconfig.build.json","prepare":"husky install","prebuild":"npm run lint && npm run prettier && npm run test && npm run clean:build","prettier":"prettier src test --check","preversion":"npm install && npm run build","clean:build":"rm -rf ./dist","postversion":"npm publish","release:major":"npm version major","release:minor":"npm version minor","release:patch":"npm version patch","prepublishOnly":"npm run build"},"_npmUser":{"name":"javzzi.doodles","email":"javi@doodles.app"},"repository":{"url":"git+https://github.com/Doodles/flooks.git","type":"git"},"_npmVersion":"9.6.7","description":"Flooks provides React hooks for connecting to the Flow blockchain.","directories":{},"_nodeVersion":"18.17.1","dependencies":{"lodash":"^4.17.21","@onflow/fcl":"^1.6.0","@types/lodash":"^4.14.200","@onflow/typedefs":"^1.1.1","@doodlesteam/floo":"^0.1.0","@tanstack/react-query":"^4.35.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","husky":"^8.0.3","react":"^18.2.0","eslint":"^8.53.0","ts-jest":"^29.1.1","prettier":"^3.1.0","react-dom":"^18.2.0","@types/jest":"^29.5.4","@types/react":"^18.2.21","@onflow/types":"^1.1.0","@nx/eslint-plugin":"^17.1.2","eslint-plugin-react":"^7.33.2","@testing-library/react":"^14.0.0","eslint-config-prettier":"^9.0.0","@typescript-eslint/parser":"^6.11.0","eslint-plugin-react-hooks":"^4.6.0","@typescript-eslint/eslint-plugin":"^6.11.0","@trivago/prettier-plugin-sort-imports":"^4.3.0"},"peerDependencies":{"react":"^18.2.0","react-dom":"^18.2.0"},"_npmOperationalInternal":{"tmp":"tmp/flooks_0.1.0_1704494881187_0.10668619641875088","host":"s3://npm-registry-packages"}}},"time":{"created":"2023-09-17T21:02:19.615Z","modified":"2024-10-29T15:50:12.451Z","0.0.2":"2023-09-17T21:02:19.999Z","0.0.3":"2023-09-20T00:14:48.732Z","0.1.0":"2024-01-05T22:48:01.412Z"},"bugs":{"url":"https://github.com/Doodles/flooks/issues"},"author":{"name":"Doodles"},"license":"MIT","homepage":"https://github.com/Doodles/flooks#readme","keywords":["react","flow","fcl"],"repository":{"url":"git+https://github.com/Doodles/flooks.git","type":"git"},"description":"Flooks provides React hooks for connecting to the Flow blockchain.","maintainers":[{"email":"lucas@doodles.app","name":"robo7"},{"email":"javi@doodles.app","name":"javzzi.doodles"},{"email":"noah@doodles.app","name":"frenchloaf"},{"email":"jay@doodles.app","name":"doodleseng"}],"readme":"[![npm version](https://badge.fury.io/js/@doodlesteam%2Fflooks.svg)](https://badge.fury.io/js/@doodlesteam%2Fflooks)\n\n# Flooks (Beta)\n\nFlooks is a library that provides React hooks to interact with Flow blockchain, making development easy and intuitive. It's wagmi for Flow!\n\n### 🚧 Work In Progress 🚧\n\nThis package is currently in beta. While we are putting a lot of effort into ensuring it's as robust as possible, you may encounter breaking changes or occasional bugs. If you find value in what we're building, please consider giving us a ⭐. Your feedback and stars motivate us to make this package the best way to integrate Flow in any React app!\n\n## Table of contents\n\n- [Install](#install)\n- [Quick Start](#quick-start)\n- [Usage](#usage)\n  - [Account](#account)\n  - [Scripts](#scripts)\n  - [Transactions](#transactions)\n  - [Events](#events)\n- [License](#license)\n\n## Install\n\n```sh\nnpm install @doodlesteam/flooks\n```\n\n## Quick Start\n\nConfigure your Flow connection and add a FlowProvider:\n\n```ts\nimport { FlowProvider, configureChains } from '@doodlesteam/flooks';\nimport Profile from './Profile';\n\nconfigureChains({\n  title: 'MyDapp',\n  accessNodeApi: 'https://rest-testnet.onflow.org',\n  discoveryWallet: 'https://staging.accounts.meetdapper.com/fcl/authn-restricted',\n  network: 'testnet',\n});\n\nfunction App() {\n  return (\n    <FlowProvider>\n      <Profile />\n    </FlowProvider>\n  );\n}\n```\n\nInside the profile, you can add more hooks to handle connection:\n\n```ts\nimport {\n  useFlowAccount,\n  useFlowConnect,\n  useFlowDisconnect\n} from '@doodlesteam/flooks';\n\nfunction Profile() {\n  const { address } = useFlowAccount();\n  const { connect } = useFlowConnect();\n  const { disconnect } = useFlowDisconnect();\n\n  if (address)\n    return (\n      <div>\n        Connected to {address}\n        <button onClick={() => disconnect()}>Disconnect</button>\n      </div>\n    );\n  return <button onClick={() => connect()}>Connect Wallet</button>;\n}\n```\n\n## Usage\n\n### Account\n\n`useFlowAccount` provides you with callbacks to handle connection:\n\n```ts\nimport { useFlowAccount } from '@doodlesteam/flooks';\nimport { useAccountContext } from '../contexts/AccountContext';\n\nfunction Component {\n  const { dispatch } = useAccountContext();\n\n  const account = useFlowAccount({\n    onConnect: (connectedAccount) => {\n      dispatch({ type: 'accountConnected', payload: connectedAccount });\n    },\n    onDisconnect: () => {\n      dispatch({ type: 'accountDisconnected' });\n    },\n  });\n\n  // Rest of the code...\n}\n```\n\n### Scripts\n\nYou can fetch data from the blockchain using `useFlowScript`:\n\n```ts\nimport { useFlowScript } from '@doodlesteam/flooks';\n\nconst script = `\n  pub fun main(x: Int, y: Int): Int {\n    return x + y\n  }`;\n\nfunction Component {\n  const { data } = useFlowScript<number>({\n    code: script,\n    args: [1, 2],\n  });\n\n  // Rest of the code...\n}\n```\n\nArguments are automatically parsed and validated from your script, so you don't have to specify each argument type manually.\n\nYou can optionally define the expected result type. In this case `data` will be a number.\n\nFlooks uses [react-query](https://www.npmjs.com/package/@tanstack/react-query) in the background, so you also get all its features, like retries and refetch intervals.\n\n---\n\nDoing the same with fcl:\n\n```ts\nimport { useEffect, useState } from \"react\";\nimport * as fcl from \"@onflow/fcl\";\n\nconst script = `\n  pub fun main(x: Int, y: Int): Int {\n    return x + y\n  }`;\n\nfunction Component {\n  const [result, setResult] = useState<number>();\n\n  useEffect(() => {\n    fcl.query({\n      cadence: script,\n      args: (arg, t) => [arg(\"1\", t.Int), arg(\"2\", t.Int)],\n    }).then((data) => {\n      setResult(data);\n    });\n  }, []);\n\n  // Rest of the code...\n}\n```\n\n### Transactions\n\nExecute transactions using `useFlowTransaction`:\n\n```ts\nimport { useFlowTransaction } from '@doodlesteam/flooks';\n\nconst transaction = `\n  import NonFungibleToken from 0x...\n  import Doodles from 0x...\n\n  transaction(recipient: Address, nftID: UInt64) {\n    let withdrawRef: &Doodles.Collection\n    let depositRef: &Doodles.Collection{NonFungibleToken.Receiver}\n\n    prepare(signer: AuthAccount) {\n      self.withdrawRef = signer.borrow<&Doodles.Collection>(from: Doodles.CollectionStoragePath)\n        ?? panic(\"Account does not store an object at the specified path\")\n\n      self.depositRef = getAccount(recipient).getCapability(Doodles.CollectionPublicPath)\n        .borrow<&Doodles.Collection{NonFungibleToken.CollectionPublic}>()\n          ?? panic(\"Could not borrow a reference to the receiver's collection\")\n    }\n\n    execute {\n      let nft <- self.withdrawRef.withdraw(withdrawID: nftID)\n      self.depositRef.deposit(token: <-nft)\n    }\n  }`;\n\nfunction Component {\n  const { execute, isIdle, isLoading, isSealed, isError } =\n    useFlowTransaction({\n      code: transaction,\n      args: ['0x...', 1],\n      onTransactionSealed(result) {\n        console.log('Transaction completed!', result.transactionId);\n        for (const event of result.events) {\n          console.log(event.type, event.data);\n        }\n      },\n      onTransactionError(result) {\n        console.error(result.error);\n      },\n    });\n\n  return (\n    <button disabled={!isIdle} onClick={() => execute()}>\n      {isIdle && 'Transfer NFT'}\n      {isLoading && 'Loading...'}\n      {isSealed && 'Sealed!'}\n      {isError && 'Error'}\n    </button>\n  );\n}\n```\n\n`useFlowTransaction` also provides you with automatic parsed and validated arguments, and also subscribes to transaction status.\n\n---\n\nDoing the same with fcl:\n\n```ts\nimport { useEffect, useState } from \"react\";\nimport * as fcl from \"@onflow/fcl\";\n\nconst transaction = `\n  import NonFungibleToken from 0x...\n  import Doodles from 0x...\n\n  transaction(recipient: Address, nftID: UInt64) {\n    let withdrawRef: &Doodles.Collection\n    let depositRef: &Doodles.Collection{NonFungibleToken.Receiver}\n\n    prepare(signer: AuthAccount) {\n      self.withdrawRef = signer.borrow<&Doodles.Collection>(from: Doodles.CollectionStoragePath)\n        ?? panic(\"Account does not store an object at the specified path\")\n\n      self.depositRef = getAccount(recipient).getCapability(Doodles.CollectionPublicPath)\n        .borrow<&Doodles.Collection{NonFungibleToken.CollectionPublic}>()\n          ?? panic(\"Could not borrow a reference to the receiver's collection\")\n    }\n\n    execute {\n      let nft <- self.withdrawRef.withdraw(withdrawID: nftID)\n      self.depositRef.deposit(token: <-nft)\n    }\n  }`;\n\nfunction Component {\n  const [txStatus, setTxStatus] = useState();\n  const [txUnsubscribe, setTxUnsubscribe] = useState();\n\n  const execute = async () => {\n    const transactionId = await fcl.mutate({\n      cadence: transaction,\n      args: (arg, t) => [arg(\"0x...\", t.Address), arg(\"1\", t.UInt64)],\n    });\n\n    const unsubscribe = fcl.tx(txId).subscribe(setTxStatus);\n    setTxUnsubscribe(unsubscribe);\n  }\n\n  useEffect(() => {\n    if (txStatus?.status === 4) {\n      console.log('Transaction completed!', txStatus.transactionId);\n      for (const event of txStatus.events) {\n        console.log(event.type, event.data);\n      }\n      txUnsubscribe();\n    } else if (txStatus?.errorMessage !== '') {\n      console.error(result.error);\n      txUnsubscribe();\n    }\n  }, [txStatus]);\n\n  return (\n    <button disabled={!isIdle} onClick={() => execute()}>\n      {!txStatus && 'Transfer NFT'}\n      {[1, 2, 3].includes(txStatus?.status) && 'Loading...'}\n      {txStatus?.status === 4 && 'Sealed!'}\n      {txStatus?.errorMessage !== '' && 'Error'}\n    </button>\n  );\n}\n```\n\n### Events\n\nYou can subscribe to events using `useFlowEvent`:\n\n```ts\nimport { useFlowEvent } from '@doodlesteam/flooks';\n\ninterface TokensWithdrawnData {\n  amount: string;\n  from: string\n};\n\nfunction Component {\n  useFlowEvent<TokensWithdrawnData>({\n    eventName: {\n      contractAddress: '0x7e60df042a9c0868', // Flooks will automatically remove the '0x' prefix\n      contractName: 'FlowToken',\n      eventName: 'TokensWithdrawn',\n    },\n    listener: (event: TokensWithdrawnData) => {\n      console.log('TokensWithdrawn', event.amount, event.from);\n    },\n  });\n\n  // Rest of the code...\n}\n```\n\nYou can also pass the `eventName` argument as a string like fcl:\n\n```\neventName: 'A.7e60df042a9c0868.FlowToken.TokensWithdrawn',\n```\n\nAre you waiting just for the first event emitted? Use the `once` argument:\n\n```ts\nimport { useFlowEvent } from '@doodlesteam/flooks';\n\nfunction Component {\n  useFlowEvent<{winner: string}>({\n    eventName: {\n      contractAddress: '...',\n      contractName: 'Auction',\n      eventName: 'ClosedAuction',\n    },\n    once: true,\n    listener: (event) => {\n      // This will only be executed once\n      console.log('Winner address', event.winner);\n    },\n  });\n\n  // Rest of the code...\n}\n```\n\n## License\n\n[MIT License](./LICENSE)\n","readmeFilename":"README.md"}