@thehoneyjar/sigil-lens 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/wagmi.js ADDED
@@ -0,0 +1,74 @@
1
+ // src/wagmi.ts
2
+ import { useAccount } from "wagmi";
3
+ import { useEffect } from "react";
4
+
5
+ // src/store.ts
6
+ import { create } from "zustand";
7
+ import { persist } from "zustand/middleware";
8
+ var initialState = {
9
+ enabled: false,
10
+ impersonatedAddress: null,
11
+ realAddress: null,
12
+ savedAddresses: []
13
+ };
14
+ var useLensStore = create()(
15
+ persist(
16
+ (set) => ({
17
+ ...initialState,
18
+ setImpersonatedAddress: (address) => set({
19
+ enabled: true,
20
+ impersonatedAddress: address
21
+ }),
22
+ clearImpersonation: () => set({
23
+ enabled: false,
24
+ impersonatedAddress: null
25
+ }),
26
+ setRealAddress: (address) => set({ realAddress: address }),
27
+ saveAddress: (entry) => set((state) => {
28
+ if (state.savedAddresses.some((a) => a.address === entry.address)) {
29
+ return state;
30
+ }
31
+ return {
32
+ savedAddresses: [
33
+ ...state.savedAddresses,
34
+ { ...entry, addedAt: Date.now() }
35
+ ]
36
+ };
37
+ }),
38
+ removeAddress: (address) => set((state) => ({
39
+ savedAddresses: state.savedAddresses.filter((a) => a.address !== address)
40
+ })),
41
+ reset: () => set(initialState)
42
+ }),
43
+ {
44
+ name: "sigil-lens-storage",
45
+ partialize: (state) => ({
46
+ savedAddresses: state.savedAddresses
47
+ })
48
+ }
49
+ )
50
+ );
51
+
52
+ // src/wagmi.ts
53
+ function useLensAwareAccount() {
54
+ const { address: realAddress, isConnected } = useAccount();
55
+ const setRealAddress = useLensStore((state) => state.setRealAddress);
56
+ useEffect(() => {
57
+ setRealAddress(realAddress ?? null);
58
+ }, [realAddress, setRealAddress]);
59
+ const enabled = useLensStore((state) => state.enabled);
60
+ const impersonatedAddress = useLensStore((state) => state.impersonatedAddress);
61
+ const isImpersonating = enabled && impersonatedAddress !== null;
62
+ const address = isImpersonating ? impersonatedAddress : realAddress;
63
+ return {
64
+ address,
65
+ realAddress,
66
+ isImpersonating,
67
+ impersonatedAddress,
68
+ isConnected
69
+ };
70
+ }
71
+ export {
72
+ useLensAwareAccount
73
+ };
74
+ //# sourceMappingURL=wagmi.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/wagmi.ts","../src/store.ts"],"sourcesContent":["/**\n * Lens Wagmi Integration\n *\n * Wagmi-aware hooks for lens functionality.\n */\n\nimport { useAccount } from 'wagmi'\nimport { useEffect } from 'react'\nimport type { Address } from 'viem'\nimport { useLensStore } from './store'\n\n/**\n * Return type for useLensAwareAccount\n */\nexport interface LensAwareAccount {\n /** Address for reads - impersonated if lens enabled, otherwise real */\n address: Address | undefined\n /** The user's real connected address (always available for signing) */\n realAddress: Address | undefined\n /** Whether currently impersonating another address */\n isImpersonating: boolean\n /** The impersonated address (if any) */\n impersonatedAddress: Address | null\n /** Whether the wallet is connected */\n isConnected: boolean\n}\n\n/**\n * Hook that returns impersonated address for reads, real address for writes.\n *\n * Use this hook in place of wagmi's `useAccount` when you want components\n * to display data for an impersonated address while still being able to\n * sign transactions with the real connected wallet.\n *\n * @example\n * ```tsx\n * function WalletInfo() {\n * const { address, realAddress, isImpersonating } = useLensAwareAccount()\n *\n * // Use `address` for reading data (respects impersonation)\n * const { data: balance } = useBalance({ address })\n *\n * // Use `realAddress` for signing transactions\n * const { writeContract } = useWriteContract()\n *\n * return (\n * <div>\n * <p>Viewing: {address}</p>\n * {isImpersonating && <Badge>Lens Active</Badge>}\n * <button onClick={() => writeContract({ ... })}>\n * Sign with {realAddress}\n * </button>\n * </div>\n * )\n * }\n * ```\n */\nexport function useLensAwareAccount(): LensAwareAccount {\n const { address: realAddress, isConnected } = useAccount()\n const setRealAddress = useLensStore((state) => state.setRealAddress)\n\n // Sync real address to lens store\n useEffect(() => {\n setRealAddress(realAddress ?? null)\n }, [realAddress, setRealAddress])\n\n const enabled = useLensStore((state) => state.enabled)\n const impersonatedAddress = useLensStore((state) => state.impersonatedAddress)\n\n const isImpersonating = enabled && impersonatedAddress !== null\n const address = isImpersonating ? impersonatedAddress : realAddress\n\n return {\n address,\n realAddress,\n isImpersonating,\n impersonatedAddress,\n isConnected,\n }\n}\n","/**\n * Lens Store\n *\n * Zustand store for lens state management.\n */\n\nimport { create } from 'zustand'\nimport { persist } from 'zustand/middleware'\nimport type { Address } from 'viem'\nimport type { LensState, SavedAddress } from './types'\n\n/**\n * Lens store actions\n */\ninterface LensActions {\n setImpersonatedAddress: (address: Address) => void\n clearImpersonation: () => void\n setRealAddress: (address: Address | null) => void\n saveAddress: (entry: Omit<SavedAddress, 'addedAt'>) => void\n removeAddress: (address: Address) => void\n reset: () => void\n}\n\n/**\n * Combined lens store type\n */\nexport type LensStore = LensState & LensActions\n\n/**\n * Initial lens state\n */\nconst initialState: LensState = {\n enabled: false,\n impersonatedAddress: null,\n realAddress: null,\n savedAddresses: [],\n}\n\n/**\n * Create the lens store\n */\nexport const useLensStore = create<LensStore>()(\n persist(\n (set) => ({\n ...initialState,\n\n setImpersonatedAddress: (address: Address) =>\n set({\n enabled: true,\n impersonatedAddress: address,\n }),\n\n clearImpersonation: () =>\n set({\n enabled: false,\n impersonatedAddress: null,\n }),\n\n setRealAddress: (address: Address | null) =>\n set({ realAddress: address }),\n\n saveAddress: (entry: Omit<SavedAddress, 'addedAt'>) =>\n set((state) => {\n // Don't add duplicates\n if (state.savedAddresses.some((a) => a.address === entry.address)) {\n return state\n }\n return {\n savedAddresses: [\n ...state.savedAddresses,\n { ...entry, addedAt: Date.now() },\n ],\n }\n }),\n\n removeAddress: (address: Address) =>\n set((state) => ({\n savedAddresses: state.savedAddresses.filter((a) => a.address !== address),\n })),\n\n reset: () => set(initialState),\n }),\n {\n name: 'sigil-lens-storage',\n partialize: (state) => ({\n savedAddresses: state.savedAddresses,\n }),\n }\n )\n)\n\n/**\n * Get lens store state (for non-React contexts)\n */\nexport function getLensState(): LensState {\n const state = useLensStore.getState()\n return {\n enabled: state.enabled,\n impersonatedAddress: state.impersonatedAddress,\n realAddress: state.realAddress,\n savedAddresses: state.savedAddresses,\n }\n}\n"],"mappings":";AAMA,SAAS,kBAAkB;AAC3B,SAAS,iBAAiB;;;ACD1B,SAAS,cAAc;AACvB,SAAS,eAAe;AAwBxB,IAAM,eAA0B;AAAA,EAC9B,SAAS;AAAA,EACT,qBAAqB;AAAA,EACrB,aAAa;AAAA,EACb,gBAAgB,CAAC;AACnB;AAKO,IAAM,eAAe,OAAkB;AAAA,EAC5C;AAAA,IACE,CAAC,SAAS;AAAA,MACR,GAAG;AAAA,MAEH,wBAAwB,CAAC,YACvB,IAAI;AAAA,QACF,SAAS;AAAA,QACT,qBAAqB;AAAA,MACvB,CAAC;AAAA,MAEH,oBAAoB,MAClB,IAAI;AAAA,QACF,SAAS;AAAA,QACT,qBAAqB;AAAA,MACvB,CAAC;AAAA,MAEH,gBAAgB,CAAC,YACf,IAAI,EAAE,aAAa,QAAQ,CAAC;AAAA,MAE9B,aAAa,CAAC,UACZ,IAAI,CAAC,UAAU;AAEb,YAAI,MAAM,eAAe,KAAK,CAAC,MAAM,EAAE,YAAY,MAAM,OAAO,GAAG;AACjE,iBAAO;AAAA,QACT;AACA,eAAO;AAAA,UACL,gBAAgB;AAAA,YACd,GAAG,MAAM;AAAA,YACT,EAAE,GAAG,OAAO,SAAS,KAAK,IAAI,EAAE;AAAA,UAClC;AAAA,QACF;AAAA,MACF,CAAC;AAAA,MAEH,eAAe,CAAC,YACd,IAAI,CAAC,WAAW;AAAA,QACd,gBAAgB,MAAM,eAAe,OAAO,CAAC,MAAM,EAAE,YAAY,OAAO;AAAA,MAC1E,EAAE;AAAA,MAEJ,OAAO,MAAM,IAAI,YAAY;AAAA,IAC/B;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,YAAY,CAAC,WAAW;AAAA,QACtB,gBAAgB,MAAM;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AACF;;;ADhCO,SAAS,sBAAwC;AACtD,QAAM,EAAE,SAAS,aAAa,YAAY,IAAI,WAAW;AACzD,QAAM,iBAAiB,aAAa,CAAC,UAAU,MAAM,cAAc;AAGnE,YAAU,MAAM;AACd,mBAAe,eAAe,IAAI;AAAA,EACpC,GAAG,CAAC,aAAa,cAAc,CAAC;AAEhC,QAAM,UAAU,aAAa,CAAC,UAAU,MAAM,OAAO;AACrD,QAAM,sBAAsB,aAAa,CAAC,UAAU,MAAM,mBAAmB;AAE7E,QAAM,kBAAkB,WAAW,wBAAwB;AAC3D,QAAM,UAAU,kBAAkB,sBAAsB;AAExD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
package/package.json ADDED
@@ -0,0 +1,78 @@
1
+ {
2
+ "name": "@thehoneyjar/sigil-lens",
3
+ "version": "0.1.0",
4
+ "description": "Address impersonation for testing different user states",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": "./dist/index.js",
12
+ "types": "./dist/index.d.ts"
13
+ },
14
+ "./wagmi": {
15
+ "import": "./dist/wagmi.js",
16
+ "types": "./dist/wagmi.d.ts"
17
+ }
18
+ },
19
+ "files": [
20
+ "dist"
21
+ ],
22
+ "peerDependencies": {
23
+ "react": "^18.0.0",
24
+ "viem": "^2.0.0",
25
+ "wagmi": "^2.0.0"
26
+ },
27
+ "peerDependenciesMeta": {
28
+ "wagmi": {
29
+ "optional": true
30
+ }
31
+ },
32
+ "dependencies": {
33
+ "zustand": "^4.4.7"
34
+ },
35
+ "devDependencies": {
36
+ "@types/node": "^20.11.0",
37
+ "@types/react": "^18.2.45",
38
+ "react": "^18.2.0",
39
+ "tsup": "^8.0.1",
40
+ "typescript": "^5.3.3",
41
+ "viem": "^2.0.0",
42
+ "vitest": "^1.2.0",
43
+ "wagmi": "^2.0.0"
44
+ },
45
+ "keywords": [
46
+ "sigil",
47
+ "lens",
48
+ "impersonation",
49
+ "web3",
50
+ "testing"
51
+ ],
52
+ "author": "Sigil Framework",
53
+ "license": "MIT",
54
+ "publishConfig": {
55
+ "access": "public",
56
+ "registry": "https://registry.npmjs.org/"
57
+ },
58
+ "repository": {
59
+ "type": "git",
60
+ "url": "https://github.com/0xHoneyJar/sigil.git",
61
+ "directory": "packages/lens"
62
+ },
63
+ "bugs": {
64
+ "url": "https://github.com/0xHoneyJar/sigil/issues"
65
+ },
66
+ "homepage": "https://github.com/0xHoneyJar/sigil/tree/main/packages/lens#readme",
67
+ "engines": {
68
+ "node": ">=20.0.0"
69
+ },
70
+ "scripts": {
71
+ "build": "tsup",
72
+ "dev": "tsup --watch",
73
+ "test": "vitest",
74
+ "test:run": "vitest run",
75
+ "typecheck": "tsc --noEmit",
76
+ "lint": "eslint src --ext .ts,.tsx"
77
+ }
78
+ }