@cypher-zk/sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2 @@
1
+
2
+ export { }
@@ -0,0 +1,3 @@
1
+
2
+ //# sourceMappingURL=index.js.map
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -0,0 +1,164 @@
1
+ import React, { ReactNode } from 'react';
2
+ import { C as CypherClient, G as GlobalStateAccount, M as MarketAccount, E as EncryptedPositionAccount, a as CancelMarketParams, b as ClaimResult, c as ClaimInputs, d as CreateMarketResult, e as CreateMarketParams, P as PlaceBetResult, f as PlaceBetInputs, R as ResolveMarketResult, g as ResolveMarketInputs, S as SubscribeOptions, h as CypherEvent } from '../client-CO5-Gpyu.js';
3
+ import * as _tanstack_react_query from '@tanstack/react-query';
4
+ import { UseQueryOptions, UseMutationOptions } from '@tanstack/react-query';
5
+ import { PublicKey } from '@solana/web3.js';
6
+ import '@anchor-lang/core';
7
+ import '@arcium-hq/client';
8
+
9
+ interface CypherContextValue {
10
+ client: CypherClient;
11
+ }
12
+ interface CypherProviderProps {
13
+ /**
14
+ * A fully-constructed `CypherClient`. The provider does NOT manage
15
+ * lifecycle — the host app creates the client (with its own connection
16
+ * + wallet) and passes it in.
17
+ */
18
+ client: CypherClient;
19
+ children: ReactNode;
20
+ }
21
+ /**
22
+ * Provides a `CypherClient` instance to the React tree. All SDK hooks
23
+ * read from this context — mount exactly one `<CypherProvider>` at the
24
+ * top of your app (or the feature subtree that needs it).
25
+ *
26
+ * @example
27
+ * ```tsx
28
+ * import { CypherClient } from "@cypher/sdk";
29
+ * import { CypherProvider } from "@cypher/sdk/react";
30
+ *
31
+ * const client = new CypherClient({ connection, wallet, cluster: "devnet" });
32
+ *
33
+ * function App() {
34
+ * return (
35
+ * <CypherProvider client={client}>
36
+ * <MarketList />
37
+ * </CypherProvider>
38
+ * );
39
+ * }
40
+ * ```
41
+ */
42
+ declare function CypherProvider({ client, children }: CypherProviderProps): React.FunctionComponentElement<React.ProviderProps<CypherContextValue | null>>;
43
+ /**
44
+ * Returns the `CypherClient` from the nearest `<CypherProvider>`.
45
+ * Throws if called outside the provider tree.
46
+ */
47
+ declare function useCypherClient(): CypherClient;
48
+
49
+ /** Query key factory — keeps cache keys stable across the app. */
50
+ declare const globalStateKeys: {
51
+ all: readonly ["cypher", "globalState"];
52
+ };
53
+ /**
54
+ * Fetches the on-chain `GlobalState` singleton (protocol fees, admin,
55
+ * accepted mint, market counter). Automatically cached via React Query.
56
+ *
57
+ * @example
58
+ * ```tsx
59
+ * const { data: gs, isLoading } = useGlobalState();
60
+ * if (gs) console.log("Fee rate:", gs.protocolFeeRate);
61
+ * ```
62
+ */
63
+ declare function useGlobalState(opts?: Omit<UseQueryOptions<GlobalStateAccount, Error>, "queryKey" | "queryFn">): _tanstack_react_query.UseQueryResult<NoInfer<GlobalStateAccount>, Error>;
64
+
65
+ declare const marketKeys: {
66
+ all: readonly ["cypher", "market"];
67
+ one: (id: bigint | number) => readonly ["cypher", "market", string];
68
+ byCreator: (creator: PublicKey) => readonly ["cypher", "market", "creator", string];
69
+ byState: (state: number) => readonly ["cypher", "market", "state", number];
70
+ };
71
+ /**
72
+ * Fetch a single market by its numeric `marketId`.
73
+ *
74
+ * @example
75
+ * ```tsx
76
+ * const { data: market } = useMarket(42n);
77
+ * ```
78
+ */
79
+ declare function useMarket(marketId: bigint | number, opts?: Omit<UseQueryOptions<MarketAccount | null, Error>, "queryKey" | "queryFn">): _tanstack_react_query.UseQueryResult<NoInfer<MarketAccount | null>, Error>;
80
+ interface UseMarketsFilter {
81
+ creator?: PublicKey;
82
+ state?: number;
83
+ }
84
+ /**
85
+ * Fetch multiple markets, optionally filtered by creator or state.
86
+ * With no filter, fetches **all** markets (expensive on large deployments).
87
+ *
88
+ * @example
89
+ * ```tsx
90
+ * const { data: active } = useMarkets({ state: MarketState.Active });
91
+ * ```
92
+ */
93
+ declare function useMarkets(filter?: UseMarketsFilter, opts?: Omit<UseQueryOptions<Array<{
94
+ publicKey: PublicKey;
95
+ account: MarketAccount;
96
+ }>, Error>, "queryKey" | "queryFn">): _tanstack_react_query.UseQueryResult<NoInfer<{
97
+ publicKey: PublicKey;
98
+ account: MarketAccount;
99
+ }[]>, Error>;
100
+
101
+ declare const positionKeys: {
102
+ byUser: (user: PublicKey) => readonly ["cypher", "position", "user", string];
103
+ forMarket: (market: PublicKey) => readonly ["cypher", "position", "market", string];
104
+ };
105
+ /**
106
+ * Fetch all positions for a given user across all markets.
107
+ *
108
+ * @example
109
+ * ```tsx
110
+ * const { data: positions } = useUserPositions(wallet.publicKey);
111
+ * ```
112
+ */
113
+ declare function useUserPositions(user: PublicKey, opts?: Omit<UseQueryOptions<Array<{
114
+ publicKey: PublicKey;
115
+ account: EncryptedPositionAccount;
116
+ }>, Error>, "queryKey" | "queryFn">): _tanstack_react_query.UseQueryResult<NoInfer<{
117
+ publicKey: PublicKey;
118
+ account: EncryptedPositionAccount;
119
+ }[]>, Error>;
120
+
121
+ /**
122
+ * Mutation hook for the end-to-end `placeBet` action: encrypt → send →
123
+ * await callback → refetch position. Invalidates the market + position
124
+ * queries on success.
125
+ *
126
+ * @example
127
+ * ```tsx
128
+ * const { mutateAsync: placeBet, isPending } = usePlaceBet();
129
+ * await placeBet({ payer: wallet.publicKey, user: wallet.publicKey, marketId: 1n, side: 0, amountUsdc: 5_000_000n });
130
+ * ```
131
+ */
132
+ declare function usePlaceBet(opts?: Omit<UseMutationOptions<PlaceBetResult, Error, PlaceBetInputs>, "mutationFn">): _tanstack_react_query.UseMutationResult<PlaceBetResult, Error, PlaceBetInputs, unknown>;
133
+ declare function useResolveMarket(opts?: Omit<UseMutationOptions<ResolveMarketResult, Error, ResolveMarketInputs>, "mutationFn">): _tanstack_react_query.UseMutationResult<ResolveMarketResult, Error, ResolveMarketInputs, unknown>;
134
+ declare function useClaimPayout(opts?: Omit<UseMutationOptions<ClaimResult, Error, ClaimInputs>, "mutationFn">): _tanstack_react_query.UseMutationResult<ClaimResult, Error, ClaimInputs, unknown>;
135
+ declare function useClaimRefund(opts?: Omit<UseMutationOptions<ClaimResult, Error, ClaimInputs>, "mutationFn">): _tanstack_react_query.UseMutationResult<ClaimResult, Error, ClaimInputs, unknown>;
136
+ type CreateMarketInputs = Omit<CreateMarketParams, "expectedMarketId" | "acceptedMint"> & {
137
+ acceptedMint?: PublicKey;
138
+ };
139
+ declare function useCreateMarket(opts?: Omit<UseMutationOptions<CreateMarketResult, Error, CreateMarketInputs>, "mutationFn">): _tanstack_react_query.UseMutationResult<CreateMarketResult, Error, CreateMarketInputs, unknown>;
140
+ type CancelMarketInputs = Omit<CancelMarketParams, "acceptedMint"> & {
141
+ acceptedMint?: PublicKey;
142
+ };
143
+ declare function useCancelMarket(opts?: Omit<UseMutationOptions<{
144
+ signature: string;
145
+ market: MarketAccount | null;
146
+ }, Error, CancelMarketInputs>, "mutationFn">): _tanstack_react_query.UseMutationResult<{
147
+ signature: string;
148
+ market: MarketAccount | null;
149
+ }, Error, CancelMarketInputs, unknown>;
150
+
151
+ /**
152
+ * Subscribe to all Cypher events for the lifetime of the component.
153
+ * Returns the latest batch of events as an ever-growing array (newest
154
+ * last). Clear the buffer by re-mounting the component.
155
+ *
156
+ * @example
157
+ * ```tsx
158
+ * const events = useMarketEvents();
159
+ * // events: CypherEvent[]
160
+ * ```
161
+ */
162
+ declare function useMarketEvents(opts?: SubscribeOptions): CypherEvent[];
163
+
164
+ export { CypherProvider, type CypherProviderProps, type UseMarketsFilter, globalStateKeys, marketKeys, positionKeys, useCancelMarket, useClaimPayout, useClaimRefund, useCreateMarket, useCypherClient, useGlobalState, useMarket, useMarketEvents, useMarkets, usePlaceBet, useResolveMarket, useUserPositions };
@@ -0,0 +1,163 @@
1
+ import '../chunk-5WRI5ZAA.js';
2
+ import React, { createContext, useMemo, useContext, useState, useRef, useEffect } from 'react';
3
+ import { useQuery, useQueryClient, useMutation } from '@tanstack/react-query';
4
+
5
+ var CypherContext = createContext(null);
6
+ function CypherProvider({ client, children }) {
7
+ const value = useMemo(() => ({ client }), [client]);
8
+ return React.createElement(CypherContext.Provider, { value }, children);
9
+ }
10
+ function useCypherClient() {
11
+ const ctx = useContext(CypherContext);
12
+ if (!ctx) {
13
+ throw new Error(
14
+ "useCypherClient must be used within a <CypherProvider>. Wrap your component tree with <CypherProvider client={client}>."
15
+ );
16
+ }
17
+ return ctx.client;
18
+ }
19
+ var globalStateKeys = {
20
+ all: ["cypher", "globalState"]
21
+ };
22
+ function useGlobalState(opts) {
23
+ const client = useCypherClient();
24
+ return useQuery({
25
+ queryKey: globalStateKeys.all,
26
+ queryFn: () => client.globalState.fetch({ refresh: true }),
27
+ staleTime: 3e4,
28
+ // 30s — global state changes rarely
29
+ ...opts
30
+ });
31
+ }
32
+ var marketKeys = {
33
+ all: ["cypher", "market"],
34
+ one: (id) => ["cypher", "market", String(id)],
35
+ byCreator: (creator) => ["cypher", "market", "creator", creator.toBase58()],
36
+ byState: (state) => ["cypher", "market", "state", state]
37
+ };
38
+ function useMarket(marketId, opts) {
39
+ const client = useCypherClient();
40
+ return useQuery({
41
+ queryKey: marketKeys.one(marketId),
42
+ queryFn: () => client.markets.fetch(marketId),
43
+ staleTime: 1e4,
44
+ ...opts
45
+ });
46
+ }
47
+ function useMarkets(filter, opts) {
48
+ const client = useCypherClient();
49
+ const queryKey = filter?.creator ? marketKeys.byCreator(filter.creator) : filter?.state !== void 0 ? marketKeys.byState(filter.state) : marketKeys.all;
50
+ const queryFn = () => {
51
+ if (filter?.creator) return client.markets.byCreator(filter.creator);
52
+ if (filter?.state !== void 0) return client.markets.byState(filter.state);
53
+ return client.markets.all();
54
+ };
55
+ return useQuery({
56
+ queryKey,
57
+ queryFn,
58
+ staleTime: 1e4,
59
+ ...opts
60
+ });
61
+ }
62
+ var positionKeys = {
63
+ byUser: (user) => ["cypher", "position", "user", user.toBase58()],
64
+ forMarket: (market) => ["cypher", "position", "market", market.toBase58()]
65
+ };
66
+ function useUserPositions(user, opts) {
67
+ const client = useCypherClient();
68
+ return useQuery({
69
+ queryKey: positionKeys.byUser(user),
70
+ queryFn: () => client.positions.byUser(user),
71
+ staleTime: 5e3,
72
+ ...opts
73
+ });
74
+ }
75
+ function usePlaceBet(opts) {
76
+ const client = useCypherClient();
77
+ const qc = useQueryClient();
78
+ return useMutation({
79
+ mutationFn: (inputs) => client.actions.placeBet(inputs),
80
+ onSuccess: (_data, vars) => {
81
+ qc.invalidateQueries({ queryKey: marketKeys.one(vars.marketId) });
82
+ qc.invalidateQueries({ queryKey: positionKeys.byUser(vars.user) });
83
+ },
84
+ ...opts
85
+ });
86
+ }
87
+ function useResolveMarket(opts) {
88
+ const client = useCypherClient();
89
+ const qc = useQueryClient();
90
+ return useMutation({
91
+ mutationFn: (inputs) => client.actions.resolveMarket(inputs),
92
+ onSuccess: (_data, vars) => {
93
+ qc.invalidateQueries({ queryKey: marketKeys.one(vars.marketId) });
94
+ },
95
+ ...opts
96
+ });
97
+ }
98
+ function useClaimPayout(opts) {
99
+ const client = useCypherClient();
100
+ const qc = useQueryClient();
101
+ return useMutation({
102
+ mutationFn: (inputs) => client.actions.claimPayout(inputs),
103
+ onSuccess: (_data, vars) => {
104
+ qc.invalidateQueries({ queryKey: marketKeys.one(vars.marketId) });
105
+ qc.invalidateQueries({ queryKey: positionKeys.byUser(vars.user) });
106
+ },
107
+ ...opts
108
+ });
109
+ }
110
+ function useClaimRefund(opts) {
111
+ const client = useCypherClient();
112
+ const qc = useQueryClient();
113
+ return useMutation({
114
+ mutationFn: (inputs) => client.actions.claimRefund(inputs),
115
+ onSuccess: (_data, vars) => {
116
+ qc.invalidateQueries({ queryKey: marketKeys.one(vars.marketId) });
117
+ qc.invalidateQueries({ queryKey: positionKeys.byUser(vars.user) });
118
+ },
119
+ ...opts
120
+ });
121
+ }
122
+ function useCreateMarket(opts) {
123
+ const client = useCypherClient();
124
+ const qc = useQueryClient();
125
+ return useMutation({
126
+ mutationFn: (inputs) => client.actions.createMarket(inputs),
127
+ onSuccess: () => {
128
+ qc.invalidateQueries({ queryKey: marketKeys.all });
129
+ },
130
+ ...opts
131
+ });
132
+ }
133
+ function useCancelMarket(opts) {
134
+ const client = useCypherClient();
135
+ const qc = useQueryClient();
136
+ return useMutation({
137
+ mutationFn: (inputs) => client.actions.cancelMarket(inputs),
138
+ onSuccess: (_data, vars) => {
139
+ qc.invalidateQueries({ queryKey: marketKeys.one(vars.marketId) });
140
+ qc.invalidateQueries({ queryKey: marketKeys.all });
141
+ },
142
+ ...opts
143
+ });
144
+ }
145
+ function useMarketEvents(opts) {
146
+ const client = useCypherClient();
147
+ const [events, setEvents] = useState([]);
148
+ const subRef = useRef(null);
149
+ useEffect(() => {
150
+ subRef.current = client.events.subscribeAll((event) => {
151
+ setEvents((prev) => [...prev, event]);
152
+ }, opts);
153
+ return () => {
154
+ subRef.current?.unsubscribe();
155
+ subRef.current = null;
156
+ };
157
+ }, [client]);
158
+ return events;
159
+ }
160
+
161
+ export { CypherProvider, globalStateKeys, marketKeys, positionKeys, useCancelMarket, useClaimPayout, useClaimRefund, useCreateMarket, useCypherClient, useGlobalState, useMarket, useMarketEvents, useMarkets, usePlaceBet, useResolveMarket, useUserPositions };
162
+ //# sourceMappingURL=index.js.map
163
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../react/src/CypherProvider.tsx","../../react/src/useGlobalState.ts","../../react/src/useMarket.ts","../../react/src/useUserPositions.ts","../../react/src/mutations.ts","../../react/src/useMarketEvents.ts"],"names":["useQuery"],"mappings":"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","file":"index.js","sourcesContent":["\"use client\";\n\nimport React, { createContext, useContext, useMemo, type ReactNode } from \"react\";\nimport type { CypherClient } from \"../../src/client.ts\";\n\n/* -----------------------------------------------------------------------\n * Context\n * ----------------------------------------------------------------------- */\n\ninterface CypherContextValue {\n client: CypherClient;\n}\n\nconst CypherContext = createContext<CypherContextValue | null>(null);\n\n/* -----------------------------------------------------------------------\n * Provider\n * ----------------------------------------------------------------------- */\n\nexport interface CypherProviderProps {\n /**\n * A fully-constructed `CypherClient`. The provider does NOT manage\n * lifecycle — the host app creates the client (with its own connection\n * + wallet) and passes it in.\n */\n client: CypherClient;\n children: ReactNode;\n}\n\n/**\n * Provides a `CypherClient` instance to the React tree. All SDK hooks\n * read from this context — mount exactly one `<CypherProvider>` at the\n * top of your app (or the feature subtree that needs it).\n *\n * @example\n * ```tsx\n * import { CypherClient } from \"@cypher/sdk\";\n * import { CypherProvider } from \"@cypher/sdk/react\";\n *\n * const client = new CypherClient({ connection, wallet, cluster: \"devnet\" });\n *\n * function App() {\n * return (\n * <CypherProvider client={client}>\n * <MarketList />\n * </CypherProvider>\n * );\n * }\n * ```\n */\nexport function CypherProvider({ client, children }: CypherProviderProps) {\n const value = useMemo<CypherContextValue>(() => ({ client }), [client]);\n return React.createElement(CypherContext.Provider, { value }, children);\n}\n\n/* -----------------------------------------------------------------------\n * Hook\n * ----------------------------------------------------------------------- */\n\n/**\n * Returns the `CypherClient` from the nearest `<CypherProvider>`.\n * Throws if called outside the provider tree.\n */\nexport function useCypherClient(): CypherClient {\n const ctx = useContext(CypherContext);\n if (!ctx) {\n throw new Error(\n \"useCypherClient must be used within a <CypherProvider>. \" +\n \"Wrap your component tree with <CypherProvider client={client}>.\",\n );\n }\n return ctx.client;\n}\n","\"use client\";\n\nimport { useQuery, type UseQueryOptions } from \"@tanstack/react-query\";\nimport { useCypherClient } from \"./CypherProvider.tsx\";\nimport type { GlobalStateAccount } from \"../../src/accounts/index.ts\";\n\n/** Query key factory — keeps cache keys stable across the app. */\nexport const globalStateKeys = {\n all: [\"cypher\", \"globalState\"] as const,\n};\n\n/**\n * Fetches the on-chain `GlobalState` singleton (protocol fees, admin,\n * accepted mint, market counter). Automatically cached via React Query.\n *\n * @example\n * ```tsx\n * const { data: gs, isLoading } = useGlobalState();\n * if (gs) console.log(\"Fee rate:\", gs.protocolFeeRate);\n * ```\n */\nexport function useGlobalState(\n opts?: Omit<\n UseQueryOptions<GlobalStateAccount, Error>,\n \"queryKey\" | \"queryFn\"\n >,\n) {\n const client = useCypherClient();\n return useQuery<GlobalStateAccount, Error>({\n queryKey: globalStateKeys.all,\n queryFn: () => client.globalState.fetch({ refresh: true }),\n staleTime: 30_000, // 30s — global state changes rarely\n ...opts,\n });\n}\n","\"use client\";\n\nimport { useQuery, type UseQueryOptions } from \"@tanstack/react-query\";\nimport type { PublicKey } from \"@solana/web3.js\";\nimport { useCypherClient } from \"./CypherProvider.tsx\";\nimport type { MarketAccount } from \"../../src/accounts/index.ts\";\n\nexport const marketKeys = {\n all: [\"cypher\", \"market\"] as const,\n one: (id: bigint | number) => [\"cypher\", \"market\", String(id)] as const,\n byCreator: (creator: PublicKey) =>\n [\"cypher\", \"market\", \"creator\", creator.toBase58()] as const,\n byState: (state: number) =>\n [\"cypher\", \"market\", \"state\", state] as const,\n};\n\n/**\n * Fetch a single market by its numeric `marketId`.\n *\n * @example\n * ```tsx\n * const { data: market } = useMarket(42n);\n * ```\n */\nexport function useMarket(\n marketId: bigint | number,\n opts?: Omit<\n UseQueryOptions<MarketAccount | null, Error>,\n \"queryKey\" | \"queryFn\"\n >,\n) {\n const client = useCypherClient();\n return useQuery<MarketAccount | null, Error>({\n queryKey: marketKeys.one(marketId),\n queryFn: () => client.markets.fetch(marketId),\n staleTime: 10_000,\n ...opts,\n });\n}\n\nexport interface UseMarketsFilter {\n creator?: PublicKey;\n state?: number;\n}\n\n/**\n * Fetch multiple markets, optionally filtered by creator or state.\n * With no filter, fetches **all** markets (expensive on large deployments).\n *\n * @example\n * ```tsx\n * const { data: active } = useMarkets({ state: MarketState.Active });\n * ```\n */\nexport function useMarkets(\n filter?: UseMarketsFilter,\n opts?: Omit<\n UseQueryOptions<\n Array<{ publicKey: PublicKey; account: MarketAccount }>,\n Error\n >,\n \"queryKey\" | \"queryFn\"\n >,\n) {\n const client = useCypherClient();\n\n const queryKey = filter?.creator\n ? marketKeys.byCreator(filter.creator)\n : filter?.state !== undefined\n ? marketKeys.byState(filter.state)\n : marketKeys.all;\n\n const queryFn = () => {\n if (filter?.creator) return client.markets.byCreator(filter.creator);\n if (filter?.state !== undefined) return client.markets.byState(filter.state);\n return client.markets.all();\n };\n\n return useQuery({\n queryKey,\n queryFn,\n staleTime: 10_000,\n ...opts,\n });\n}\n","\"use client\";\n\nimport { useQuery, type UseQueryOptions } from \"@tanstack/react-query\";\nimport type { PublicKey } from \"@solana/web3.js\";\nimport { useCypherClient } from \"./CypherProvider.tsx\";\nimport type { EncryptedPositionAccount } from \"../../src/accounts/index.ts\";\n\nexport const positionKeys = {\n byUser: (user: PublicKey) =>\n [\"cypher\", \"position\", \"user\", user.toBase58()] as const,\n forMarket: (market: PublicKey) =>\n [\"cypher\", \"position\", \"market\", market.toBase58()] as const,\n};\n\n/**\n * Fetch all positions for a given user across all markets.\n *\n * @example\n * ```tsx\n * const { data: positions } = useUserPositions(wallet.publicKey);\n * ```\n */\nexport function useUserPositions(\n user: PublicKey,\n opts?: Omit<\n UseQueryOptions<\n Array<{ publicKey: PublicKey; account: EncryptedPositionAccount }>,\n Error\n >,\n \"queryKey\" | \"queryFn\"\n >,\n) {\n const client = useCypherClient();\n return useQuery({\n queryKey: positionKeys.byUser(user),\n queryFn: () => client.positions.byUser(user),\n staleTime: 5_000,\n ...opts,\n });\n}\n","\"use client\";\n\nimport { useMutation, useQueryClient, type UseMutationOptions } from \"@tanstack/react-query\";\nimport { useCypherClient } from \"./CypherProvider.tsx\";\nimport { marketKeys } from \"./useMarket.ts\";\nimport { positionKeys } from \"./useUserPositions.ts\";\nimport type {\n PlaceBetInputs,\n PlaceBetResult,\n ResolveMarketInputs,\n ResolveMarketResult,\n ClaimInputs,\n ClaimResult,\n CreateMarketResult,\n} from \"../../src/actions/index.ts\";\nimport type {\n CreateMarketParams,\n CreateMarketMultiParams,\n CancelMarketParams,\n WithdrawCreatorFundsParams,\n} from \"../../src/instructions/index.ts\";\nimport type { PublicKey } from \"@solana/web3.js\";\nimport type { MarketAccount } from \"../../src/accounts/index.ts\";\n\n/* -----------------------------------------------------------------------\n * usePlaceBet\n * ----------------------------------------------------------------------- */\n\n/**\n * Mutation hook for the end-to-end `placeBet` action: encrypt → send →\n * await callback → refetch position. Invalidates the market + position\n * queries on success.\n *\n * @example\n * ```tsx\n * const { mutateAsync: placeBet, isPending } = usePlaceBet();\n * await placeBet({ payer: wallet.publicKey, user: wallet.publicKey, marketId: 1n, side: 0, amountUsdc: 5_000_000n });\n * ```\n */\nexport function usePlaceBet(\n opts?: Omit<UseMutationOptions<PlaceBetResult, Error, PlaceBetInputs>, \"mutationFn\">,\n) {\n const client = useCypherClient();\n const qc = useQueryClient();\n return useMutation<PlaceBetResult, Error, PlaceBetInputs>({\n mutationFn: (inputs) => client.actions.placeBet(inputs),\n onSuccess: (_data, vars) => {\n qc.invalidateQueries({ queryKey: marketKeys.one(vars.marketId) });\n qc.invalidateQueries({ queryKey: positionKeys.byUser(vars.user) });\n },\n ...opts,\n });\n}\n\n/* -----------------------------------------------------------------------\n * useResolveMarket\n * ----------------------------------------------------------------------- */\n\nexport function useResolveMarket(\n opts?: Omit<UseMutationOptions<ResolveMarketResult, Error, ResolveMarketInputs>, \"mutationFn\">,\n) {\n const client = useCypherClient();\n const qc = useQueryClient();\n return useMutation<ResolveMarketResult, Error, ResolveMarketInputs>({\n mutationFn: (inputs) => client.actions.resolveMarket(inputs),\n onSuccess: (_data, vars) => {\n qc.invalidateQueries({ queryKey: marketKeys.one(vars.marketId) });\n },\n ...opts,\n });\n}\n\n/* -----------------------------------------------------------------------\n * useClaimPayout\n * ----------------------------------------------------------------------- */\n\nexport function useClaimPayout(\n opts?: Omit<UseMutationOptions<ClaimResult, Error, ClaimInputs>, \"mutationFn\">,\n) {\n const client = useCypherClient();\n const qc = useQueryClient();\n return useMutation<ClaimResult, Error, ClaimInputs>({\n mutationFn: (inputs) => client.actions.claimPayout(inputs),\n onSuccess: (_data, vars) => {\n qc.invalidateQueries({ queryKey: marketKeys.one(vars.marketId) });\n qc.invalidateQueries({ queryKey: positionKeys.byUser(vars.user) });\n },\n ...opts,\n });\n}\n\n/* -----------------------------------------------------------------------\n * useClaimRefund\n * ----------------------------------------------------------------------- */\n\nexport function useClaimRefund(\n opts?: Omit<UseMutationOptions<ClaimResult, Error, ClaimInputs>, \"mutationFn\">,\n) {\n const client = useCypherClient();\n const qc = useQueryClient();\n return useMutation<ClaimResult, Error, ClaimInputs>({\n mutationFn: (inputs) => client.actions.claimRefund(inputs),\n onSuccess: (_data, vars) => {\n qc.invalidateQueries({ queryKey: marketKeys.one(vars.marketId) });\n qc.invalidateQueries({ queryKey: positionKeys.byUser(vars.user) });\n },\n ...opts,\n });\n}\n\n/* -----------------------------------------------------------------------\n * useCreateMarket\n * ----------------------------------------------------------------------- */\n\ntype CreateMarketInputs = Omit<CreateMarketParams, \"expectedMarketId\" | \"acceptedMint\"> & {\n acceptedMint?: PublicKey;\n};\n\nexport function useCreateMarket(\n opts?: Omit<UseMutationOptions<CreateMarketResult, Error, CreateMarketInputs>, \"mutationFn\">,\n) {\n const client = useCypherClient();\n const qc = useQueryClient();\n return useMutation<CreateMarketResult, Error, CreateMarketInputs>({\n mutationFn: (inputs) => client.actions.createMarket(inputs),\n onSuccess: () => {\n qc.invalidateQueries({ queryKey: marketKeys.all });\n },\n ...opts,\n });\n}\n\n/* -----------------------------------------------------------------------\n * useCancelMarket\n * ----------------------------------------------------------------------- */\n\ntype CancelMarketInputs = Omit<CancelMarketParams, \"acceptedMint\"> & {\n acceptedMint?: PublicKey;\n};\n\nexport function useCancelMarket(\n opts?: Omit<\n UseMutationOptions<{ signature: string; market: MarketAccount | null }, Error, CancelMarketInputs>,\n \"mutationFn\"\n >,\n) {\n const client = useCypherClient();\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (inputs: CancelMarketInputs) => client.actions.cancelMarket(inputs),\n onSuccess: (_data, vars) => {\n qc.invalidateQueries({ queryKey: marketKeys.one(vars.marketId) });\n qc.invalidateQueries({ queryKey: marketKeys.all });\n },\n ...opts,\n });\n}\n","\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\nimport { useCypherClient } from \"./CypherProvider.tsx\";\nimport type { CypherEvent, EventSubscription, SubscribeOptions } from \"../../src/events/index.ts\";\n\n/**\n * Subscribe to all Cypher events for the lifetime of the component.\n * Returns the latest batch of events as an ever-growing array (newest\n * last). Clear the buffer by re-mounting the component.\n *\n * @example\n * ```tsx\n * const events = useMarketEvents();\n * // events: CypherEvent[]\n * ```\n */\nexport function useMarketEvents(opts?: SubscribeOptions): CypherEvent[] {\n const client = useCypherClient();\n const [events, setEvents] = useState<CypherEvent[]>([]);\n const subRef = useRef<EventSubscription | null>(null);\n\n useEffect(() => {\n subRef.current = client.events.subscribeAll((event) => {\n setEvents((prev) => [...prev, event]);\n }, opts);\n return () => {\n subRef.current?.unsubscribe();\n subRef.current = null;\n };\n // Re-subscribe when the client identity changes\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [client]);\n\n return events;\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,97 @@
1
+ {
2
+ "name": "@cypher-zk/sdk",
3
+ "version": "0.1.0",
4
+ "description": "TypeScript SDK for the Cypher prediction market (Arcium + Anchor on Solana)",
5
+ "type": "module",
6
+ "license": "SEE LICENSE IN LICENSE",
7
+ "sideEffects": false,
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/cypher-zk/cypher-sdk.git"
11
+ },
12
+ "homepage": "https://cyphers.live",
13
+ "bugs": {
14
+ "url": "https://github.com/cypher-zk/cypher-sdk/issues"
15
+ },
16
+ "publishConfig": {
17
+ "access": "public"
18
+ },
19
+ "files": [
20
+ "dist",
21
+ "src/idl",
22
+ "LICENSE",
23
+ "README.md"
24
+ ],
25
+ "main": "./dist/index.js",
26
+ "module": "./dist/index.js",
27
+ "types": "./dist/index.d.ts",
28
+ "exports": {
29
+ ".": {
30
+ "types": "./dist/index.d.ts",
31
+ "import": "./dist/index.js"
32
+ },
33
+ "./node": {
34
+ "types": "./dist/node/index.d.ts",
35
+ "import": "./dist/node/index.js"
36
+ },
37
+ "./react": {
38
+ "types": "./dist/react/index.d.ts",
39
+ "import": "./dist/react/index.js"
40
+ },
41
+ "./idl": "./src/idl/cypher.json",
42
+ "./package.json": "./package.json"
43
+ },
44
+ "scripts": {
45
+ "build": "tsup",
46
+ "typecheck": "tsc --noEmit",
47
+ "test": "bun test",
48
+ "test:unit": "bun test tests/unit",
49
+ "test:integration": "INTEGRATION=1 bun test tests/integration",
50
+ "test:devnet": "DEVNET=1 bun test tests/devnet",
51
+ "sync:idl": "bun run scripts/sync-idl.ts",
52
+ "clean": "rm -rf dist",
53
+ "prepublishOnly": "bun run sync:idl && bun run typecheck && bun run test:unit && bun run build"
54
+ },
55
+ "dependencies": {
56
+ "@anchor-lang/core": "^1.0.2",
57
+ "@arcium-hq/client": "^0.10.4",
58
+ "@solana/spl-token": "^0.4.14",
59
+ "@solana/web3.js": "^1.95.0",
60
+ "bn.js": "^5.2.1"
61
+ },
62
+ "peerDependencies": {
63
+ "@tanstack/react-query": "^5.0.0",
64
+ "react": "^18.0.0 || ^19.0.0",
65
+ "typescript": "^5.0.0"
66
+ },
67
+ "peerDependenciesMeta": {
68
+ "react": {
69
+ "optional": true
70
+ },
71
+ "@tanstack/react-query": {
72
+ "optional": true
73
+ }
74
+ },
75
+ "devDependencies": {
76
+ "@tanstack/react-query": "^5.0.0",
77
+ "@types/bn.js": "^5.1.0",
78
+ "@types/bun": "latest",
79
+ "@types/react": "^18",
80
+ "react": "^18.0.0",
81
+ "tsup": "^8.3.0",
82
+ "typescript": "^5.9.0"
83
+ },
84
+ "engines": {
85
+ "node": ">=18"
86
+ },
87
+ "keywords": [
88
+ "solana",
89
+ "anchor",
90
+ "arcium",
91
+ "mpc",
92
+ "prediction-market",
93
+ "cypher",
94
+ "privacy",
95
+ "sdk"
96
+ ]
97
+ }