@aromedia/contracts-sdk 0.2.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.
Files changed (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +121 -0
  3. package/dist/chains.cjs +67 -0
  4. package/dist/chains.cjs.map +1 -0
  5. package/dist/chains.d.cts +826 -0
  6. package/dist/chains.d.ts +826 -0
  7. package/dist/chains.js +23 -0
  8. package/dist/chains.js.map +1 -0
  9. package/dist/chunk-7I5N3BGV.js +271 -0
  10. package/dist/chunk-7I5N3BGV.js.map +1 -0
  11. package/dist/chunk-BYPGUFYV.js +50 -0
  12. package/dist/chunk-BYPGUFYV.js.map +1 -0
  13. package/dist/chunk-FWZ7XKFC.js +91 -0
  14. package/dist/chunk-FWZ7XKFC.js.map +1 -0
  15. package/dist/chunk-J6YVU3VA.js +35 -0
  16. package/dist/chunk-J6YVU3VA.js.map +1 -0
  17. package/dist/chunk-TZQHQLNY.js +7213 -0
  18. package/dist/chunk-TZQHQLNY.js.map +1 -0
  19. package/dist/generated/abis.cjs +7244 -0
  20. package/dist/generated/abis.cjs.map +1 -0
  21. package/dist/generated/abis.d.cts +11005 -0
  22. package/dist/generated/abis.d.ts +11005 -0
  23. package/dist/generated/abis.js +21 -0
  24. package/dist/generated/abis.js.map +1 -0
  25. package/dist/generated/addresses.cjs +119 -0
  26. package/dist/generated/addresses.cjs.map +1 -0
  27. package/dist/generated/addresses.d.cts +18 -0
  28. package/dist/generated/addresses.d.ts +18 -0
  29. package/dist/generated/addresses.js +15 -0
  30. package/dist/generated/addresses.js.map +1 -0
  31. package/dist/hooks/index.cjs +2005 -0
  32. package/dist/hooks/index.cjs.map +1 -0
  33. package/dist/hooks/index.d.cts +63 -0
  34. package/dist/hooks/index.d.ts +63 -0
  35. package/dist/hooks/index.js +218 -0
  36. package/dist/hooks/index.js.map +1 -0
  37. package/dist/index.cjs +7884 -0
  38. package/dist/index.cjs.map +1 -0
  39. package/dist/index.d.cts +42 -0
  40. package/dist/index.d.ts +42 -0
  41. package/dist/index.js +258 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/onboarding-BHpAJaNW.d.cts +302 -0
  44. package/dist/onboarding-DxL_LpM3.d.ts +302 -0
  45. package/dist/workflows/index.cjs +1988 -0
  46. package/dist/workflows/index.cjs.map +1 -0
  47. package/dist/workflows/index.d.cts +72 -0
  48. package/dist/workflows/index.d.ts +72 -0
  49. package/dist/workflows/index.js +25 -0
  50. package/dist/workflows/index.js.map +1 -0
  51. package/package.json +120 -0
@@ -0,0 +1,63 @@
1
+ import { addresses, AroChainId } from '../generated/addresses.cjs';
2
+ import * as wagmi from 'wagmi';
3
+ import { UseReadContractParameters } from 'wagmi';
4
+ import * as abitype from 'abitype';
5
+ import { O as OnboardingState } from '../onboarding-BHpAJaNW.cjs';
6
+ import '../generated/abis.cjs';
7
+ import 'viem';
8
+
9
+ /**
10
+ * Returns the deployed contract addresses for the chain the user is
11
+ * currently connected to. Returns `null` for chains the SDK does not
12
+ * recognize so the dapp can render a "switch network" prompt.
13
+ */
14
+ declare function useAroAddresses(): Record<keyof typeof addresses[AroChainId], `0x${string}`> | null;
15
+ declare function useAroChainId(): AroChainId | null;
16
+
17
+ /**
18
+ * Read whether an address holds an SBT. Returns `undefined` while loading
19
+ * and `false` if the address has been confirmed as a non-member.
20
+ */
21
+ declare function useHasSBT(account: `0x${string}` | undefined, opts?: Partial<UseReadContractParameters>): wagmi.UseReadContractReturnType<readonly unknown[] | abitype.Abi, string, readonly unknown[], unknown>;
22
+ /**
23
+ * Decoded MemberData for an address. Throws on-chain if the address has
24
+ * no SBT, so the dapp should only call this after `useHasSBT` returns true.
25
+ */
26
+ declare function useMemberData(account: `0x${string}` | undefined, opts?: Partial<UseReadContractParameters>): wagmi.UseReadContractReturnType<readonly unknown[] | abitype.Abi, string, readonly unknown[], unknown>;
27
+ /**
28
+ * Admin write hook for minting an SBT. The contract gates this behind
29
+ * ROLE_MINTER, so the caller's wallet must be a holder of that role —
30
+ * the dapp's UI should hide this control for non-admin users.
31
+ */
32
+ declare function useMintSBT(): wagmi.UseWriteContractReturnType<wagmi.Config, unknown>;
33
+
34
+ /**
35
+ * Read the full nomination record for a candidate.
36
+ */
37
+ declare function useNomination(candidate: `0x${string}` | undefined, opts?: Partial<UseReadContractParameters>): wagmi.UseReadContractReturnType<readonly unknown[] | abitype.Abi, string, readonly unknown[], unknown>;
38
+ /**
39
+ * Convenience read: just the status enum, when the dapp only needs to
40
+ * branch on PENDING / APPROVED / CLEARED.
41
+ */
42
+ declare function useNominationStatus(candidate: `0x${string}` | undefined, opts?: Partial<UseReadContractParameters>): wagmi.UseReadContractReturnType<readonly unknown[] | abitype.Abi, string, readonly unknown[], unknown>;
43
+ /** Current vouch threshold (typically 3 per KYC Policy §6.3). */
44
+ declare function useNominationThreshold(opts?: Partial<UseReadContractParameters>): wagmi.UseReadContractReturnType<readonly unknown[] | abitype.Abi, string, readonly unknown[], unknown>;
45
+ /** Whether `voucher` has already vouched for `candidate`. */
46
+ declare function useHasVouched(voucher: `0x${string}` | undefined, candidate: `0x${string}` | undefined, opts?: Partial<UseReadContractParameters>): wagmi.UseReadContractReturnType<readonly unknown[] | abitype.Abi, string, readonly unknown[], unknown>;
47
+ /** Write hook returning `writeContractAsync` for nominate/vouch/clear. */
48
+ declare function useNominationWriter(): wagmi.UseWriteContractReturnType<wagmi.Config, unknown>;
49
+
50
+ /**
51
+ * The hook the access-gate page reaches for. Batches the three reads it
52
+ * needs (hasSBT, nomination, threshold) into a single multicall and
53
+ * returns a derived OnboardingState matching `describeOnboardingState`
54
+ * from the workflows module — but reactive instead of a one-shot read.
55
+ */
56
+ declare function useMembership(wallet: `0x${string}` | undefined): {
57
+ data?: OnboardingState;
58
+ isLoading: boolean;
59
+ isError: boolean;
60
+ refetch: () => void;
61
+ };
62
+
63
+ export { useAroAddresses, useAroChainId, useHasSBT, useHasVouched, useMemberData, useMembership, useMintSBT, useNomination, useNominationStatus, useNominationThreshold, useNominationWriter };
@@ -0,0 +1,63 @@
1
+ import { addresses, AroChainId } from '../generated/addresses.js';
2
+ import * as wagmi from 'wagmi';
3
+ import { UseReadContractParameters } from 'wagmi';
4
+ import * as abitype from 'abitype';
5
+ import { O as OnboardingState } from '../onboarding-DxL_LpM3.js';
6
+ import '../generated/abis.js';
7
+ import 'viem';
8
+
9
+ /**
10
+ * Returns the deployed contract addresses for the chain the user is
11
+ * currently connected to. Returns `null` for chains the SDK does not
12
+ * recognize so the dapp can render a "switch network" prompt.
13
+ */
14
+ declare function useAroAddresses(): Record<keyof typeof addresses[AroChainId], `0x${string}`> | null;
15
+ declare function useAroChainId(): AroChainId | null;
16
+
17
+ /**
18
+ * Read whether an address holds an SBT. Returns `undefined` while loading
19
+ * and `false` if the address has been confirmed as a non-member.
20
+ */
21
+ declare function useHasSBT(account: `0x${string}` | undefined, opts?: Partial<UseReadContractParameters>): wagmi.UseReadContractReturnType<readonly unknown[] | abitype.Abi, string, readonly unknown[], unknown>;
22
+ /**
23
+ * Decoded MemberData for an address. Throws on-chain if the address has
24
+ * no SBT, so the dapp should only call this after `useHasSBT` returns true.
25
+ */
26
+ declare function useMemberData(account: `0x${string}` | undefined, opts?: Partial<UseReadContractParameters>): wagmi.UseReadContractReturnType<readonly unknown[] | abitype.Abi, string, readonly unknown[], unknown>;
27
+ /**
28
+ * Admin write hook for minting an SBT. The contract gates this behind
29
+ * ROLE_MINTER, so the caller's wallet must be a holder of that role —
30
+ * the dapp's UI should hide this control for non-admin users.
31
+ */
32
+ declare function useMintSBT(): wagmi.UseWriteContractReturnType<wagmi.Config, unknown>;
33
+
34
+ /**
35
+ * Read the full nomination record for a candidate.
36
+ */
37
+ declare function useNomination(candidate: `0x${string}` | undefined, opts?: Partial<UseReadContractParameters>): wagmi.UseReadContractReturnType<readonly unknown[] | abitype.Abi, string, readonly unknown[], unknown>;
38
+ /**
39
+ * Convenience read: just the status enum, when the dapp only needs to
40
+ * branch on PENDING / APPROVED / CLEARED.
41
+ */
42
+ declare function useNominationStatus(candidate: `0x${string}` | undefined, opts?: Partial<UseReadContractParameters>): wagmi.UseReadContractReturnType<readonly unknown[] | abitype.Abi, string, readonly unknown[], unknown>;
43
+ /** Current vouch threshold (typically 3 per KYC Policy §6.3). */
44
+ declare function useNominationThreshold(opts?: Partial<UseReadContractParameters>): wagmi.UseReadContractReturnType<readonly unknown[] | abitype.Abi, string, readonly unknown[], unknown>;
45
+ /** Whether `voucher` has already vouched for `candidate`. */
46
+ declare function useHasVouched(voucher: `0x${string}` | undefined, candidate: `0x${string}` | undefined, opts?: Partial<UseReadContractParameters>): wagmi.UseReadContractReturnType<readonly unknown[] | abitype.Abi, string, readonly unknown[], unknown>;
47
+ /** Write hook returning `writeContractAsync` for nominate/vouch/clear. */
48
+ declare function useNominationWriter(): wagmi.UseWriteContractReturnType<wagmi.Config, unknown>;
49
+
50
+ /**
51
+ * The hook the access-gate page reaches for. Batches the three reads it
52
+ * needs (hasSBT, nomination, threshold) into a single multicall and
53
+ * returns a derived OnboardingState matching `describeOnboardingState`
54
+ * from the workflows module — but reactive instead of a one-shot read.
55
+ */
56
+ declare function useMembership(wallet: `0x${string}` | undefined): {
57
+ data?: OnboardingState;
58
+ isLoading: boolean;
59
+ isError: boolean;
60
+ refetch: () => void;
61
+ };
62
+
63
+ export { useAroAddresses, useAroChainId, useHasSBT, useHasVouched, useMemberData, useMembership, useMintSBT, useNomination, useNominationStatus, useNominationThreshold, useNominationWriter };
@@ -0,0 +1,218 @@
1
+ import {
2
+ SUPPORTED_CHAIN_IDS,
3
+ addresses
4
+ } from "../chunk-FWZ7XKFC.js";
5
+ import "../chunk-BYPGUFYV.js";
6
+ import {
7
+ AroNomination_ABI,
8
+ AroSBT_ABI
9
+ } from "../chunk-TZQHQLNY.js";
10
+
11
+ // src/hooks/useAroAddresses.ts
12
+ import { useMemo } from "react";
13
+ import { useChainId } from "wagmi";
14
+ function useAroAddresses() {
15
+ const chainId = useChainId();
16
+ return useMemo(() => {
17
+ if (!isSupportedChain(chainId)) return null;
18
+ return addresses[chainId];
19
+ }, [chainId]);
20
+ }
21
+ function useAroChainId() {
22
+ const chainId = useChainId();
23
+ return isSupportedChain(chainId) ? chainId : null;
24
+ }
25
+ function isSupportedChain(id) {
26
+ return SUPPORTED_CHAIN_IDS.includes(id);
27
+ }
28
+
29
+ // src/hooks/useAroSBT.ts
30
+ import { useReadContract, useWriteContract } from "wagmi";
31
+ function useHasSBT(account, opts = {}) {
32
+ const addrs = useAroAddresses();
33
+ return useReadContract({
34
+ address: addrs?.AroSBT,
35
+ abi: AroSBT_ABI,
36
+ functionName: "hasSBT",
37
+ args: account ? [account] : void 0,
38
+ query: {
39
+ enabled: Boolean(addrs?.AroSBT && account),
40
+ ...opts.query
41
+ },
42
+ ...opts
43
+ });
44
+ }
45
+ function useMemberData(account, opts = {}) {
46
+ const addrs = useAroAddresses();
47
+ return useReadContract({
48
+ address: addrs?.AroSBT,
49
+ abi: AroSBT_ABI,
50
+ functionName: "getMemberData",
51
+ args: account ? [account] : void 0,
52
+ query: {
53
+ enabled: Boolean(addrs?.AroSBT && account),
54
+ ...opts.query
55
+ },
56
+ ...opts
57
+ });
58
+ }
59
+ function useMintSBT() {
60
+ return useWriteContract();
61
+ }
62
+
63
+ // src/hooks/useAroNomination.ts
64
+ import { useReadContract as useReadContract2, useWriteContract as useWriteContract2 } from "wagmi";
65
+ function useNomination(candidate, opts = {}) {
66
+ const addrs = useAroAddresses();
67
+ return useReadContract2({
68
+ address: addrs?.AroNomination,
69
+ abi: AroNomination_ABI,
70
+ functionName: "getNomination",
71
+ args: candidate ? [candidate] : void 0,
72
+ query: {
73
+ enabled: Boolean(addrs?.AroNomination && candidate),
74
+ ...opts.query
75
+ },
76
+ ...opts
77
+ });
78
+ }
79
+ function useNominationStatus(candidate, opts = {}) {
80
+ const addrs = useAroAddresses();
81
+ return useReadContract2({
82
+ address: addrs?.AroNomination,
83
+ abi: AroNomination_ABI,
84
+ functionName: "getNominationStatus",
85
+ args: candidate ? [candidate] : void 0,
86
+ query: {
87
+ enabled: Boolean(addrs?.AroNomination && candidate),
88
+ ...opts.query
89
+ },
90
+ ...opts
91
+ });
92
+ }
93
+ function useNominationThreshold(opts = {}) {
94
+ const addrs = useAroAddresses();
95
+ return useReadContract2({
96
+ address: addrs?.AroNomination,
97
+ abi: AroNomination_ABI,
98
+ functionName: "threshold",
99
+ query: {
100
+ enabled: Boolean(addrs?.AroNomination),
101
+ ...opts.query
102
+ },
103
+ ...opts
104
+ });
105
+ }
106
+ function useHasVouched(voucher, candidate, opts = {}) {
107
+ const addrs = useAroAddresses();
108
+ return useReadContract2({
109
+ address: addrs?.AroNomination,
110
+ abi: AroNomination_ABI,
111
+ functionName: "hasVouched",
112
+ args: voucher && candidate ? [voucher, candidate] : void 0,
113
+ query: {
114
+ enabled: Boolean(addrs?.AroNomination && voucher && candidate),
115
+ ...opts.query
116
+ },
117
+ ...opts
118
+ });
119
+ }
120
+ function useNominationWriter() {
121
+ return useWriteContract2();
122
+ }
123
+
124
+ // src/hooks/useMembership.ts
125
+ import { useMemo as useMemo2 } from "react";
126
+ import { useReadContracts } from "wagmi";
127
+ function useMembership(wallet) {
128
+ const addrs = useAroAddresses();
129
+ const reads = useReadContracts({
130
+ contracts: addrs && wallet ? [
131
+ {
132
+ address: addrs.AroSBT,
133
+ abi: AroSBT_ABI,
134
+ functionName: "hasSBT",
135
+ args: [wallet]
136
+ },
137
+ {
138
+ address: addrs.AroNomination,
139
+ abi: AroNomination_ABI,
140
+ functionName: "getNomination",
141
+ args: [wallet]
142
+ },
143
+ {
144
+ address: addrs.AroNomination,
145
+ abi: AroNomination_ABI,
146
+ functionName: "threshold"
147
+ },
148
+ {
149
+ address: addrs.AroSBT,
150
+ abi: AroSBT_ABI,
151
+ functionName: "getMemberData",
152
+ args: [wallet]
153
+ }
154
+ ] : [],
155
+ query: { enabled: Boolean(addrs && wallet) }
156
+ });
157
+ const data = useMemo2(() => {
158
+ if (!wallet) return { step: "needs-wallet", membership: { hasSBT: false } };
159
+ if (!reads.data) return void 0;
160
+ const [hasSBTResult, nomResult, thresholdResult, memberDataResult] = reads.data;
161
+ const hasSBT = hasSBTResult?.result ?? false;
162
+ if (hasSBT) {
163
+ const md = memberDataResult?.result;
164
+ return {
165
+ step: "member",
166
+ membership: {
167
+ hasSBT: true,
168
+ tier: md?.tier,
169
+ memberId: md?.memberId,
170
+ issuanceDate: md?.issuanceDate,
171
+ kycHash: md?.kycHash
172
+ }
173
+ };
174
+ }
175
+ const nomTuple = nomResult?.result;
176
+ const threshold = thresholdResult?.result;
177
+ if (!nomTuple || threshold === void 0) {
178
+ return { step: "needs-nomination", membership: { hasSBT: false } };
179
+ }
180
+ const [nominator, vouchers, nominatedAt, status] = nomTuple;
181
+ const thresholdN = Number(threshold);
182
+ const voucherCount = vouchers.length;
183
+ const snapshot = {
184
+ status,
185
+ nominator,
186
+ vouchers,
187
+ nominatedAt,
188
+ voucherCount,
189
+ threshold: thresholdN,
190
+ remaining: Math.max(0, thresholdN - voucherCount),
191
+ ready: status === 2 /* APPROVED */
192
+ };
193
+ let step = "needs-nomination";
194
+ if (snapshot.status === 1 /* PENDING */) step = "needs-vouches";
195
+ else if (snapshot.status === 2 /* APPROVED */) step = "needs-kyc";
196
+ return { step, membership: { hasSBT: false }, nomination: snapshot };
197
+ }, [reads.data, wallet]);
198
+ return {
199
+ data,
200
+ isLoading: reads.isLoading,
201
+ isError: reads.isError,
202
+ refetch: reads.refetch
203
+ };
204
+ }
205
+ export {
206
+ useAroAddresses,
207
+ useAroChainId,
208
+ useHasSBT,
209
+ useHasVouched,
210
+ useMemberData,
211
+ useMembership,
212
+ useMintSBT,
213
+ useNomination,
214
+ useNominationStatus,
215
+ useNominationThreshold,
216
+ useNominationWriter
217
+ };
218
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/hooks/useAroAddresses.ts","../../src/hooks/useAroSBT.ts","../../src/hooks/useAroNomination.ts","../../src/hooks/useMembership.ts"],"sourcesContent":["import { useMemo } from \"react\";\nimport { useChainId } from \"wagmi\";\n\nimport { addresses, SUPPORTED_CHAIN_IDS, type AroChainId } from \"../generated/addresses.js\";\n\n/**\n * Returns the deployed contract addresses for the chain the user is\n * currently connected to. Returns `null` for chains the SDK does not\n * recognize so the dapp can render a \"switch network\" prompt.\n */\nexport function useAroAddresses(): Record<keyof typeof addresses[AroChainId], `0x${string}`> | null {\n const chainId = useChainId();\n return useMemo(() => {\n if (!isSupportedChain(chainId)) return null;\n return addresses[chainId];\n }, [chainId]);\n}\n\nexport function useAroChainId(): AroChainId | null {\n const chainId = useChainId();\n return isSupportedChain(chainId) ? chainId : null;\n}\n\nfunction isSupportedChain(id: number): id is AroChainId {\n return (SUPPORTED_CHAIN_IDS as readonly number[]).includes(id);\n}\n","import { useReadContract, useWriteContract, type UseReadContractParameters } from \"wagmi\";\n\nimport { AroSBT_ABI } from \"../generated/abis.js\";\nimport { useAroAddresses } from \"./useAroAddresses.js\";\n\n/**\n * Read whether an address holds an SBT. Returns `undefined` while loading\n * and `false` if the address has been confirmed as a non-member.\n */\nexport function useHasSBT(\n account: `0x${string}` | undefined,\n opts: Partial<UseReadContractParameters> = {},\n) {\n const addrs = useAroAddresses();\n return useReadContract({\n address: addrs?.AroSBT,\n abi: AroSBT_ABI,\n functionName: \"hasSBT\",\n args: account ? [account] : undefined,\n query: {\n enabled: Boolean(addrs?.AroSBT && account),\n ...((opts as { query?: unknown }).query as object | undefined),\n },\n ...opts,\n } as UseReadContractParameters);\n}\n\n/**\n * Decoded MemberData for an address. Throws on-chain if the address has\n * no SBT, so the dapp should only call this after `useHasSBT` returns true.\n */\nexport function useMemberData(\n account: `0x${string}` | undefined,\n opts: Partial<UseReadContractParameters> = {},\n) {\n const addrs = useAroAddresses();\n return useReadContract({\n address: addrs?.AroSBT,\n abi: AroSBT_ABI,\n functionName: \"getMemberData\",\n args: account ? [account] : undefined,\n query: {\n enabled: Boolean(addrs?.AroSBT && account),\n ...((opts as { query?: unknown }).query as object | undefined),\n },\n ...opts,\n } as UseReadContractParameters);\n}\n\n/**\n * Admin write hook for minting an SBT. The contract gates this behind\n * ROLE_MINTER, so the caller's wallet must be a holder of that role —\n * the dapp's UI should hide this control for non-admin users.\n */\nexport function useMintSBT() {\n return useWriteContract();\n}\n","import { useReadContract, useWriteContract, type UseReadContractParameters } from \"wagmi\";\n\nimport { AroNomination_ABI } from \"../generated/abis.js\";\nimport { useAroAddresses } from \"./useAroAddresses.js\";\n\n/**\n * Read the full nomination record for a candidate.\n */\nexport function useNomination(\n candidate: `0x${string}` | undefined,\n opts: Partial<UseReadContractParameters> = {},\n) {\n const addrs = useAroAddresses();\n return useReadContract({\n address: addrs?.AroNomination,\n abi: AroNomination_ABI,\n functionName: \"getNomination\",\n args: candidate ? [candidate] : undefined,\n query: {\n enabled: Boolean(addrs?.AroNomination && candidate),\n ...((opts as { query?: unknown }).query as object | undefined),\n },\n ...opts,\n } as UseReadContractParameters);\n}\n\n/**\n * Convenience read: just the status enum, when the dapp only needs to\n * branch on PENDING / APPROVED / CLEARED.\n */\nexport function useNominationStatus(\n candidate: `0x${string}` | undefined,\n opts: Partial<UseReadContractParameters> = {},\n) {\n const addrs = useAroAddresses();\n return useReadContract({\n address: addrs?.AroNomination,\n abi: AroNomination_ABI,\n functionName: \"getNominationStatus\",\n args: candidate ? [candidate] : undefined,\n query: {\n enabled: Boolean(addrs?.AroNomination && candidate),\n ...((opts as { query?: unknown }).query as object | undefined),\n },\n ...opts,\n } as UseReadContractParameters);\n}\n\n/** Current vouch threshold (typically 3 per KYC Policy §6.3). */\nexport function useNominationThreshold(opts: Partial<UseReadContractParameters> = {}) {\n const addrs = useAroAddresses();\n return useReadContract({\n address: addrs?.AroNomination,\n abi: AroNomination_ABI,\n functionName: \"threshold\",\n query: {\n enabled: Boolean(addrs?.AroNomination),\n ...((opts as { query?: unknown }).query as object | undefined),\n },\n ...opts,\n } as UseReadContractParameters);\n}\n\n/** Whether `voucher` has already vouched for `candidate`. */\nexport function useHasVouched(\n voucher: `0x${string}` | undefined,\n candidate: `0x${string}` | undefined,\n opts: Partial<UseReadContractParameters> = {},\n) {\n const addrs = useAroAddresses();\n return useReadContract({\n address: addrs?.AroNomination,\n abi: AroNomination_ABI,\n functionName: \"hasVouched\",\n args: voucher && candidate ? [voucher, candidate] : undefined,\n query: {\n enabled: Boolean(addrs?.AroNomination && voucher && candidate),\n ...((opts as { query?: unknown }).query as object | undefined),\n },\n ...opts,\n } as UseReadContractParameters);\n}\n\n/** Write hook returning `writeContractAsync` for nominate/vouch/clear. */\nexport function useNominationWriter() {\n return useWriteContract();\n}\n","import { useMemo } from \"react\";\nimport { useReadContracts } from \"wagmi\";\n\nimport { AroNomination_ABI } from \"../generated/abis.js\";\nimport { AroSBT_ABI } from \"../generated/abis.js\";\nimport { AroTier, NominationStatus } from \"../generated/types.js\";\nimport type { OnboardingState, OnboardingStep } from \"../workflows/onboarding.js\";\nimport { useAroAddresses } from \"./useAroAddresses.js\";\n\n/**\n * The hook the access-gate page reaches for. Batches the three reads it\n * needs (hasSBT, nomination, threshold) into a single multicall and\n * returns a derived OnboardingState matching `describeOnboardingState`\n * from the workflows module — but reactive instead of a one-shot read.\n */\nexport function useMembership(wallet: `0x${string}` | undefined): {\n data?: OnboardingState;\n isLoading: boolean;\n isError: boolean;\n refetch: () => void;\n} {\n const addrs = useAroAddresses();\n\n const reads = useReadContracts({\n contracts:\n addrs && wallet\n ? [\n {\n address: addrs.AroSBT,\n abi: AroSBT_ABI,\n functionName: \"hasSBT\",\n args: [wallet],\n },\n {\n address: addrs.AroNomination,\n abi: AroNomination_ABI,\n functionName: \"getNomination\",\n args: [wallet],\n },\n {\n address: addrs.AroNomination,\n abi: AroNomination_ABI,\n functionName: \"threshold\",\n },\n {\n address: addrs.AroSBT,\n abi: AroSBT_ABI,\n functionName: \"getMemberData\",\n args: [wallet],\n },\n ]\n : [],\n query: { enabled: Boolean(addrs && wallet) },\n });\n\n const data = useMemo<OnboardingState | undefined>(() => {\n if (!wallet) return { step: \"needs-wallet\", membership: { hasSBT: false } };\n if (!reads.data) return undefined;\n\n const [hasSBTResult, nomResult, thresholdResult, memberDataResult] = reads.data;\n const hasSBT = (hasSBTResult?.result as boolean) ?? false;\n\n if (hasSBT) {\n const md = memberDataResult?.result as\n | {\n memberId: bigint;\n issuanceDate: bigint;\n tier: number;\n kycHash: `0x${string}`;\n }\n | undefined;\n return {\n step: \"member\" as OnboardingStep,\n membership: {\n hasSBT: true,\n tier: md?.tier as AroTier | undefined,\n memberId: md?.memberId,\n issuanceDate: md?.issuanceDate,\n kycHash: md?.kycHash,\n },\n };\n }\n\n const nomTuple = nomResult?.result as\n | [`0x${string}`, readonly `0x${string}`[], bigint, number]\n | undefined;\n const threshold = thresholdResult?.result as bigint | undefined;\n\n if (!nomTuple || threshold === undefined) {\n return { step: \"needs-nomination\", membership: { hasSBT: false } };\n }\n\n const [nominator, vouchers, nominatedAt, status] = nomTuple;\n const thresholdN = Number(threshold);\n const voucherCount = vouchers.length;\n const snapshot = {\n status: status as NominationStatus,\n nominator,\n vouchers,\n nominatedAt,\n voucherCount,\n threshold: thresholdN,\n remaining: Math.max(0, thresholdN - voucherCount),\n ready: status === NominationStatus.APPROVED,\n };\n\n let step: OnboardingStep = \"needs-nomination\";\n if (snapshot.status === NominationStatus.PENDING) step = \"needs-vouches\";\n else if (snapshot.status === NominationStatus.APPROVED) step = \"needs-kyc\";\n\n return { step, membership: { hasSBT: false }, nomination: snapshot };\n }, [reads.data, wallet]);\n\n return {\n data,\n isLoading: reads.isLoading,\n isError: reads.isError,\n refetch: reads.refetch,\n };\n}\n"],"mappings":"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","names":["useReadContract","useWriteContract","useReadContract","useWriteContract","useMemo","useMemo"]}