{"_id":"@droplinked_inc/web3-ui","_rev":"3-240217c5dc122543038c9461277b47fb","name":"@droplinked_inc/web3-ui","dist-tags":{"latest":"0.3.1"},"versions":{"0.1.0":{"name":"@droplinked_inc/web3-ui","version":"0.1.0","license":"MIT","_id":"@droplinked_inc/web3-ui@0.1.0","maintainers":[{"name":"droplinked_inc","email":"ali@droplinked.com"}],"homepage":"https://github.com/droplinked/droplink-packages#readme","bugs":{"url":"https://github.com/droplinked/droplink-packages/issues"},"dist":{"shasum":"7f16487bfd4789a89a2ffa3e5ea05d7b15cd456a","tarball":"https://registry.npmjs.org/@droplinked_inc/web3-ui/-/web3-ui-0.1.0.tgz","fileCount":41,"integrity":"sha512-0ywUS7ms05cgMsFXwEruUUBPxINGJuvYOjNFbj8AeOJqAf7DROHu68AtB6e5txGQSEcuMdyr0vQyQEdYdPVkgg==","signatures":[{"sig":"MEUCIBiIXtJK5jjzEwYMj8Lb/i6Dy0QJp82iSI1oxigUIH+DAiEA5NYgVUF5Y6W2FbOdhVpbXPSox86th0bCcuE8YEysZYs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":58121},"main":"./dist/index.js","type":"module","_from":"file:droplinked_inc-web3-ui-0.1.0.tgz","types":"./dist/index.d.ts","engines":{"node":">=22.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"lint":"eslint src","test":"jest --passWithNoTests","build":"tsc -p tsconfig.json","typecheck":"tsc --noEmit -p tsconfig.json","test:coverage":"jest --coverage --passWithNoTests"},"_npmUser":{"name":"droplinked_inc","email":"ali@droplinked.com"},"_resolved":"/tmp/947f1d37e0c815ddd197b402a94d5a7c/droplinked_inc-web3-ui-0.1.0.tgz","_integrity":"sha512-0ywUS7ms05cgMsFXwEruUUBPxINGJuvYOjNFbj8AeOJqAf7DROHu68AtB6e5txGQSEcuMdyr0vQyQEdYdPVkgg==","repository":{"url":"git+https://github.com/droplinked/droplink-packages.git","type":"git","directory":"packages/web3-ui"},"_npmVersion":"10.9.7","description":"Hardened React UI primitives for droplinked web3 flows (payment & NFT claim).","directories":{},"sideEffects":false,"_nodeVersion":"22.22.2","dependencies":{"zod":"^3.23.8"},"publishConfig":{"access":"public","provenance":false},"_hasShrinkwrap":false,"devDependencies":{"react":"^18.3.1","react-dom":"^18.3.1","@types/react":"^18.3.12","@types/react-dom":"^18.3.1","@testing-library/react":"^16.0.1","jest-environment-jsdom":"^29.7.0","@testing-library/jest-dom":"^6.5.0"},"peerDependencies":{"react":"^18.0.0 || ^19.0.0"},"_npmOperationalInternal":{"tmp":"tmp/web3-ui_0.1.0_1779168343444_0.7425391114185469","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@droplinked_inc/web3-ui","version":"0.3.0","license":"MIT","_id":"@droplinked_inc/web3-ui@0.3.0","maintainers":[{"name":"droplinked_inc","email":"ali@droplinked.com"}],"homepage":"https://github.com/droplinked/droplink-packages#readme","bugs":{"url":"https://github.com/droplinked/droplink-packages/issues"},"dist":{"shasum":"f6b996efa008bf3864c966c7dc7e9ac1d5a82a12","tarball":"https://registry.npmjs.org/@droplinked_inc/web3-ui/-/web3-ui-0.3.0.tgz","fileCount":41,"integrity":"sha512-oMiCa/zZknvpOSmaQXUyw850xyBFL1c3RhEULXmVRUx8IromUJ4FxutaML9Mwx5umJhk037unhrU9uVEj6+iSw==","signatures":[{"sig":"MEYCIQCrwl+e/SEoaNJ65E45Yi2WKUc8z5UvAOiguQJenGLFtwIhAK8WZ+Q5AyJ21VaapPRo3tmg5lMLz8i+FePQXEej6hqd","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":59459},"main":"./dist/index.js","type":"module","_from":"file:droplinked_inc-web3-ui-0.3.0.tgz","types":"./dist/index.d.ts","engines":{"node":">=22.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"lint":"eslint src","test":"jest --passWithNoTests","build":"tsc -p tsconfig.json","typecheck":"tsc --noEmit -p tsconfig.typecheck.json","test:coverage":"jest --coverage --passWithNoTests"},"_npmUser":{"name":"droplinked_inc","email":"ali@droplinked.com"},"_resolved":"/tmp/be16fcb6c9c9f6d592233872d679803d/droplinked_inc-web3-ui-0.3.0.tgz","_integrity":"sha512-oMiCa/zZknvpOSmaQXUyw850xyBFL1c3RhEULXmVRUx8IromUJ4FxutaML9Mwx5umJhk037unhrU9uVEj6+iSw==","repository":{"url":"git+https://github.com/droplinked/droplink-packages.git","type":"git","directory":"packages/web3-ui"},"_npmVersion":"10.9.8","description":"Hardened React UI primitives for droplinked web3 flows (payment & NFT claim).","directories":{},"sideEffects":false,"_nodeVersion":"22.22.3","dependencies":{"zod":"^3.23.8"},"publishConfig":{"access":"public","provenance":false},"_hasShrinkwrap":false,"devDependencies":{"react":"^18.3.1","react-dom":"^18.3.1","@types/react":"^18.3.12","@types/react-dom":"^18.3.1","@testing-library/react":"^16.0.1","jest-environment-jsdom":"^29.7.0","@testing-library/jest-dom":"^6.5.0"},"peerDependencies":{"react":"^18.0.0 || ^19.0.0"},"_npmOperationalInternal":{"tmp":"tmp/web3-ui_0.3.0_1779326467513_0.581575172213425","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@droplinked_inc/web3-ui","version":"0.3.1","description":"Hardened React UI primitives for droplinked web3 flows (payment & NFT claim).","license":"MIT","type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"sideEffects":false,"publishConfig":{"provenance":false,"access":"public"},"repository":{"type":"git","url":"git+https://github.com/droplinked/droplink-packages.git","directory":"packages/web3-ui"},"dependencies":{"zod":"^3.23.8"},"peerDependencies":{"react":"^18.0.0 || ^19.0.0"},"devDependencies":{"@testing-library/jest-dom":"^6.5.0","@testing-library/react":"^16.1.0","@types/react":"^18.3.12","@types/react-dom":"^18.3.1","jest-environment-jsdom":"^29.7.0","react":"^19.0.0","react-dom":"^19.0.0"},"engines":{"node":">=22.0.0"},"scripts":{"build":"tsc -p tsconfig.json","test":"jest --passWithNoTests","test:coverage":"jest --coverage --passWithNoTests","lint":"eslint src","typecheck":"tsc --noEmit -p tsconfig.typecheck.json"},"_id":"@droplinked_inc/web3-ui@0.3.1","bugs":{"url":"https://github.com/droplinked/droplink-packages/issues"},"homepage":"https://github.com/droplinked/droplink-packages#readme","_integrity":"sha512-hXDljrWnQ4dugmn4d/Xxsqck7zB3WUvAtUUNwPDGNLJGSsDyvIGikmlVGYdMpeFIPEOw3NWk+2Tiu5ku/2xK6g==","_resolved":"/tmp/9958817fb7762e4b64b718ca226421fb/droplinked_inc-web3-ui-0.3.1.tgz","_from":"file:droplinked_inc-web3-ui-0.3.1.tgz","_nodeVersion":"22.23.1","_npmVersion":"11.19.0","dist":{"integrity":"sha512-hXDljrWnQ4dugmn4d/Xxsqck7zB3WUvAtUUNwPDGNLJGSsDyvIGikmlVGYdMpeFIPEOw3NWk+2Tiu5ku/2xK6g==","shasum":"530f418542904334b801c3ace38f79d364c775ff","tarball":"https://registry.npmjs.org/@droplinked_inc/web3-ui/-/web3-ui-0.3.1.tgz","fileCount":41,"unpackedSize":60186,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIEjoJzK+GWpCukxbPaWmNBisXfA6WDweyUVUymPDTEgcAiEAlNhrb8sxouRqyAnq9S+we/cSXk/K6mWasgCElV55+FI="}]},"_npmUser":{"name":"droplinked_inc","email":"ali@droplinked.com"},"directories":{},"maintainers":[{"name":"droplinked_inc","email":"ali@droplinked.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/web3-ui_0.3.1_1786016229771_0.10753096185325162"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-19T05:25:43.346Z","modified":"2026-08-06T11:37:10.088Z","0.1.0":"2026-05-19T05:25:43.617Z","0.3.0":"2026-05-21T01:21:07.666Z","0.3.1":"2026-08-06T11:37:09.935Z"},"bugs":{"url":"https://github.com/droplinked/droplink-packages/issues"},"license":"MIT","homepage":"https://github.com/droplinked/droplink-packages#readme","repository":{"type":"git","url":"git+https://github.com/droplinked/droplink-packages.git","directory":"packages/web3-ui"},"description":"Hardened React UI primitives for droplinked web3 flows (payment & NFT claim).","maintainers":[{"name":"droplinked_inc","email":"ali@droplinked.com"}],"readme":"# @droplinked_inc/web3-ui\n\n> Replaces `droplinked-web3-ui`. See [MIGRATION.md](../../docs/MIGRATION.md) for the swap path.\n\nHardened React UI primitives for droplinked web3 flows.\n\nThis is the first-pass rewrite of the original `droplinked-web3-ui@0.0.26`\n(hostile-published by an external actor and now deprecated). The public API\nsurface intentionally matches the `.d.ts` shape of the upstream package so\nexisting call sites continue to compile.\n\nThis package is a **pure renderer**. All wallet-protocol logic\n(chain selection, RPC, signing, broadcast, receipts) lives in\n`@droplinked_inc/wallet-connection` and is injected at runtime through a\n`WalletAdapter` interface. See [`THREAT_MODEL.md`](./THREAT_MODEL.md) for\nthe security delta vs. the upstream.\n\n## Install\n\n```bash\npnpm add @droplinked_inc/web3-ui\n```\n\n## Quick start\n\n```tsx\nimport {\n  DroplinkedWeb3Ui,\n  DropWeb3Provider,\n  Actions,\n  type WalletAdapter,\n} from '@droplinked_inc/web3-ui';\n\n// Bridge to @droplinked_inc/wallet-connection (or a stub in tests).\nconst adapter: WalletAdapter = {\n  async payWithCrypto({ cartId, shopId }) {\n    /* ... */\n    return orderId;\n  },\n  async claimNft({ orderId, skuId }) {\n    /* ... */\n    return { transactionHash, transactionUrl };\n  },\n};\n\nfunction App() {\n  return (\n    <DropWeb3Provider adapter={adapter}>\n      <Checkout />\n    </DropWeb3Provider>\n  );\n}\n```\n\n## Component gallery\n\n### `DroplinkedWeb3Ui` — `Actions.Payment`\n\nRenders a \"Pay with crypto\" button. Initiates the payment flow via the\nadapter, surfaces pending state, and invokes the caller-supplied\n`onSuccess(orderId)` / `onError(message)` callbacks.\n\n```tsx\n<DroplinkedWeb3Ui\n  action={Actions.Payment}\n  inputs={{\n    cartId: 'cart-abc',\n    shopId: 'shop-xyz',\n    onError: (msg) => console.error(msg),\n    onSuccess: (orderId) => console.log('paid:', orderId),\n  }}\n/>\n```\n\n| Prop               | Type                              | Required | Notes                                  |\n| ------------------ | --------------------------------- | -------- | -------------------------------------- |\n| `cartId`           | `string` (≤128 printable ASCII)   | yes      | Zod-validated at the component boundary |\n| `shopId`           | `string` (≤128 printable ASCII)   | yes      | \"                                      |\n| `onError(message)` | `(string) => void`                | yes      | Errors from adapter rejections         |\n| `onSuccess(id?)`   | `(string \\| undefined) => void`   | yes      | Empty / whitespace-only ids → `undefined` |\n\n### `DroplinkedWeb3Ui` — `Actions.ClaimNFT`\n\nRenders a customizable claim button. On click, calls\n`adapter.claimNft({ orderId, skuId })`, renders the resulting tx hash, and\nemits a \"view tx\" link **only if the adapter returned an https URL**.\n\n```tsx\n<DroplinkedWeb3Ui\n  action={Actions.ClaimNFT}\n  inputs={{\n    orderId: 'order-1',\n    skuId: 'sku-2',\n    buttonText: 'Claim NFT',\n    isButtonDisabled: false,\n    onError: (msg) => console.error(msg),\n    onSuccess: (txHash, txUrl) => console.log('claimed', txHash, txUrl),\n  }}\n/>\n```\n\n| Prop                 | Type                                | Required | Notes                                                 |\n| -------------------- | ----------------------------------- | -------- | ----------------------------------------------------- |\n| `orderId`            | `string` (≤128 printable ASCII)     | yes      |                                                       |\n| `skuId`              | `string` (≤128 printable ASCII)     | yes      |                                                       |\n| `buttonText`         | `string` (1–64 chars)               | yes      | Auto-escaped on render; control bytes stripped        |\n| `isButtonDisabled`   | `boolean`                           | yes      |                                                       |\n| `onError(message)`   | `(string) => void`                  | yes      |                                                       |\n| `onSuccess(hash,url)`| `(string, string) => void`          | yes      | `url` is `''` when adapter returned a non-https value |\n\n### `DropWeb3Provider`\n\nSupplies the `WalletAdapter` to the subtree.\n\n| Prop      | Type                       | Default | Notes                                                                 |\n| --------- | -------------------------- | ------- | --------------------------------------------------------------------- |\n| `adapter` | `WalletAdapter \\| null`    | `null`  | When `null`, all buttons render disabled and emit a config error toast |\n| `children`| `ReactNode`                | —       |                                                                       |\n\n### Utility exports\n\n- `parseHttpUrl(raw, opts)` — strict https URL parser, rejects\n  `javascript:` / `data:` / `vbscript:` / etc. Allows `http:` only with\n  `{ allowHttp: true }`.\n- `safeHref(raw, opts)` — returns the URL string or `undefined` for use\n  in JSX `href` props.\n- `safeText(value, fallback, maxLength)` — render-safe string coercion;\n  strips C0 / DEL, trims, length-caps.\n- `PaymentInputsSchema`, `ClaimNFTInputsSchema` — re-exported zod\n  schemas for consumer-side validation.\n\n## Design constraints\n\n1. **Pure renderer** — never talks to a wallet directly. Every wallet\n   call goes through the injected `WalletAdapter`. Move that logic into\n   `@droplinked_inc/wallet-connection`.\n2. **TypeScript strict** — no `any`, no `as` casts on user inputs (only\n   on the zod schema declaration to satisfy zod's\n   `z.function()` type-inference limitation).\n3. **No `dangerouslySetInnerHTML`** — anywhere. React's auto-escape is\n   sufficient and our `safeText` adds defense in depth.\n4. **No global state** — phase/error state lives in `useState`.\n5. **No embedded URLs / API keys / dev endpoints** — the upstream\n   bundle had `apiv3dev.droplinked.com` baked in (see PR body). All\n   network calls are delegated to the consumer's adapter.\n\n## Scripts\n\n```bash\npnpm --filter @droplinked_inc/web3-ui build         # tsc -p\npnpm --filter @droplinked_inc/web3-ui typecheck     # tsc --noEmit\npnpm --filter @droplinked_inc/web3-ui lint          # eslint src\npnpm --filter @droplinked_inc/web3-ui test:coverage # jest --coverage\n```\n","readmeFilename":"README.md"}