@bananapus/nana-sdk-react 1.0.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 (98) hide show
  1. package/README.md +45 -0
  2. package/dist/components/NativeTokenValue.d.ts +13 -0
  3. package/dist/components/NativeTokenValue.d.ts.map +1 -0
  4. package/dist/contexts/JBChainContext/JBChainContext.d.ts +22 -0
  5. package/dist/contexts/JBChainContext/JBChainContext.d.ts.map +1 -0
  6. package/dist/contexts/JBContractContext/JBContractContext.d.ts +54 -0
  7. package/dist/contexts/JBContractContext/JBContractContext.d.ts.map +1 -0
  8. package/dist/contexts/JBDataHookContext/JBCurrentDataHookProvider.d.ts +9 -0
  9. package/dist/contexts/JBDataHookContext/JBCurrentDataHookProvider.d.ts.map +1 -0
  10. package/dist/contexts/JBDataHookContext/JBDataHookContext.d.ts +29 -0
  11. package/dist/contexts/JBDataHookContext/JBDataHookContext.d.ts.map +1 -0
  12. package/dist/contexts/JBProjectMetadataContext/JBProjectMetadataContext.d.ts +25 -0
  13. package/dist/contexts/JBProjectMetadataContext/JBProjectMetadataContext.d.ts.map +1 -0
  14. package/dist/contexts/JBProjectProvider/JBProjectProvider.d.ts +37 -0
  15. package/dist/contexts/JBProjectProvider/JBProjectProvider.d.ts.map +1 -0
  16. package/dist/contexts/JBRulesetContext/JBRulesetContext.d.ts +64 -0
  17. package/dist/contexts/JBRulesetContext/JBRulesetContext.d.ts.map +1 -0
  18. package/dist/contexts/JBTerminalContext/JBPrimaryNativeTerminalProvider.d.ts +9 -0
  19. package/dist/contexts/JBTerminalContext/JBPrimaryNativeTerminalProvider.d.ts.map +1 -0
  20. package/dist/contexts/JBTerminalContext/JBTerminalContext.d.ts +26 -0
  21. package/dist/contexts/JBTerminalContext/JBTerminalContext.d.ts.map +1 -0
  22. package/dist/contexts/JBTokenContext/JBTokenContext.d.ts +32 -0
  23. package/dist/contexts/JBTokenContext/JBTokenContext.d.ts.map +1 -0
  24. package/dist/contexts/types.d.ts +8 -0
  25. package/dist/contexts/types.d.ts.map +1 -0
  26. package/dist/generated/fragment-masking.d.ts +20 -0
  27. package/dist/generated/fragment-masking.d.ts.map +1 -0
  28. package/dist/generated/gql.d.ts +37 -0
  29. package/dist/generated/gql.d.ts.map +1 -0
  30. package/dist/generated/graphql.d.ts +6216 -0
  31. package/dist/generated/graphql.d.ts.map +1 -0
  32. package/dist/generated/index.d.ts +3 -0
  33. package/dist/generated/index.d.ts.map +1 -0
  34. package/dist/hooks/index.d.ts +17 -0
  35. package/dist/hooks/index.d.ts.map +1 -0
  36. package/dist/hooks/jb721Hook/helpers.d.ts +9 -0
  37. package/dist/hooks/jb721Hook/helpers.d.ts.map +1 -0
  38. package/dist/hooks/jb721Hook/helpers.test.d.ts +2 -0
  39. package/dist/hooks/jb721Hook/helpers.test.d.ts.map +1 -0
  40. package/dist/hooks/jb721Hook/use721HookMetadataId.d.ts +8 -0
  41. package/dist/hooks/jb721Hook/use721HookMetadataId.d.ts.map +1 -0
  42. package/dist/hooks/jb721Hook/useFind721DataHook.d.ts +5 -0
  43. package/dist/hooks/jb721Hook/useFind721DataHook.d.ts.map +1 -0
  44. package/dist/hooks/ruleset/useJBRuleset.d.ts +861 -0
  45. package/dist/hooks/ruleset/useJBRuleset.d.ts.map +1 -0
  46. package/dist/hooks/ruleset/useJBUpcomingRuleset.d.ts +10 -0
  47. package/dist/hooks/ruleset/useJBUpcomingRuleset.d.ts.map +1 -0
  48. package/dist/hooks/ruleset/useResolveDataHook.d.ts +21 -0
  49. package/dist/hooks/ruleset/useResolveDataHook.d.ts.map +1 -0
  50. package/dist/hooks/suckers/useSuckers.d.ts +189 -0
  51. package/dist/hooks/suckers/useSuckers.d.ts.map +1 -0
  52. package/dist/hooks/token/useNativeTokenSurplus.d.ts +148 -0
  53. package/dist/hooks/token/useNativeTokenSurplus.d.ts.map +1 -0
  54. package/dist/hooks/token/useNativeTokenSymbol.d.ts +8 -0
  55. package/dist/hooks/token/useNativeTokenSymbol.d.ts.map +1 -0
  56. package/dist/hooks/token/useSuckersCashOutQuote.d.ts +10 -0
  57. package/dist/hooks/token/useSuckersCashOutQuote.d.ts.map +1 -0
  58. package/dist/hooks/token/useSuckersNativeTokenBalance.d.ts +13 -0
  59. package/dist/hooks/token/useSuckersNativeTokenBalance.d.ts.map +1 -0
  60. package/dist/hooks/token/useSuckersNativeTokenSurplus.d.ts +14 -0
  61. package/dist/hooks/token/useSuckersNativeTokenSurplus.d.ts.map +1 -0
  62. package/dist/hooks/token/useSuckersTokenCashOutValue.d.ts +15 -0
  63. package/dist/hooks/token/useSuckersTokenCashOutValue.d.ts.map +1 -0
  64. package/dist/hooks/token/useSuckersUserTokenBalance.d.ts +14 -0
  65. package/dist/hooks/token/useSuckersUserTokenBalance.d.ts.map +1 -0
  66. package/dist/hooks/token/useTokenCashOutQuoteEth.d.ts +1890 -0
  67. package/dist/hooks/token/useTokenCashOutQuoteEth.d.ts.map +1 -0
  68. package/dist/hooks/useEtherPrice.d.ts +7 -0
  69. package/dist/hooks/useEtherPrice.d.ts.map +1 -0
  70. package/dist/hooks/useNetwork.d.ts +8 -0
  71. package/dist/hooks/useNetwork.d.ts.map +1 -0
  72. package/dist/hooks/usePreparePayMetadata.d.ts +14 -0
  73. package/dist/hooks/usePreparePayMetadata.d.ts.map +1 -0
  74. package/dist/index.d.ts +15 -0
  75. package/dist/index.d.ts.map +1 -0
  76. package/dist/index.js +1676 -0
  77. package/dist/index.js.map +1 -0
  78. package/dist/lib/bendystraw/getBendystrawUrl.d.ts +6 -0
  79. package/dist/lib/bendystraw/getBendystrawUrl.d.ts.map +1 -0
  80. package/dist/lib/bendystraw/useBendystrawQuery.d.ts +10 -0
  81. package/dist/lib/bendystraw/useBendystrawQuery.d.ts.map +1 -0
  82. package/dist/lib/relayr/constants.d.ts +3 -0
  83. package/dist/lib/relayr/constants.d.ts.map +1 -0
  84. package/dist/lib/relayr/hooks/useGetRelayrTxBundle.d.ts +10 -0
  85. package/dist/lib/relayr/hooks/useGetRelayrTxBundle.d.ts.map +1 -0
  86. package/dist/lib/relayr/hooks/useGetRelayrTxQuote.d.ts +150 -0
  87. package/dist/lib/relayr/hooks/useGetRelayrTxQuote.d.ts.map +1 -0
  88. package/dist/lib/relayr/hooks/useRequestRelayrQuote.d.ts +9 -0
  89. package/dist/lib/relayr/hooks/useRequestRelayrQuote.d.ts.map +1 -0
  90. package/dist/lib/relayr/hooks/useSendRelayrTx.d.ts +12 -0
  91. package/dist/lib/relayr/hooks/useSendRelayrTx.d.ts.map +1 -0
  92. package/dist/lib/relayr/hooks/useSignErc2771ForwardRequest.d.ts +13 -0
  93. package/dist/lib/relayr/hooks/useSignErc2771ForwardRequest.d.ts.map +1 -0
  94. package/dist/lib/relayr/index.d.ts +6 -0
  95. package/dist/lib/relayr/index.d.ts.map +1 -0
  96. package/dist/lib/relayr/types.d.ts +61 -0
  97. package/dist/lib/relayr/types.d.ts.map +1 -0
  98. package/package.json +53 -0
package/dist/index.js ADDED
@@ -0,0 +1,1676 @@
1
+ // src/components/NativeTokenValue.tsx
2
+ import { NATIVE_TOKEN_DECIMALS, formatUnits } from "@bananapus/nana-sdk-core";
3
+
4
+ // src/hooks/token/useNativeTokenSymbol.ts
5
+ import { DEFAULT_NATIVE_TOKEN_SYMBOL, JB_CHAINS } from "@bananapus/nana-sdk-core";
6
+
7
+ // src/contexts/JBChainContext/JBChainContext.tsx
8
+ import { debug } from "@bananapus/nana-sdk-core";
9
+ import { createContext, useContext } from "react";
10
+ import { jsx } from "react/jsx-runtime";
11
+ var JBChainContext = createContext({
12
+ chainId: void 0
13
+ });
14
+ function useJBChainId() {
15
+ const { chainId } = useContext(JBChainContext);
16
+ return chainId;
17
+ }
18
+ var JBChainProvider = ({
19
+ chainId,
20
+ children
21
+ }) => {
22
+ debug("JBChainContext", { chainId });
23
+ return /* @__PURE__ */ jsx(JBChainContext.Provider, { value: { chainId }, children });
24
+ };
25
+
26
+ // src/hooks/token/useNativeTokenSymbol.ts
27
+ function useNativeTokenSymbol(chainId) {
28
+ const _chainId = chainId ?? useJBChainId();
29
+ if (!_chainId) {
30
+ return DEFAULT_NATIVE_TOKEN_SYMBOL;
31
+ }
32
+ return JB_CHAINS[_chainId]?.nativeTokenSymbol ?? DEFAULT_NATIVE_TOKEN_SYMBOL;
33
+ }
34
+
35
+ // src/components/NativeTokenValue.tsx
36
+ import { Fragment, jsxs } from "react/jsx-runtime";
37
+ function NativeTokenValue({ wei, decimals = 4 }) {
38
+ const symbol = useNativeTokenSymbol();
39
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
40
+ formatUnits(wei, NATIVE_TOKEN_DECIMALS, {
41
+ fractionDigits: decimals
42
+ }),
43
+ " ",
44
+ symbol
45
+ ] });
46
+ }
47
+
48
+ // src/contexts/JBContractContext/JBContractContext.tsx
49
+ import {
50
+ NATIVE_TOKEN as NATIVE_TOKEN4,
51
+ debug as debug10,
52
+ USDC_ADDRESSES,
53
+ jbDirectoryAbi,
54
+ jbControllerAbi as jbControllerAbi5,
55
+ jbContractAddress as jbContractAddress2,
56
+ JBCoreContracts as JBCoreContracts3,
57
+ getJBContractAddress as getJBContractAddress2
58
+ } from "@bananapus/nana-sdk-core";
59
+ import { createContext as createContext8, useCallback, useContext as useContext8, useMemo as useMemo3 } from "react";
60
+ import { isAddressEqual as isAddressEqual4, zeroAddress as zeroAddress4 } from "viem";
61
+
62
+ // src/hooks/usePreparePayMetadata.ts
63
+ import { DEFAULT_ALLOW_OVERSPENDING, createHookMetadata } from "@bananapus/nana-sdk-core";
64
+ import { encodeAbiParameters } from "viem";
65
+
66
+ // src/hooks/jb721Hook/helpers.ts
67
+ import { bytesToHex, keccak256, toBytes } from "viem";
68
+ function createMetadataTargetIdPayHash(metadataTargetId, purpose = "pay") {
69
+ const targetBytes = toBytes(metadataTargetId);
70
+ const purposeBytes = toBytes(purpose);
71
+ const targetBytes20 = targetBytes.slice(0, 20);
72
+ const purposeBytes20 = toBytes(keccak256(purposeBytes)).slice(0, 20);
73
+ const xorResult = targetBytes20.map((byte, i) => byte ^ purposeBytes20[i]);
74
+ return bytesToHex(xorResult.slice(0, 4));
75
+ }
76
+
77
+ // src/hooks/jb721Hook/use721HookMetadataId.tsx
78
+ import { jb721TiersHookAbi } from "@bananapus/nana-sdk-core";
79
+ import { useReadContract } from "wagmi";
80
+ function use721HookMetadataId({
81
+ dataHookAddress
82
+ }) {
83
+ const chainId = useJBChainId();
84
+ const { data: hashedMetadataId } = useReadContract({
85
+ abi: jb721TiersHookAbi,
86
+ functionName: "METADATA_ID_TARGET",
87
+ chainId,
88
+ address: dataHookAddress,
89
+ query: {
90
+ enabled: !!dataHookAddress,
91
+ select(metadataTargetId) {
92
+ return createMetadataTargetIdPayHash(metadataTargetId, "pay");
93
+ }
94
+ }
95
+ });
96
+ return hashedMetadataId;
97
+ }
98
+
99
+ // src/hooks/usePreparePayMetadata.ts
100
+ import { debug as debug2 } from "@bananapus/nana-sdk-core";
101
+ function encodeJB721HookPayMetadata(metadata) {
102
+ const args = [
103
+ metadata.allowOverspending ?? DEFAULT_ALLOW_OVERSPENDING,
104
+ metadata.tierIdsToMint.map(Number)
105
+ ];
106
+ const encoded = encodeAbiParameters([{ type: "bool" }, { type: "uint16[]" }], args);
107
+ return encoded;
108
+ }
109
+ function usePreparePayMetadata({
110
+ jb721Hook
111
+ } = {}) {
112
+ const HookIds = [];
113
+ const metadatas = [];
114
+ const metadataId = use721HookMetadataId({
115
+ dataHookAddress: jb721Hook?.dataHookAddress
116
+ });
117
+ debug2("usePreparePayMetadata", { metadataId, jb721Hook });
118
+ if (!jb721Hook || jb721Hook.tierIdsToMint.length == 0 || !metadataId) {
119
+ return null;
120
+ }
121
+ const jb721HookMetadata = encodeJB721HookPayMetadata({
122
+ tierIdsToMint: jb721Hook.tierIdsToMint,
123
+ allowOverspending: DEFAULT_ALLOW_OVERSPENDING
124
+ });
125
+ HookIds.push(metadataId);
126
+ metadatas.push(jb721HookMetadata);
127
+ return createHookMetadata(HookIds, metadatas);
128
+ }
129
+
130
+ // src/hooks/useNetwork.ts
131
+ import { useAccount, useClient } from "wagmi";
132
+ function useChain() {
133
+ const { chain } = useAccount();
134
+ const client = useClient();
135
+ return chain ?? client?.chain;
136
+ }
137
+
138
+ // src/hooks/jb721Hook/useFind721DataHook.tsx
139
+ import { find721DataHook } from "@bananapus/nana-sdk-core";
140
+ import { usePublicClient } from "wagmi";
141
+ import { useQuery } from "wagmi/query";
142
+
143
+ // src/contexts/JBRulesetContext/JBRulesetContext.tsx
144
+ import {
145
+ CashOutTaxRate,
146
+ debug as debug3,
147
+ jbControllerAbi,
148
+ ReservedPercent,
149
+ RulesetWeight,
150
+ WeightCutPercent
151
+ } from "@bananapus/nana-sdk-core";
152
+ import { createContext as createContext2, useContext as useContext2 } from "react";
153
+ import { useReadContract as useReadContract3 } from "wagmi";
154
+
155
+ // src/hooks/ruleset/useResolveDataHook.ts
156
+ import {
157
+ jbContractAddress,
158
+ jbOmnichainDeployer4_1Abi,
159
+ jbOmnichainDeployerAbi,
160
+ jbOmnichainDeployerV5Abi
161
+ } from "@bananapus/nana-sdk-core";
162
+ import { isAddressEqual, zeroAddress } from "viem";
163
+ import { mainnet } from "viem/chains";
164
+ import { useReadContract as useReadContract2 } from "wagmi";
165
+ function useResolveDataHook({
166
+ dataHookAddress,
167
+ projectId,
168
+ chainId,
169
+ rulesetId
170
+ }) {
171
+ const { version } = useJBContractContext();
172
+ const omnichainDeployerAddress = version === 4 ? jbContractAddress[4]["JBOmnichainDeployer4_1"][mainnet.id] : jbContractAddress[version]["JBOmnichainDeployer"][mainnet.id];
173
+ const dataHookIsOmnichainDeployer = Boolean(
174
+ dataHookAddress && isAddressEqual(dataHookAddress, omnichainDeployerAddress)
175
+ );
176
+ const args = projectId && rulesetId ? [projectId, rulesetId] : void 0;
177
+ const legacyDataHookQuery = useReadContract2({
178
+ abi: version === 4 ? jbOmnichainDeployer4_1Abi : jbOmnichainDeployerV5Abi,
179
+ functionName: "dataHookOf",
180
+ address: omnichainDeployerAddress,
181
+ chainId,
182
+ args,
183
+ query: {
184
+ enabled: version !== 6 && !!dataHookIsOmnichainDeployer && !!projectId
185
+ }
186
+ });
187
+ const tiered721HookQuery = useReadContract2({
188
+ abi: jbOmnichainDeployerAbi,
189
+ functionName: "tiered721HookOf",
190
+ address: omnichainDeployerAddress,
191
+ chainId,
192
+ args,
193
+ query: {
194
+ enabled: version === 6 && !!dataHookIsOmnichainDeployer && !!projectId
195
+ }
196
+ });
197
+ const extraDataHookQuery = useReadContract2({
198
+ abi: jbOmnichainDeployerAbi,
199
+ functionName: "extraDataHookOf",
200
+ address: omnichainDeployerAddress,
201
+ chainId,
202
+ args,
203
+ query: {
204
+ enabled: version === 6 && !!dataHookIsOmnichainDeployer && !!projectId
205
+ }
206
+ });
207
+ const isLoading = version === 6 ? tiered721HookQuery.isLoading || extraDataHookQuery.isLoading : legacyDataHookQuery.isLoading;
208
+ const error = version === 6 ? tiered721HookQuery.error ?? extraDataHookQuery.error : legacyDataHookQuery.error;
209
+ if (!dataHookAddress)
210
+ return {
211
+ resolvedDataHook: zeroAddress,
212
+ dataHookIsOmnichainDeployer,
213
+ isLoading,
214
+ error
215
+ };
216
+ let resolvedDataHook = dataHookAddress;
217
+ if (dataHookIsOmnichainDeployer) {
218
+ if (version === 6) {
219
+ const tiered721Hook = tiered721HookQuery.data?.[0];
220
+ const extraDataHook = extraDataHookQuery.data?.dataHook;
221
+ if (tiered721Hook && !isAddressEqual(tiered721Hook, zeroAddress)) {
222
+ resolvedDataHook = tiered721Hook;
223
+ } else if (extraDataHook && !isAddressEqual(extraDataHook, zeroAddress)) {
224
+ resolvedDataHook = extraDataHook;
225
+ }
226
+ } else if (legacyDataHookQuery.data?.[2]) {
227
+ resolvedDataHook = legacyDataHookQuery.data[2];
228
+ }
229
+ }
230
+ return {
231
+ resolvedDataHook,
232
+ dataHookIsOmnichainDeployer,
233
+ isLoading,
234
+ error
235
+ };
236
+ }
237
+
238
+ // src/contexts/types.ts
239
+ var AsyncDataNone = {
240
+ isLoading: false,
241
+ data: void 0
242
+ };
243
+
244
+ // src/contexts/JBRulesetContext/JBRulesetContext.tsx
245
+ import { jsx as jsx2 } from "react/jsx-runtime";
246
+ var JBRulesetContext = createContext2({
247
+ ruleset: AsyncDataNone,
248
+ rulesetMetadata: AsyncDataNone
249
+ });
250
+ function useJBRulesetContext() {
251
+ return useContext2(JBRulesetContext);
252
+ }
253
+ function useJBRulesetMetadata() {
254
+ const { rulesetMetadata } = useJBRulesetContext();
255
+ return rulesetMetadata;
256
+ }
257
+ var JBRulesetProvider = ({ children }) => {
258
+ const { contracts, projectId, version } = useJBContractContext();
259
+ const chainId = useJBChainId();
260
+ const { data: ruleset, isLoading } = useReadContract3({
261
+ chainId,
262
+ abi: jbControllerAbi,
263
+ functionName: "currentRulesetOf",
264
+ address: contracts.controller.data ?? void 0,
265
+ args: [projectId],
266
+ query: {
267
+ select([ruleset2, rulesetMetadata]) {
268
+ return {
269
+ data: {
270
+ ...ruleset2,
271
+ weight: new RulesetWeight(ruleset2.weight),
272
+ weightCutPercent: new WeightCutPercent(ruleset2.weightCutPercent)
273
+ },
274
+ metadata: {
275
+ ...rulesetMetadata,
276
+ cashOutTaxRate: new CashOutTaxRate(rulesetMetadata.cashOutTaxRate),
277
+ reservedPercent: new ReservedPercent(rulesetMetadata.reservedPercent),
278
+ // v4/v5 store the INVERSE flag (`useTotalSurplusForCashOuts`) in this slot;
279
+ // normalize to the v6 field's semantics.
280
+ scopeCashOutsToLocalBalances: version === 6 ? rulesetMetadata.scopeCashOutsToLocalBalances : !rulesetMetadata.scopeCashOutsToLocalBalances
281
+ }
282
+ };
283
+ }
284
+ }
285
+ });
286
+ const { resolvedDataHook } = useResolveDataHook({
287
+ dataHookAddress: ruleset?.metadata?.dataHook,
288
+ projectId,
289
+ chainId,
290
+ rulesetId: BigInt(ruleset?.data.id ?? 0)
291
+ });
292
+ const rulesetMetadataWithResolvedDataHook = ruleset?.metadata && {
293
+ ...ruleset.metadata,
294
+ dataHook: resolvedDataHook
295
+ };
296
+ debug3("JBRulesetContext", {
297
+ ruleset: {
298
+ data: ruleset?.data,
299
+ isLoading
300
+ },
301
+ rulesetMetadata: {
302
+ data: rulesetMetadataWithResolvedDataHook,
303
+ isLoading
304
+ }
305
+ });
306
+ return /* @__PURE__ */ jsx2(
307
+ JBRulesetContext.Provider,
308
+ {
309
+ value: {
310
+ ruleset: {
311
+ data: ruleset?.data,
312
+ isLoading
313
+ },
314
+ rulesetMetadata: {
315
+ data: rulesetMetadataWithResolvedDataHook,
316
+ isLoading
317
+ }
318
+ },
319
+ children
320
+ }
321
+ );
322
+ };
323
+
324
+ // src/contexts/JBDataHookContext/JBDataHookContext.tsx
325
+ import { createContext as createContext3, useContext as useContext3, useMemo } from "react";
326
+ import { debug as debug4 } from "@bananapus/nana-sdk-core";
327
+ import { jsx as jsx3 } from "react/jsx-runtime";
328
+ var JBDataHookContext = createContext3(AsyncDataNone);
329
+ function useJBDataHookContext() {
330
+ return useContext3(JBDataHookContext);
331
+ }
332
+ var JBDataHookProvider = ({
333
+ dataHookAddress,
334
+ children
335
+ }) => {
336
+ const data = useMemo(() => {
337
+ if (!dataHookAddress) {
338
+ return AsyncDataNone;
339
+ }
340
+ return {
341
+ isLoading: false,
342
+ data: {
343
+ dataHookAddress
344
+ }
345
+ };
346
+ }, [dataHookAddress]);
347
+ debug4("JBDataHookContext", data);
348
+ return /* @__PURE__ */ jsx3(JBDataHookContext.Provider, { value: data, children });
349
+ };
350
+
351
+ // src/hooks/jb721Hook/useFind721DataHook.tsx
352
+ import { debug as debug5 } from "@bananapus/nana-sdk-core";
353
+ function useFind721DataHook() {
354
+ const { data } = useJBDataHookContext();
355
+ const { projectId, version } = useJBContractContext();
356
+ const { ruleset } = useJBRulesetContext();
357
+ const publicClient = usePublicClient();
358
+ const rulesetId = ruleset.data?.id;
359
+ const dataHookAddress = data?.dataHookAddress;
360
+ debug5("useFind721DataHook::args", {
361
+ projectId,
362
+ rulesetId,
363
+ dataHookAddress,
364
+ publicClient
365
+ });
366
+ const jb721DataHookQuery = useQuery({
367
+ queryKey: ["dataHook", projectId, rulesetId, dataHookAddress],
368
+ staleTime: Infinity,
369
+ queryFn: async () => {
370
+ if (!rulesetId || !dataHookAddress) return null;
371
+ if (!publicClient) {
372
+ throw new Error("Public client not available.");
373
+ }
374
+ const jb721DataHook = await find721DataHook(publicClient, {
375
+ dataHookAddress,
376
+ projectId,
377
+ rulesetId,
378
+ version
379
+ });
380
+ return jb721DataHook;
381
+ }
382
+ });
383
+ return jb721DataHookQuery;
384
+ }
385
+
386
+ // src/hooks/suckers/useSuckers.ts
387
+ import { debug as debug9 } from "@bananapus/nana-sdk-core";
388
+
389
+ // src/generated/graphql.ts
390
+ var ProjectDocument = { "kind": "Document", "definitions": [{ "kind": "OperationDefinition", "operation": "query", "name": { "kind": "Name", "value": "Project" }, "variableDefinitions": [{ "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "projectId" } }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "Float" } } } }, { "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "chainId" } }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "Float" } } } }, { "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "version" } }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "Float" } } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "project" }, "arguments": [{ "kind": "Argument", "name": { "kind": "Name", "value": "projectId" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "projectId" } } }, { "kind": "Argument", "name": { "kind": "Name", "value": "chainId" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "chainId" } } }, { "kind": "Argument", "name": { "kind": "Name", "value": "version" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "version" } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "projectId" } }, { "kind": "Field", "name": { "kind": "Name", "value": "metadataUri" } }, { "kind": "Field", "name": { "kind": "Name", "value": "handle" } }, { "kind": "Field", "name": { "kind": "Name", "value": "createdAt" } }, { "kind": "Field", "name": { "kind": "Name", "value": "logoUri" } }, { "kind": "Field", "name": { "kind": "Name", "value": "name" } }, { "kind": "Field", "name": { "kind": "Name", "value": "version" } }, { "kind": "Field", "name": { "kind": "Name", "value": "suckerGroupId" } }, { "kind": "Field", "name": { "kind": "Name", "value": "suckerGroup" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "projects" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "items" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "chainId" } }, { "kind": "Field", "name": { "kind": "Name", "value": "balance" } }, { "kind": "Field", "name": { "kind": "Name", "value": "tokenSupply" } }, { "kind": "Field", "name": { "kind": "Name", "value": "projectId" } }] } }] } }] } }] } }] } }] };
391
+
392
+ // src/lib/bendystraw/useBendystrawQuery.ts
393
+ import { useQuery as useQuery3 } from "@tanstack/react-query";
394
+ import request from "graphql-request";
395
+
396
+ // src/lib/bendystraw/getBendystrawUrl.ts
397
+ import { arbitrum, base, mainnet as mainnet2, optimism } from "viem/chains";
398
+ var bendystrawUrl = "https://bendystraw.xyz";
399
+ var testnetBendystrawUrl = "https://testnet.bendystraw.xyz";
400
+ function getBendystrawUrl(chainId, config) {
401
+ const { url, apiKey } = config;
402
+ if (url) return `${url}/${apiKey}`;
403
+ const isMainnet = [mainnet2, base, arbitrum, optimism].some((c) => c.id === chainId);
404
+ return `${isMainnet ? bendystrawUrl : testnetBendystrawUrl}${apiKey !== "" ? `/${apiKey}` : ""}`;
405
+ }
406
+
407
+ // src/contexts/JBProjectProvider/JBProjectProvider.tsx
408
+ import { createContext as createContext7, useContext as useContext7 } from "react";
409
+
410
+ // src/contexts/JBDataHookContext/JBCurrentDataHookProvider.tsx
411
+ import { debug as debug6 } from "@bananapus/nana-sdk-core";
412
+ import { jsx as jsx4 } from "react/jsx-runtime";
413
+ function JBCurrentDataHookProvider({
414
+ children
415
+ }) {
416
+ const { data } = useJBRulesetMetadata();
417
+ const dataHookAddress = data?.dataHook;
418
+ debug6("JBCurrentDataHookContext", { dataHookAddress });
419
+ return /* @__PURE__ */ jsx4(JBDataHookProvider, { dataHookAddress, children });
420
+ }
421
+
422
+ // src/contexts/JBProjectMetadataContext/JBProjectMetadataContext.tsx
423
+ import { debug as debug7, getProjectMetadata } from "@bananapus/nana-sdk-core";
424
+ import { createContext as createContext4, useContext as useContext4 } from "react";
425
+ import { usePublicClient as usePublicClient2 } from "wagmi";
426
+ import { useQuery as useQuery2 } from "wagmi/query";
427
+ import { jsx as jsx5 } from "react/jsx-runtime";
428
+ var JBProjectMetadataContext = createContext4({
429
+ metadata: AsyncDataNone
430
+ });
431
+ function useJBProjectMetadataContext() {
432
+ return useContext4(JBProjectMetadataContext);
433
+ }
434
+ function useProjectMetadata({
435
+ projectId,
436
+ jbControllerAddress,
437
+ ipfsGatewayHostname
438
+ }) {
439
+ const chainId = useJBChainId();
440
+ const publicClient = usePublicClient2({ chainId });
441
+ return useQuery2({
442
+ queryKey: [
443
+ "juice-sdk",
444
+ "useProjectMetadata",
445
+ projectId?.toString(),
446
+ jbControllerAddress,
447
+ ipfsGatewayHostname
448
+ ],
449
+ queryFn: async () => {
450
+ if (!projectId || !jbControllerAddress) return null;
451
+ if (!publicClient) {
452
+ throw new Error("Public client not available.");
453
+ }
454
+ const response = await getProjectMetadata(
455
+ publicClient,
456
+ {
457
+ projectId,
458
+ jbControllerAddress
459
+ },
460
+ {
461
+ ipfsGatewayHostname
462
+ }
463
+ );
464
+ return response ?? null;
465
+ }
466
+ });
467
+ }
468
+ var JBProjectMetadataProvider = ({
469
+ children,
470
+ ipfsGatewayHostname
471
+ }) => {
472
+ const { projectId, contracts } = useJBContractContext();
473
+ const metadata = useProjectMetadata({
474
+ projectId,
475
+ jbControllerAddress: contracts.controller.data ?? void 0,
476
+ ipfsGatewayHostname
477
+ });
478
+ debug7("JBProjectMetadataContext", {
479
+ projectId,
480
+ ipfsGatewayHostname,
481
+ contracts,
482
+ metadata
483
+ });
484
+ return /* @__PURE__ */ jsx5(
485
+ JBProjectMetadataContext.Provider,
486
+ {
487
+ value: { metadata },
488
+ children
489
+ }
490
+ );
491
+ };
492
+
493
+ // src/contexts/JBTokenContext/JBTokenContext.tsx
494
+ import {
495
+ getJBContractAddress,
496
+ jbControllerAbi as jbControllerAbi2,
497
+ JBCoreContracts,
498
+ JBProjectToken,
499
+ jbTokensAbi
500
+ } from "@bananapus/nana-sdk-core";
501
+ import { createContext as createContext5, useContext as useContext5 } from "react";
502
+ import { isAddressEqual as isAddressEqual2, zeroAddress as zeroAddress2 } from "viem";
503
+ import { useReadContract as useReadContract4, useToken } from "wagmi";
504
+ import { jsx as jsx6 } from "react/jsx-runtime";
505
+ var JBTokenContext = createContext5({
506
+ /**
507
+ * The token of the project.
508
+ *
509
+ * @default none {@link AsyncDataNone}
510
+ */
511
+ token: AsyncDataNone,
512
+ /**
513
+ * The total outstanding tokens of the project.
514
+ *
515
+ * @default none {@link AsyncDataNone}
516
+ */
517
+ totalOutstanding: AsyncDataNone
518
+ });
519
+ function useJBTokenContext() {
520
+ return useContext5(JBTokenContext);
521
+ }
522
+ var JBTokenProvider = ({ children, withTotalOutstanding }) => {
523
+ const chainId = useJBChainId();
524
+ const {
525
+ projectId,
526
+ version,
527
+ contracts: { controller }
528
+ } = useJBContractContext();
529
+ const { data: tokenAddress } = useReadContract4({
530
+ address: getJBContractAddress(JBCoreContracts.JBTokens, version, chainId),
531
+ abi: jbTokensAbi,
532
+ functionName: "tokenOf",
533
+ chainId,
534
+ args: [projectId],
535
+ query: { enabled: !!projectId && !!chainId && !!version }
536
+ });
537
+ const fetchTokenEnabled = Boolean(tokenAddress && !isAddressEqual2(tokenAddress, zeroAddress2));
538
+ const token = useToken({
539
+ chainId,
540
+ address: fetchTokenEnabled ? tokenAddress : void 0,
541
+ query: { enabled: fetchTokenEnabled }
542
+ });
543
+ const totalOutstandingRes = useReadContract4({
544
+ abi: jbControllerAbi2,
545
+ functionName: "totalTokenSupplyWithReservedTokensOf",
546
+ chainId,
547
+ address: controller?.data ?? void 0,
548
+ args: withTotalOutstanding ? [projectId] : void 0,
549
+ query: {
550
+ enabled: withTotalOutstanding && controller?.data !== void 0
551
+ }
552
+ });
553
+ const totalOutstandingData = totalOutstandingRes?.data ? new JBProjectToken(totalOutstandingRes?.data) : void 0;
554
+ return /* @__PURE__ */ jsx6(
555
+ JBTokenContext.Provider,
556
+ {
557
+ value: {
558
+ token,
559
+ totalOutstanding: {
560
+ data: totalOutstandingData,
561
+ isLoading: totalOutstandingRes?.isLoading
562
+ }
563
+ },
564
+ children
565
+ }
566
+ );
567
+ };
568
+
569
+ // src/contexts/JBTerminalContext/JBPrimaryNativeTerminalProvider.tsx
570
+ import { debug as debug8 } from "@bananapus/nana-sdk-core";
571
+
572
+ // src/contexts/JBTerminalContext/JBTerminalContext.tsx
573
+ import { jbMultiTerminalAbi } from "@bananapus/nana-sdk-core";
574
+ import { createContext as createContext6, useContext as useContext6 } from "react";
575
+ import { isAddressEqual as isAddressEqual3, zeroAddress as zeroAddress3 } from "viem";
576
+ import { useReadContract as useReadContract5 } from "wagmi";
577
+ import { jsx as jsx7 } from "react/jsx-runtime";
578
+ var JBTerminalContext = createContext6({
579
+ address: void 0,
580
+ accountingContexts: AsyncDataNone,
581
+ store: AsyncDataNone
582
+ });
583
+ function useJBTerminalContext() {
584
+ return useContext6(JBTerminalContext);
585
+ }
586
+ var JBTerminalProvider = ({ address, children }) => {
587
+ const chainId = useJBChainId();
588
+ const { data: store, isLoading: isStoreLoading } = useReadContract5({
589
+ abi: jbMultiTerminalAbi,
590
+ functionName: "STORE",
591
+ chainId,
592
+ address: address && isAddressEqual3(address, zeroAddress3) ? void 0 : address
593
+ });
594
+ const { data: accountingContexts, isLoading: accountingContextsLoading } = useReadContract5({
595
+ abi: jbMultiTerminalAbi,
596
+ functionName: "accountingContextsOf",
597
+ chainId,
598
+ address: address && isAddressEqual3(address, zeroAddress3) ? void 0 : address
599
+ });
600
+ return /* @__PURE__ */ jsx7(
601
+ JBTerminalContext.Provider,
602
+ {
603
+ value: {
604
+ address,
605
+ store: {
606
+ data: store,
607
+ isLoading: isStoreLoading
608
+ },
609
+ accountingContexts: {
610
+ data: accountingContexts,
611
+ isLoading: accountingContextsLoading
612
+ }
613
+ },
614
+ children
615
+ }
616
+ );
617
+ };
618
+
619
+ // src/contexts/JBTerminalContext/JBPrimaryNativeTerminalProvider.tsx
620
+ import { jsx as jsx8 } from "react/jsx-runtime";
621
+ function JBPrimaryNativeTerminalProvider({
622
+ children
623
+ }) {
624
+ const { contracts } = useJBContractContext();
625
+ const terminalAddress = contracts?.primaryNativeTerminal?.data;
626
+ debug8("JBPrimaryNativeTerminalProvider", { terminalAddress });
627
+ if (!terminalAddress) return children;
628
+ return /* @__PURE__ */ jsx8(JBTerminalProvider, { address: terminalAddress, children });
629
+ }
630
+
631
+ // src/contexts/JBProjectProvider/JBProjectProvider.tsx
632
+ import { jsx as jsx9 } from "react/jsx-runtime";
633
+ var JBProjectContext = createContext7(void 0);
634
+ var JBProjectProvider = ({
635
+ projectId,
636
+ chainId,
637
+ children,
638
+ ctxProps,
639
+ version,
640
+ bendystraw
641
+ }) => {
642
+ return /* @__PURE__ */ jsx9(JBProjectContext.Provider, { value: { chainId, projectId, version, bendystraw }, children: /* @__PURE__ */ jsx9(JBChainProvider, { chainId, children: /* @__PURE__ */ jsx9(JBContractProvider, { projectId, version, ...ctxProps?.contract, children: /* @__PURE__ */ jsx9(JBRulesetProvider, { children: /* @__PURE__ */ jsx9(JBProjectMetadataProvider, { ...ctxProps?.metadata, children: /* @__PURE__ */ jsx9(JBCurrentDataHookProvider, { children: /* @__PURE__ */ jsx9(JBPrimaryNativeTerminalProvider, { children: /* @__PURE__ */ jsx9(JBTokenProvider, { ...ctxProps?.token, children }) }) }) }) }) }) }) });
643
+ };
644
+ function useJBProject() {
645
+ return useContext7(JBProjectContext);
646
+ }
647
+ function useBendystrawConfig() {
648
+ return useContext7(JBProjectContext)?.bendystraw;
649
+ }
650
+
651
+ // src/lib/bendystraw/useBendystrawQuery.ts
652
+ function useBendystrawQuery(document, ...[variables, options]) {
653
+ const chainId = useJBChainId();
654
+ const config = useBendystrawConfig();
655
+ const url = chainId && config ? getBendystrawUrl(chainId, config) : void 0;
656
+ return useQuery3({
657
+ queryKey: [document.definitions[0].name.value, chainId, variables],
658
+ queryFn: async () => request(`${url}/graphql`, document, variables),
659
+ enabled: options?.enabled !== false && !!chainId && !!url,
660
+ refetchInterval: options?.pollInterval,
661
+ retry: 3,
662
+ retryDelay: (attemptIndex) => Math.min(1e3 * 2 ** attemptIndex, 3e4),
663
+ // Exponential backoff
664
+ staleTime: 3e4,
665
+ // Consider data stale after 30 seconds
666
+ gcTime: 5 * 60 * 1e3
667
+ // Keep in cache for 5 minutes
668
+ });
669
+ }
670
+
671
+ // src/hooks/suckers/useSuckers.ts
672
+ import {
673
+ arbitrum as arbitrum2,
674
+ arbitrumSepolia,
675
+ base as base2,
676
+ baseSepolia,
677
+ mainnet as mainnet3,
678
+ optimism as optimism2,
679
+ optimismSepolia,
680
+ sepolia
681
+ } from "viem/chains";
682
+ import { useMemo as useMemo2 } from "react";
683
+ var chainOrder = [
684
+ mainnet3.id,
685
+ base2.id,
686
+ optimism2.id,
687
+ arbitrum2.id,
688
+ sepolia.id,
689
+ baseSepolia.id,
690
+ optimismSepolia.id,
691
+ arbitrumSepolia.id
692
+ ];
693
+ function useSuckers(args) {
694
+ const { enabled = true } = args ?? {};
695
+ const { projectId, version } = useJBContractContext();
696
+ const chainId = useJBChainId();
697
+ debug9("useSuckers::args", { projectId, chainId });
698
+ const { data, ...rest } = useBendystrawQuery(ProjectDocument, {
699
+ projectId: Number(projectId),
700
+ chainId: Number(chainId),
701
+ version,
702
+ staleTime: Infinity,
703
+ enabled: !!chainId && enabled
704
+ });
705
+ const pairs = useMemo2(
706
+ () => data?.project?.suckerGroup?.projects?.items.map((item) => ({
707
+ peerChainId: item.chainId,
708
+ projectId: BigInt(item.projectId)
709
+ }))?.sort((a, b) => {
710
+ const aChainId = chainOrder.indexOf(a.peerChainId);
711
+ const bChainId = chainOrder.indexOf(b.peerChainId);
712
+ if (aChainId === -1 || bChainId === -1) return 0;
713
+ return aChainId - bChainId;
714
+ }),
715
+ [data]
716
+ );
717
+ return { data: pairs, ...rest };
718
+ }
719
+
720
+ // src/hooks/token/useNativeTokenSurplus.ts
721
+ import {
722
+ ETH_CURRENCY_ID,
723
+ jbMultiTerminalAbi as jbMultiTerminalAbi2,
724
+ jbMultiTerminalV5Abi,
725
+ NATIVE_TOKEN,
726
+ NATIVE_TOKEN_DECIMALS as NATIVE_TOKEN_DECIMALS2
727
+ } from "@bananapus/nana-sdk-core";
728
+ import { useReadContract as useReadContract6 } from "wagmi";
729
+ function useNativeTokenSurplus({
730
+ chainId
731
+ } = {}) {
732
+ const {
733
+ projectId,
734
+ version,
735
+ contracts: { primaryNativeTerminal }
736
+ } = useJBContractContext();
737
+ const _chainId = chainId ?? useJBChainId();
738
+ const v6Query = useReadContract6({
739
+ chainId: _chainId,
740
+ abi: jbMultiTerminalAbi2,
741
+ functionName: "currentSurplusOf",
742
+ address: primaryNativeTerminal.data ?? void 0,
743
+ args: [
744
+ projectId,
745
+ [NATIVE_TOKEN],
746
+ BigInt(NATIVE_TOKEN_DECIMALS2),
747
+ BigInt(ETH_CURRENCY_ID)
748
+ ],
749
+ query: { enabled: version === 6 }
750
+ });
751
+ const legacyQuery = useReadContract6({
752
+ chainId: _chainId,
753
+ abi: jbMultiTerminalV5Abi,
754
+ functionName: "currentSurplusOf",
755
+ address: primaryNativeTerminal.data ?? void 0,
756
+ args: [
757
+ projectId,
758
+ [
759
+ {
760
+ token: NATIVE_TOKEN,
761
+ decimals: NATIVE_TOKEN_DECIMALS2,
762
+ currency: ETH_CURRENCY_ID
763
+ }
764
+ ],
765
+ BigInt(NATIVE_TOKEN_DECIMALS2),
766
+ BigInt(ETH_CURRENCY_ID)
767
+ ],
768
+ query: { enabled: version !== 6 }
769
+ });
770
+ return version === 6 ? v6Query : legacyQuery;
771
+ }
772
+
773
+ // src/hooks/token/useSuckersNativeTokenSurplus.ts
774
+ import {
775
+ ETH_CURRENCY_ID as ETH_CURRENCY_ID2,
776
+ getPrimaryNativeTerminal,
777
+ jbMultiTerminalAbi as jbMultiTerminalAbi3,
778
+ jbMultiTerminalV5Abi as jbMultiTerminalV5Abi2,
779
+ NATIVE_TOKEN as NATIVE_TOKEN2,
780
+ NATIVE_TOKEN_DECIMALS as NATIVE_TOKEN_DECIMALS3
781
+ } from "@bananapus/nana-sdk-core";
782
+ import { getContract } from "viem";
783
+ import { useConfig } from "wagmi";
784
+ import { useQuery as useQuery4 } from "wagmi/query";
785
+ function useSuckersNativeTokenSurplus() {
786
+ const config = useConfig();
787
+ const chainId = useJBChainId();
788
+ const { projectId, version } = useJBContractContext();
789
+ const { data: pairs = [], isLoading, isError } = useSuckers();
790
+ const surplusQuery = useQuery4({
791
+ queryKey: [
792
+ "suckersNativeTokenSurplus",
793
+ projectId.toString(),
794
+ chainId?.toString(),
795
+ version,
796
+ pairs?.map((pair) => pair.peerChainId).join(",")
797
+ ],
798
+ queryFn: async () => {
799
+ if (!chainId) return null;
800
+ if (!pairs || pairs.length === 0) {
801
+ return [];
802
+ }
803
+ const surpluses = await Promise.all(
804
+ pairs.map(async (pair) => {
805
+ const { peerChainId, projectId: projectId2 } = pair;
806
+ const terminal = await getPrimaryNativeTerminal(
807
+ config,
808
+ peerChainId,
809
+ projectId2,
810
+ version
811
+ );
812
+ const surplus = version === 6 ? await getContract({
813
+ address: terminal,
814
+ abi: jbMultiTerminalAbi3,
815
+ client: config.getClient({ chainId: peerChainId })
816
+ }).read.currentSurplusOf([
817
+ projectId2,
818
+ [NATIVE_TOKEN2],
819
+ BigInt(NATIVE_TOKEN_DECIMALS3),
820
+ BigInt(ETH_CURRENCY_ID2)
821
+ ]) : await getContract({
822
+ address: terminal,
823
+ abi: jbMultiTerminalV5Abi2,
824
+ client: config.getClient({ chainId: peerChainId })
825
+ }).read.currentSurplusOf([
826
+ projectId2,
827
+ [
828
+ {
829
+ token: NATIVE_TOKEN2,
830
+ decimals: NATIVE_TOKEN_DECIMALS3,
831
+ currency: ETH_CURRENCY_ID2
832
+ }
833
+ ],
834
+ BigInt(NATIVE_TOKEN_DECIMALS3),
835
+ BigInt(ETH_CURRENCY_ID2)
836
+ ]);
837
+ return { surplus, chainId: peerChainId, projectId: projectId2 };
838
+ })
839
+ );
840
+ return surpluses;
841
+ }
842
+ });
843
+ return {
844
+ isLoading: surplusQuery.isLoading || isLoading,
845
+ isError: surplusQuery.isError || isError,
846
+ data: surplusQuery.data
847
+ };
848
+ }
849
+
850
+ // src/hooks/token/useSuckersCashOutQuote.ts
851
+ import {
852
+ applyJbDaoCashOutFee,
853
+ ETH_CURRENCY_ID as ETH_CURRENCY_ID3,
854
+ getProjectTerminalStore,
855
+ jbTerminalStoreAbi,
856
+ jbTerminalStoreV5Abi,
857
+ NATIVE_TOKEN_DECIMALS as NATIVE_TOKEN_DECIMALS4
858
+ } from "@bananapus/nana-sdk-core";
859
+ import { getContract as getContract2 } from "viem";
860
+ import { useConfig as useConfig2 } from "wagmi";
861
+ import { useQuery as useQuery5 } from "wagmi/query";
862
+ function useSuckersCashOutQuote(tokenAmountWei) {
863
+ const config = useConfig2();
864
+ const chainId = useJBChainId();
865
+ const { projectId, version } = useJBContractContext();
866
+ const { data: pairs = [], isLoading, error } = useSuckers();
867
+ const suckersQuote = useQuery5({
868
+ queryKey: [
869
+ "suckersTokenRedemptionQuote",
870
+ projectId.toString(),
871
+ chainId?.toString(),
872
+ version,
873
+ tokenAmountWei.toString(),
874
+ pairs.map((pair) => pair.peerChainId).join(",")
875
+ ],
876
+ enabled: Boolean(!isLoading && chainId),
877
+ queryFn: async () => {
878
+ if (!chainId) return null;
879
+ const quotes = await Promise.all(
880
+ pairs.map(async ({ peerChainId, projectId: projectId2 }) => {
881
+ return getTokenRedemptionQuote(
882
+ config,
883
+ peerChainId,
884
+ projectId2,
885
+ tokenAmountWei,
886
+ version
887
+ );
888
+ }) ?? []
889
+ );
890
+ return quotes.reduce((acc, quote) => acc + quote, 0n);
891
+ }
892
+ });
893
+ const netTotal = applyJbDaoCashOutFee(suckersQuote.data ?? 0n);
894
+ return {
895
+ data: netTotal,
896
+ isLoading: suckersQuote.isLoading || isLoading,
897
+ errors: [error, suckersQuote.error].filter(Boolean)
898
+ };
899
+ }
900
+ async function getTokenRedemptionQuote(config, chainId, projectId, tokenAmountWei, version) {
901
+ const contract = getContract2({
902
+ address: getProjectTerminalStore(chainId, version),
903
+ abi: version === 6 ? jbTerminalStoreAbi : jbTerminalStoreV5Abi,
904
+ client: config.getClient({ chainId })
905
+ });
906
+ return await contract.read.currentReclaimableSurplusOf([
907
+ projectId,
908
+ tokenAmountWei,
909
+ [],
910
+ [],
911
+ BigInt(NATIVE_TOKEN_DECIMALS4),
912
+ BigInt(ETH_CURRENCY_ID3)
913
+ ]);
914
+ }
915
+
916
+ // src/hooks/token/useTokenCashOutQuoteEth.ts
917
+ import {
918
+ ETH_CURRENCY_ID as ETH_CURRENCY_ID4,
919
+ NATIVE_TOKEN_DECIMALS as NATIVE_TOKEN_DECIMALS5,
920
+ applyJbDaoCashOutFee as applyJbDaoCashOutFee2,
921
+ jbTerminalStoreAbi as jbTerminalStoreAbi2,
922
+ jbTerminalStoreV5Abi as jbTerminalStoreV5Abi2
923
+ } from "@bananapus/nana-sdk-core";
924
+ import { useReadContract as useReadContract7 } from "wagmi";
925
+ function useTokenCashOutQuoteEth(tokenAmountWei, { chainId }) {
926
+ const { projectId, version } = useJBContractContext();
927
+ const { store } = useJBTerminalContext();
928
+ const jbChainId = useJBChainId();
929
+ const _chainId = chainId ?? jbChainId;
930
+ return useReadContract7({
931
+ abi: version === 6 ? jbTerminalStoreAbi2 : jbTerminalStoreV5Abi2,
932
+ functionName: "currentReclaimableSurplusOf",
933
+ chainId: _chainId,
934
+ address: store.data ?? void 0,
935
+ args: tokenAmountWei ? [projectId, tokenAmountWei, [], [], BigInt(NATIVE_TOKEN_DECIMALS5), BigInt(ETH_CURRENCY_ID4)] : void 0,
936
+ query: {
937
+ select(data) {
938
+ return applyJbDaoCashOutFee2(data);
939
+ }
940
+ }
941
+ });
942
+ }
943
+
944
+ // src/hooks/token/useSuckersTokenCashOutValue.ts
945
+ import { ONE_JB_TOKEN } from "@bananapus/nana-sdk-core";
946
+ import { formatEther } from "viem";
947
+
948
+ // src/hooks/useEtherPrice.ts
949
+ import { useQuery as useQuery6 } from "wagmi/query";
950
+ var PRICE_REFRESH_INTERVAL = 60 * 1e3 * 5;
951
+ function useEtherPrice() {
952
+ return useQuery6({
953
+ queryKey: ["juice-sdk", "etherPrice"],
954
+ queryFn: async () => {
955
+ return fetch("https://juicebox.money/api/juicebox/prices/ethusd").then((res) => res.json()).then((data) => data.price);
956
+ },
957
+ staleTime: PRICE_REFRESH_INTERVAL
958
+ });
959
+ }
960
+
961
+ // src/hooks/token/useSuckersTokenCashOutValue.ts
962
+ function useSuckersTokenCashOutValue({ targetCurrency }) {
963
+ const { data: ethPrice, isLoading: isEthLoading } = useEtherPrice();
964
+ const { data: quote, isLoading: isQuoteLoading, errors } = useSuckersCashOutQuote(ONE_JB_TOKEN);
965
+ const loading = isQuoteLoading || isEthLoading;
966
+ if (loading) {
967
+ return { loading: true, data: void 0 };
968
+ }
969
+ const quoteEth = parseFloat(formatEther(quote ?? 0n));
970
+ const data = targetCurrency === "eth" ? quoteEth : quoteEth * (ethPrice ?? 0);
971
+ return {
972
+ loading,
973
+ data,
974
+ errors
975
+ };
976
+ }
977
+
978
+ // src/hooks/token/useSuckersUserTokenBalance.ts
979
+ import { JBCoreContracts as JBCoreContracts2, JBProjectToken as JBProjectToken2, jbTokensAbi as jbTokensAbi2 } from "@bananapus/nana-sdk-core";
980
+ import { getContract as getContract3 } from "viem";
981
+ import { useAccount as useAccount2, useConfig as useConfig3, useReadContract as useReadContract8 } from "wagmi";
982
+ import { useQuery as useQuery7 } from "wagmi/query";
983
+ function useSuckersUserTokenBalance() {
984
+ const config = useConfig3();
985
+ const chainId = useJBChainId();
986
+ const { projectId, contractAddress } = useJBContractContext();
987
+ const { address: userAddress } = useAccount2();
988
+ const currentChainQuery = useReadContract8({
989
+ abi: jbTokensAbi2,
990
+ functionName: "totalBalanceOf",
991
+ address: contractAddress(JBCoreContracts2.JBTokens),
992
+ chainId,
993
+ args: userAddress ? [userAddress, projectId] : void 0,
994
+ query: {
995
+ select(data) {
996
+ return new JBProjectToken2(data);
997
+ }
998
+ }
999
+ });
1000
+ const { data: pairs = [], isLoading, isError } = useSuckers();
1001
+ const balanceQuery = useQuery7({
1002
+ queryKey: [
1003
+ "suckersUserTokenBalance",
1004
+ projectId.toString(),
1005
+ chainId?.toString(),
1006
+ currentChainQuery.data?.value.toString(),
1007
+ pairs?.map((pair) => pair.peerChainId).join(",")
1008
+ ],
1009
+ queryFn: async () => {
1010
+ if (!chainId || !userAddress) return null;
1011
+ const currentChain = {
1012
+ balance: currentChainQuery.data ?? new JBProjectToken2(0n),
1013
+ chainId,
1014
+ projectId
1015
+ };
1016
+ if (!pairs || pairs.length === 0) {
1017
+ return [currentChain];
1018
+ }
1019
+ const balances = await Promise.all(
1020
+ pairs.map(async (pair) => {
1021
+ const { peerChainId, projectId: projectId2 } = pair;
1022
+ const contract = getContract3({
1023
+ address: contractAddress(JBCoreContracts2.JBTokens, peerChainId),
1024
+ abi: jbTokensAbi2,
1025
+ client: config.getClient({ chainId: peerChainId })
1026
+ });
1027
+ const balance = await contract.read.totalBalanceOf([userAddress, projectId2]);
1028
+ return {
1029
+ balance: new JBProjectToken2(balance),
1030
+ chainId: peerChainId,
1031
+ projectId: projectId2
1032
+ };
1033
+ })
1034
+ );
1035
+ if (!balances.some((balance) => balance.chainId === currentChain.chainId)) {
1036
+ balances.push(currentChain);
1037
+ }
1038
+ return balances;
1039
+ }
1040
+ });
1041
+ return {
1042
+ isLoading: balanceQuery.isLoading || isLoading,
1043
+ isError: balanceQuery.isError || isError,
1044
+ data: balanceQuery.data
1045
+ };
1046
+ }
1047
+
1048
+ // src/hooks/token/useSuckersNativeTokenBalance.ts
1049
+ import {
1050
+ getPrimaryNativeTerminal as getPrimaryNativeTerminal2,
1051
+ getProjectTerminalStore as getProjectTerminalStore2,
1052
+ jbTerminalStoreAbi as jbTerminalStoreAbi3,
1053
+ NATIVE_TOKEN as NATIVE_TOKEN3
1054
+ } from "@bananapus/nana-sdk-core";
1055
+ import { getContract as getContract4 } from "viem";
1056
+ import { useConfig as useConfig4 } from "wagmi";
1057
+ import { useQuery as useQuery8 } from "wagmi/query";
1058
+ function useSuckersNativeTokenBalance() {
1059
+ const config = useConfig4();
1060
+ const chainId = useJBChainId();
1061
+ const { projectId, version } = useJBContractContext();
1062
+ const { data: pairs = [], isLoading, isError } = useSuckers();
1063
+ const balanceQuery = useQuery8({
1064
+ queryKey: [
1065
+ "suckersNativeTokenBalance",
1066
+ projectId.toString(),
1067
+ chainId?.toString(),
1068
+ pairs.map((pair) => pair.peerChainId).join(",")
1069
+ ],
1070
+ queryFn: async () => {
1071
+ if (!chainId) return null;
1072
+ if (!pairs || pairs.length === 0) return [];
1073
+ const balances = await Promise.all(
1074
+ pairs.map(async (pair) => {
1075
+ const { peerChainId, projectId: projectId2 } = pair;
1076
+ const terminal = await getPrimaryNativeTerminal2(config, peerChainId, projectId2, version);
1077
+ const contract = getContract4({
1078
+ address: getProjectTerminalStore2(peerChainId, version),
1079
+ abi: jbTerminalStoreAbi3,
1080
+ client: config.getClient({ chainId: peerChainId })
1081
+ });
1082
+ const balance = await contract.read.balanceOf([terminal, projectId2, NATIVE_TOKEN3]);
1083
+ return { balance, chainId: peerChainId, projectId: projectId2 };
1084
+ })
1085
+ );
1086
+ return balances;
1087
+ }
1088
+ });
1089
+ return {
1090
+ isLoading: balanceQuery.isLoading || isLoading,
1091
+ isError: balanceQuery.isError || isError,
1092
+ data: balanceQuery.data
1093
+ };
1094
+ }
1095
+
1096
+ // src/hooks/ruleset/useJBRuleset.ts
1097
+ import {
1098
+ CashOutTaxRate as CashOutTaxRate2,
1099
+ jbControllerAbi as jbControllerAbi3,
1100
+ ReservedPercent as ReservedPercent2,
1101
+ RulesetWeight as RulesetWeight2,
1102
+ WeightCutPercent as WeightCutPercent2
1103
+ } from "@bananapus/nana-sdk-core";
1104
+ import { useReadContract as useReadContract9 } from "wagmi";
1105
+ function useJBRuleset({
1106
+ projectId,
1107
+ chainId
1108
+ }) {
1109
+ const { contracts, version } = useJBContractContext();
1110
+ const query = useReadContract9({
1111
+ chainId,
1112
+ abi: jbControllerAbi3,
1113
+ functionName: "currentRulesetOf",
1114
+ address: contracts?.controller?.data ?? void 0,
1115
+ args: projectId ? [projectId] : void 0,
1116
+ query: {
1117
+ enabled: !!projectId && !!contracts?.controller?.data,
1118
+ select([ruleset, rulesetMetadata]) {
1119
+ return {
1120
+ data: {
1121
+ ...ruleset,
1122
+ weight: new RulesetWeight2(ruleset.weight),
1123
+ weightCutPercent: new WeightCutPercent2(ruleset.weightCutPercent)
1124
+ },
1125
+ metadata: {
1126
+ ...rulesetMetadata,
1127
+ cashOutTaxRate: new CashOutTaxRate2(rulesetMetadata.cashOutTaxRate),
1128
+ reservedPercent: new ReservedPercent2(rulesetMetadata.reservedPercent),
1129
+ // v4/v5 store the INVERSE flag (`useTotalSurplusForCashOuts`) in this slot;
1130
+ // normalize to the v6 field's semantics.
1131
+ scopeCashOutsToLocalBalances: version === 6 ? rulesetMetadata.scopeCashOutsToLocalBalances : !rulesetMetadata.scopeCashOutsToLocalBalances
1132
+ }
1133
+ };
1134
+ }
1135
+ }
1136
+ });
1137
+ const { resolvedDataHook } = useResolveDataHook({
1138
+ dataHookAddress: query.data?.metadata?.dataHook,
1139
+ projectId,
1140
+ chainId,
1141
+ rulesetId: BigInt(query.data?.data?.id ?? 0)
1142
+ });
1143
+ return {
1144
+ ruleset: query.data?.data,
1145
+ rulesetMetadata: query.data?.metadata && {
1146
+ ...query.data.metadata,
1147
+ dataHook: resolvedDataHook
1148
+ },
1149
+ ...query
1150
+ };
1151
+ }
1152
+
1153
+ // src/hooks/ruleset/useJBUpcomingRuleset.ts
1154
+ import {
1155
+ CashOutTaxRate as CashOutTaxRate3,
1156
+ jbControllerAbi as jbControllerAbi4,
1157
+ ReservedPercent as ReservedPercent3,
1158
+ RulesetWeight as RulesetWeight3,
1159
+ WeightCutPercent as WeightCutPercent3
1160
+ } from "@bananapus/nana-sdk-core";
1161
+ import { useReadContract as useReadContract10 } from "wagmi";
1162
+ function useJBUpcomingRuleset({
1163
+ projectId,
1164
+ chainId
1165
+ }) {
1166
+ const { contracts, version } = useJBContractContext();
1167
+ const { data, isLoading } = useReadContract10({
1168
+ abi: jbControllerAbi4,
1169
+ functionName: "upcomingRulesetOf",
1170
+ address: contracts.controller?.data ?? void 0,
1171
+ args: projectId ? [projectId] : void 0,
1172
+ chainId
1173
+ });
1174
+ const _latestUpcomingRuleset = data?.[0];
1175
+ const _latestUpcomingRulesetMetadata = data?.[1];
1176
+ const { resolvedDataHook } = useResolveDataHook({
1177
+ dataHookAddress: _latestUpcomingRulesetMetadata?.dataHook,
1178
+ projectId,
1179
+ chainId,
1180
+ rulesetId: BigInt(_latestUpcomingRuleset?.id ?? 0)
1181
+ });
1182
+ const upcomingWeight = new RulesetWeight3(_latestUpcomingRuleset?.weight ?? 0n);
1183
+ const upcomingWeightCutPercent = new WeightCutPercent3(
1184
+ _latestUpcomingRuleset?.weightCutPercent ?? 0
1185
+ );
1186
+ const latestUpcomingRuleset = _latestUpcomingRuleset ? {
1187
+ ..._latestUpcomingRuleset,
1188
+ weight: upcomingWeight,
1189
+ weightCutPercent: upcomingWeightCutPercent
1190
+ } : void 0;
1191
+ const upcomingReservedPercent = new ReservedPercent3(
1192
+ _latestUpcomingRulesetMetadata?.reservedPercent ?? 0
1193
+ );
1194
+ const upcomingCashOutTaxRate = new CashOutTaxRate3(
1195
+ _latestUpcomingRulesetMetadata?.cashOutTaxRate ?? 0
1196
+ );
1197
+ const latestUpcomingRulesetMetadata = _latestUpcomingRulesetMetadata ? {
1198
+ ..._latestUpcomingRulesetMetadata,
1199
+ reservedPercent: upcomingReservedPercent,
1200
+ cashOutTaxRate: upcomingCashOutTaxRate,
1201
+ // v4/v5 store the INVERSE flag (`useTotalSurplusForCashOuts`) in this slot;
1202
+ // normalize to the v6 field's semantics.
1203
+ scopeCashOutsToLocalBalances: version === 6 ? _latestUpcomingRulesetMetadata.scopeCashOutsToLocalBalances : !_latestUpcomingRulesetMetadata.scopeCashOutsToLocalBalances,
1204
+ dataHook: resolvedDataHook
1205
+ } : void 0;
1206
+ return {
1207
+ ruleset: latestUpcomingRuleset,
1208
+ rulesetMetadata: latestUpcomingRulesetMetadata,
1209
+ isLoading
1210
+ };
1211
+ }
1212
+
1213
+ // src/contexts/JBContractContext/JBContractContext.tsx
1214
+ import { useReadContract as useReadContract11 } from "wagmi";
1215
+ import { jsx as jsx10 } from "react/jsx-runtime";
1216
+ var JBContractContext = createContext8({
1217
+ /**
1218
+ * The project id of the Juicebox project.
1219
+ */
1220
+ projectId: 0n,
1221
+ version: 5,
1222
+ /**
1223
+ * The addresses of the contracts for the project.
1224
+ */
1225
+ contracts: {
1226
+ primaryNativeTerminal: AsyncDataNone,
1227
+ controller: AsyncDataNone,
1228
+ fundAccessLimits: AsyncDataNone,
1229
+ rulesets: AsyncDataNone,
1230
+ tokens: AsyncDataNone,
1231
+ splits: AsyncDataNone
1232
+ },
1233
+ contractAddress: () => zeroAddress4
1234
+ });
1235
+ function useJBContractContext() {
1236
+ return useContext8(JBContractContext);
1237
+ }
1238
+ var DynamicContract = /* @__PURE__ */ ((DynamicContract2) => {
1239
+ DynamicContract2[DynamicContract2["Controller"] = 0] = "Controller";
1240
+ DynamicContract2[DynamicContract2["PrimaryNativePaymentTerminal"] = 1] = "PrimaryNativePaymentTerminal";
1241
+ DynamicContract2[DynamicContract2["FundAccessLimits"] = 2] = "FundAccessLimits";
1242
+ DynamicContract2[DynamicContract2["Tokens"] = 3] = "Tokens";
1243
+ DynamicContract2[DynamicContract2["Splits"] = 4] = "Splits";
1244
+ DynamicContract2[DynamicContract2["Rulesets"] = 5] = "Rulesets";
1245
+ return DynamicContract2;
1246
+ })(DynamicContract || {});
1247
+ function useJBProjectId(chainId) {
1248
+ const currentChainId = useJBChainId();
1249
+ const { projectId: currentProjectId, version } = useJBContractContext();
1250
+ const { data: suckers } = useSuckers({ enabled: !!chainId });
1251
+ if (!chainId || currentChainId === chainId || !suckers) {
1252
+ return { projectId: currentProjectId, chainId: currentChainId, version };
1253
+ }
1254
+ const projectId = suckers.find((suckerPair) => suckerPair.peerChainId === chainId)?.projectId;
1255
+ return { projectId, chainId, version };
1256
+ }
1257
+ var JBContractProvider = ({
1258
+ projectId,
1259
+ include,
1260
+ children,
1261
+ version
1262
+ }) => {
1263
+ const chainId = useJBChainId();
1264
+ const enabled = useCallback(
1265
+ (selector) => {
1266
+ if (typeof include === "undefined") return true;
1267
+ return include.some((c) => selector.includes(c));
1268
+ },
1269
+ [include]
1270
+ );
1271
+ const jbDirectoryAddress = chainId ? jbContractAddress2[version][JBCoreContracts3.JBDirectory][chainId] : void 0;
1272
+ const primaryNativeTerminalEth = useReadContract11({
1273
+ address: jbDirectoryAddress,
1274
+ abi: jbDirectoryAbi,
1275
+ functionName: "primaryTerminalOf",
1276
+ chainId,
1277
+ args: enabled([1 /* PrimaryNativePaymentTerminal */]) ? [projectId, NATIVE_TOKEN4] : void 0
1278
+ });
1279
+ const primaryNativeTerminalUsdc = useReadContract11({
1280
+ address: jbDirectoryAddress,
1281
+ abi: jbDirectoryAbi,
1282
+ functionName: "primaryTerminalOf",
1283
+ chainId,
1284
+ args: enabled([1 /* PrimaryNativePaymentTerminal */]) ? [projectId, chainId ? USDC_ADDRESSES[chainId] : zeroAddress4] : void 0
1285
+ });
1286
+ const primaryNativeTerminal = useMemo3(() => {
1287
+ return primaryNativeTerminalEth.data !== zeroAddress4 ? primaryNativeTerminalEth : primaryNativeTerminalUsdc;
1288
+ }, [primaryNativeTerminalEth, primaryNativeTerminalUsdc]);
1289
+ const controller = useReadContract11({
1290
+ chainId,
1291
+ address: jbDirectoryAddress,
1292
+ abi: jbDirectoryAbi,
1293
+ functionName: "controllerOf",
1294
+ args: [projectId],
1295
+ query: {
1296
+ enabled: enabled([0 /* Controller */]),
1297
+ staleTime: Infinity
1298
+ }
1299
+ });
1300
+ const controllerAddress = useMemo3(() => controller.data, [controller.data]);
1301
+ const hasController = useMemo3(() => {
1302
+ return controllerAddress && !isAddressEqual4(controllerAddress, zeroAddress4);
1303
+ }, [controllerAddress]);
1304
+ const normalizedControllerAddress = useMemo3(() => {
1305
+ return hasController ? controllerAddress : zeroAddress4;
1306
+ }, [controllerAddress, hasController]);
1307
+ const fundAccessLimits = useReadContract11({
1308
+ chainId,
1309
+ address: normalizedControllerAddress,
1310
+ abi: jbControllerAbi5,
1311
+ functionName: "FUND_ACCESS_LIMITS",
1312
+ query: {
1313
+ enabled: enabled([0 /* Controller */, 2 /* FundAccessLimits */]),
1314
+ staleTime: Infinity
1315
+ }
1316
+ });
1317
+ const rulesets = useReadContract11({
1318
+ chainId,
1319
+ address: normalizedControllerAddress,
1320
+ abi: jbControllerAbi5,
1321
+ functionName: "RULESETS",
1322
+ query: {
1323
+ enabled: enabled([0 /* Controller */, 5 /* Rulesets */]),
1324
+ staleTime: Infinity
1325
+ }
1326
+ });
1327
+ const tokens = useReadContract11({
1328
+ chainId,
1329
+ address: normalizedControllerAddress,
1330
+ abi: jbControllerAbi5,
1331
+ functionName: "TOKENS",
1332
+ query: {
1333
+ enabled: enabled([0 /* Controller */, 3 /* Tokens */]),
1334
+ staleTime: Infinity
1335
+ }
1336
+ });
1337
+ const splits = useReadContract11({
1338
+ chainId,
1339
+ address: normalizedControllerAddress,
1340
+ abi: jbControllerAbi5,
1341
+ functionName: "SPLITS",
1342
+ query: {
1343
+ enabled: enabled([0 /* Controller */, 4 /* Splits */]),
1344
+ staleTime: Infinity
1345
+ }
1346
+ });
1347
+ const contractAddress = useCallback(
1348
+ (contract, _chainId) => {
1349
+ return getJBContractAddress2(contract, version, _chainId || chainId);
1350
+ },
1351
+ [version, chainId]
1352
+ );
1353
+ debug10("JBContractContext", {
1354
+ projectId,
1355
+ contracts: {
1356
+ controller,
1357
+ fundAccessLimits,
1358
+ primaryNativeTerminal,
1359
+ rulesets,
1360
+ tokens,
1361
+ splits
1362
+ }
1363
+ });
1364
+ return /* @__PURE__ */ jsx10(
1365
+ JBContractContext.Provider,
1366
+ {
1367
+ value: {
1368
+ version,
1369
+ projectId,
1370
+ contracts: {
1371
+ controller,
1372
+ fundAccessLimits,
1373
+ primaryNativeTerminal,
1374
+ rulesets,
1375
+ tokens,
1376
+ splits
1377
+ },
1378
+ contractAddress
1379
+ },
1380
+ children
1381
+ }
1382
+ );
1383
+ };
1384
+
1385
+ // src/lib/relayr/constants.ts
1386
+ var API = "https://api.relayr.ba5ed.com";
1387
+ var DASHBOARD = "https://relayr.ba5ed.com";
1388
+
1389
+ // src/lib/relayr/hooks/useRequestRelayrQuote.ts
1390
+ import { jbContractAddress as jbContractAddress3 } from "@bananapus/nana-sdk-core";
1391
+ import { useMutation } from "wagmi/query";
1392
+ function useRequestRelayrQuote() {
1393
+ const { version: contextVersion } = useJBContractContext();
1394
+ return useMutation({
1395
+ mutationFn: async (args) => {
1396
+ const transactions = args.map((ct) => {
1397
+ return {
1398
+ chain: ct.chain,
1399
+ data: ct.data,
1400
+ target: jbContractAddress3[ct.version ?? contextVersion]["ERC2771Forwarder"][ct.chain],
1401
+ value: ct.value
1402
+ };
1403
+ });
1404
+ const response = await fetch(`${API}/v1/bundle/prepaid`, {
1405
+ method: "POST",
1406
+ headers: {
1407
+ "Content-Type": "application/json"
1408
+ },
1409
+ body: JSON.stringify({
1410
+ transactions,
1411
+ virtual_nonce_mode: "Disabled"
1412
+ })
1413
+ });
1414
+ if (!response.ok) {
1415
+ console.error("Relayr ERROR:: ", response);
1416
+ const errorMessage = await response.text();
1417
+ throw new Error(errorMessage);
1418
+ }
1419
+ return await response.json();
1420
+ }
1421
+ });
1422
+ }
1423
+
1424
+ // src/lib/relayr/hooks/useSignErc2771ForwardRequest.ts
1425
+ import { erc2771ForwarderAbi, jbContractAddress as jbContractAddress4 } from "@bananapus/nana-sdk-core";
1426
+ import { encodeFunctionData, getContract as getContract5 } from "viem";
1427
+ import { useAccount as useAccount3, useConfig as useConfig5, useSignTypedData, useSwitchChain } from "wagmi";
1428
+ function useSignErc2771ForwardRequest() {
1429
+ const { switchChainAsync } = useSwitchChain();
1430
+ const { address } = useAccount3();
1431
+ const config = useConfig5();
1432
+ const { signTypedData } = useSignTypedData();
1433
+ const { version: contextVersion } = useJBContractContext();
1434
+ async function sign(messageData, chainId, version) {
1435
+ await switchChainAsync({ chainId });
1436
+ return new Promise(async (resolve, reject) => {
1437
+ if (!address) return;
1438
+ const verifyingContract = jbContractAddress4[version ?? contextVersion]["ERC2771Forwarder"][chainId];
1439
+ const deadline = Number(((Date.now() + 3600 * 48 * 1e3) / 1e3).toFixed(0));
1440
+ const contract = getContract5({
1441
+ address: verifyingContract,
1442
+ abi: erc2771ForwarderAbi,
1443
+ client: config.getClient({ chainId })
1444
+ });
1445
+ const nonce = await contract.read.nonces([address]);
1446
+ signTypedData(
1447
+ {
1448
+ domain: {
1449
+ name: "Juicebox",
1450
+ chainId,
1451
+ verifyingContract,
1452
+ version: "1"
1453
+ },
1454
+ primaryType: "ForwardRequest",
1455
+ types: {
1456
+ ForwardRequest: [
1457
+ {
1458
+ name: "from",
1459
+ type: "address"
1460
+ },
1461
+ {
1462
+ name: "to",
1463
+ type: "address"
1464
+ },
1465
+ {
1466
+ name: "value",
1467
+ type: "uint256"
1468
+ },
1469
+ {
1470
+ name: "gas",
1471
+ type: "uint256"
1472
+ },
1473
+ {
1474
+ name: "nonce",
1475
+ type: "uint256"
1476
+ },
1477
+ {
1478
+ name: "deadline",
1479
+ type: "uint48"
1480
+ },
1481
+ {
1482
+ name: "data",
1483
+ type: "bytes"
1484
+ }
1485
+ ]
1486
+ },
1487
+ message: { ...messageData, deadline, nonce }
1488
+ },
1489
+ {
1490
+ onSuccess: (signature) => {
1491
+ const executeFnEncodedData = encodeFunctionData({
1492
+ abi: erc2771ForwarderAbi,
1493
+ // ABI of the contract
1494
+ functionName: "execute",
1495
+ args: [
1496
+ {
1497
+ ...messageData,
1498
+ deadline,
1499
+ signature
1500
+ }
1501
+ ]
1502
+ });
1503
+ resolve(executeFnEncodedData);
1504
+ },
1505
+ onError: (e) => {
1506
+ reject(e);
1507
+ }
1508
+ }
1509
+ );
1510
+ });
1511
+ }
1512
+ return {
1513
+ sign
1514
+ };
1515
+ }
1516
+
1517
+ // src/lib/relayr/hooks/useGetRelayrTxQuote.ts
1518
+ function useGetRelayrTxQuote() {
1519
+ const requestRelayrQuote = useRequestRelayrQuote();
1520
+ const { sign } = useSignErc2771ForwardRequest();
1521
+ async function getRelayrTxQuote(data) {
1522
+ if (!data) return;
1523
+ const txDataRequest = [];
1524
+ for (const d of data) {
1525
+ const signedData = await sign(d.data, d.chainId, d.version);
1526
+ txDataRequest.push({
1527
+ chain: d.chainId,
1528
+ data: signedData,
1529
+ // The forwarder needs the forward request's value passed along with the execute call.
1530
+ value: d.data.value.toString(),
1531
+ version: d.version
1532
+ });
1533
+ }
1534
+ return await requestRelayrQuote.mutateAsync(txDataRequest);
1535
+ }
1536
+ return {
1537
+ getRelayrTxQuote,
1538
+ ...requestRelayrQuote
1539
+ };
1540
+ }
1541
+
1542
+ // src/lib/relayr/hooks/useGetRelayrTxBundle.ts
1543
+ import { useMemo as useMemo4, useState } from "react";
1544
+ import { useQuery as useQuery9 } from "wagmi/query";
1545
+ var POLL_INTERVAL = 2e3;
1546
+ var fetchTxBundle = async (uuid) => {
1547
+ if (!uuid) {
1548
+ throw new Error("No UUID provided");
1549
+ }
1550
+ const response = await fetch(`${API}/v1/bundle/${uuid}`);
1551
+ if (!response.ok) {
1552
+ const errorMessage = await response.text();
1553
+ throw new Error(errorMessage);
1554
+ }
1555
+ return response.json();
1556
+ };
1557
+ function useGetRelayrTxBundle() {
1558
+ const [uuid, setUuid] = useState();
1559
+ const getRelayrTxBundle = useQuery9({
1560
+ queryKey: ["txBundle", uuid],
1561
+ queryFn: () => fetchTxBundle(uuid),
1562
+ enabled: !!uuid,
1563
+ refetchInterval: (query) => query.state.data?.transactions?.every((tx) => tx?.status.state === "Success") ? false : POLL_INTERVAL
1564
+ });
1565
+ const startPolling = (bundleUuid) => {
1566
+ setUuid(bundleUuid);
1567
+ getRelayrTxBundle.refetch();
1568
+ };
1569
+ const isComplete = useMemo4(
1570
+ () => getRelayrTxBundle.data?.transactions?.every(
1571
+ (tx) => tx?.status.state === "Success"
1572
+ ),
1573
+ [getRelayrTxBundle.data]
1574
+ );
1575
+ return {
1576
+ startPolling,
1577
+ isComplete,
1578
+ uuid,
1579
+ response: getRelayrTxBundle.data,
1580
+ isPolling: getRelayrTxBundle.isFetching,
1581
+ error: getRelayrTxBundle.error
1582
+ };
1583
+ }
1584
+
1585
+ // src/lib/relayr/hooks/useSendRelayrTx.ts
1586
+ import { useCallback as useCallback2 } from "react";
1587
+ import { useChainId, useSwitchChain as useSwitchChain2, useSendTransaction } from "wagmi";
1588
+ function useSendRelayrTx() {
1589
+ const chainId = useChainId();
1590
+ const { switchChainAsync } = useSwitchChain2();
1591
+ const _sendTransaction = useSendTransaction();
1592
+ const sendRelayrTx = useCallback2(
1593
+ async (chainPayment) => {
1594
+ try {
1595
+ if (chainId !== chainPayment.chain) {
1596
+ try {
1597
+ await switchChainAsync({ chainId: chainPayment.chain });
1598
+ } catch (e) {
1599
+ console.error(e);
1600
+ throw new Error("Failed to switch to correct chain");
1601
+ }
1602
+ }
1603
+ const tx = await _sendTransaction.sendTransactionAsync({
1604
+ to: chainPayment.target,
1605
+ value: BigInt(chainPayment.amount),
1606
+ data: chainPayment.calldata
1607
+ });
1608
+ return tx;
1609
+ } catch (error) {
1610
+ throw error;
1611
+ }
1612
+ },
1613
+ [_sendTransaction.sendTransactionAsync, chainId, switchChainAsync]
1614
+ );
1615
+ return {
1616
+ sendRelayrTx,
1617
+ isPending: _sendTransaction.isPending,
1618
+ error: _sendTransaction.error,
1619
+ isSuccess: _sendTransaction.isSuccess,
1620
+ data: _sendTransaction.data
1621
+ };
1622
+ }
1623
+ export {
1624
+ API,
1625
+ DASHBOARD,
1626
+ DynamicContract,
1627
+ JBChainContext,
1628
+ JBChainProvider,
1629
+ JBContractContext,
1630
+ JBContractProvider,
1631
+ JBDataHookContext,
1632
+ JBDataHookProvider,
1633
+ JBProjectMetadataContext,
1634
+ JBProjectMetadataProvider,
1635
+ JBProjectProvider,
1636
+ JBRulesetContext,
1637
+ JBRulesetProvider,
1638
+ JBTerminalContext,
1639
+ JBTerminalProvider,
1640
+ JBTokenContext,
1641
+ JBTokenProvider,
1642
+ NativeTokenValue,
1643
+ getBendystrawUrl,
1644
+ useBendystrawQuery,
1645
+ useChain,
1646
+ useEtherPrice,
1647
+ useFind721DataHook,
1648
+ useGetRelayrTxBundle,
1649
+ useGetRelayrTxQuote,
1650
+ useJBChainId,
1651
+ useJBContractContext,
1652
+ useJBDataHookContext,
1653
+ useJBProject,
1654
+ useJBProjectId,
1655
+ useJBProjectMetadataContext,
1656
+ useJBRuleset,
1657
+ useJBRulesetContext,
1658
+ useJBRulesetMetadata,
1659
+ useJBTerminalContext,
1660
+ useJBTokenContext,
1661
+ useJBUpcomingRuleset,
1662
+ useNativeTokenSurplus,
1663
+ useNativeTokenSymbol,
1664
+ usePreparePayMetadata,
1665
+ useProjectMetadata,
1666
+ useResolveDataHook,
1667
+ useSendRelayrTx,
1668
+ useSuckers,
1669
+ useSuckersCashOutQuote,
1670
+ useSuckersNativeTokenBalance,
1671
+ useSuckersNativeTokenSurplus,
1672
+ useSuckersTokenCashOutValue,
1673
+ useSuckersUserTokenBalance,
1674
+ useTokenCashOutQuoteEth
1675
+ };
1676
+ //# sourceMappingURL=index.js.map