@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.
- package/LICENSE +32 -0
- package/README.md +266 -0
- package/dist/chunk-5WRI5ZAA.js +29 -0
- package/dist/chunk-5WRI5ZAA.js.map +1 -0
- package/dist/client-CO5-Gpyu.d.ts +6414 -0
- package/dist/cypher-WAYH63ZA.json +5288 -0
- package/dist/index.d.ts +507 -0
- package/dist/index.js +3635 -0
- package/dist/index.js.map +1 -0
- package/dist/node/index.d.ts +2 -0
- package/dist/node/index.js +3 -0
- package/dist/node/index.js.map +1 -0
- package/dist/react/index.d.ts +164 -0
- package/dist/react/index.js +163 -0
- package/dist/react/index.js.map +1 -0
- package/package.json +97 -0
- package/src/idl/cypher.json +5288 -0
- package/src/idl/cypher.ts +5294 -0
- package/src/idl/index.ts +8 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
Cypher SDK — Source Available License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Cypher Labs. All rights reserved.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a
|
|
6
|
+
copy of this software and associated documentation files (the "Software"),
|
|
7
|
+
to use the Software solely for the purpose of integrating with and building
|
|
8
|
+
applications on the Cypher, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
1. USE: You may use, copy, and modify the Software for internal development,
|
|
11
|
+
testing, and production use in applications that interact with the Cypher.
|
|
12
|
+
|
|
13
|
+
2. NO REDISTRIBUTION: You may NOT redistribute, sublicense, publish, sell,
|
|
14
|
+
or otherwise make available the Software or any derivative works thereof
|
|
15
|
+
to any third party, whether in source code or compiled form, without the
|
|
16
|
+
prior written consent of Cypher.
|
|
17
|
+
|
|
18
|
+
3. NO COMPETING PRODUCTS: You may NOT use the Software or any portion thereof
|
|
19
|
+
to build or operate a prediction market protocol, SDK, or competing
|
|
20
|
+
product that is not built on the Cypher.
|
|
21
|
+
|
|
22
|
+
4. ATTRIBUTION: All copies or substantial portions of the Software used in
|
|
23
|
+
your applications must retain the above copyright notice and this
|
|
24
|
+
permission notice.
|
|
25
|
+
|
|
26
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
27
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
28
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
29
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
30
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
31
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
32
|
+
IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
# Cypher SDK
|
|
2
|
+
|
|
3
|
+
> **TypeScript SDK for the [Cypher](https://cyphers.live) privacy-preserving prediction market on Solana**, powered by [Arcium](https://arcium.com) MPC.
|
|
4
|
+
|
|
5
|
+
[]()
|
|
6
|
+
[]()
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Features
|
|
11
|
+
|
|
12
|
+
- **Full instruction coverage** — builders for all 26 Anchor instructions
|
|
13
|
+
- **High-level action helpers** — encrypt → send → await MPC callback → refetch, in one call
|
|
14
|
+
- **Typed event parsing** — 7 on-chain events decoded and narrowed via discriminated unions
|
|
15
|
+
- **Real-time & poll-based subscriptions** — WebSocket `onLogs` + HTTP fallback
|
|
16
|
+
- **Framework-agnostic core** — works in any TS environment (Node, Deno, Bun, browser)
|
|
17
|
+
- **React hooks layer** — optional `@cypher/sdk/react` with React Query integration
|
|
18
|
+
- **Cluster-aware** — reads `GlobalState.accepted_mint` on-chain (devnet=CSDC, mainnet=USDC)
|
|
19
|
+
- **Deterministic test suite** — 107 unit tests, 581 assertions
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install @cypher-zk/sdk
|
|
25
|
+
# or
|
|
26
|
+
bun add @cypher-zk/sdk
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Peer dependencies
|
|
30
|
+
|
|
31
|
+
| Package | Required for |
|
|
32
|
+
| --- | --- |
|
|
33
|
+
| `react` ^18/^19 | `@cypher-zk/sdk/react` hooks only |
|
|
34
|
+
| `@tanstack/react-query` ^5 | `@cypher-zk/sdk/react` hooks only |
|
|
35
|
+
| `typescript` ^5 | Type checking |
|
|
36
|
+
|
|
37
|
+
## Quick Start
|
|
38
|
+
|
|
39
|
+
### Core SDK
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
import { CypherClient, keypairToWallet } from "@cypher-zk/sdk";
|
|
43
|
+
import { Connection, Keypair } from "@solana/web3.js";
|
|
44
|
+
|
|
45
|
+
const connection = new Connection("https://api.devnet.solana.com");
|
|
46
|
+
const wallet = keypairToWallet(Keypair.generate());
|
|
47
|
+
|
|
48
|
+
const client = new CypherClient({ connection, wallet, cluster: "devnet" });
|
|
49
|
+
|
|
50
|
+
// Fetch protocol state
|
|
51
|
+
const gs = await client.globalState.fetch();
|
|
52
|
+
console.log("Market counter:", gs.marketCounter);
|
|
53
|
+
|
|
54
|
+
// Fetch a specific market
|
|
55
|
+
const market = await client.markets.fetch(0n);
|
|
56
|
+
console.log("Question:", market?.question);
|
|
57
|
+
|
|
58
|
+
// Fetch all active markets
|
|
59
|
+
const active = await client.markets.byState(0); // MarketState.Active
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Place a Private Bet (end-to-end)
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
import { MarketType } from "@cypher-zk/sdk";
|
|
66
|
+
|
|
67
|
+
const result = await client.actions.placeBet({
|
|
68
|
+
payer: wallet.publicKey,
|
|
69
|
+
user: wallet.publicKey,
|
|
70
|
+
marketId: 0n,
|
|
71
|
+
marketType: MarketType.YesNo,
|
|
72
|
+
side: 0, // 0=YES, 1=NO
|
|
73
|
+
amountUsdc: 5_000_000n, // $5 USDC (6 decimals)
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
console.log("Tx:", result.signature);
|
|
77
|
+
console.log("Entry odds:", result.position?.entryOdds);
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Create a Market
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
const result = await client.actions.createMarket({
|
|
84
|
+
creator: wallet.publicKey,
|
|
85
|
+
question: "Will ETH hit $10k by end of 2026?",
|
|
86
|
+
closeTime: BigInt(Math.floor(Date.now() / 1000) + 7 * 24 * 3600),
|
|
87
|
+
category: 0, // Crypto
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
console.log("Market ID:", result.marketId);
|
|
91
|
+
console.log("Market PDA:", result.marketPda.toBase58());
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Subscribe to Events
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
// Real-time (WebSocket)
|
|
98
|
+
const sub = client.events.onBetPlaced((data) => {
|
|
99
|
+
console.log("Bet placed! Odds:", data.entryOdds);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// Later: sub.unsubscribe();
|
|
103
|
+
|
|
104
|
+
// Poll-based (no WS needed)
|
|
105
|
+
const recent = await client.events.pollEvents({ limit: 20 });
|
|
106
|
+
for (const { event } of recent) {
|
|
107
|
+
console.log(event.name, event.data);
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Parse Transaction Logs
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
import { parseLogs } from "@cypher-zk/sdk";
|
|
115
|
+
|
|
116
|
+
const tx = await connection.getTransaction(sig, { commitment: "confirmed" });
|
|
117
|
+
const events = parseLogs(tx.meta?.logMessages ?? []);
|
|
118
|
+
|
|
119
|
+
for (const evt of events) {
|
|
120
|
+
if (evt.name === "MarketResolvedEvent") {
|
|
121
|
+
console.log("Outcome:", evt.data.outcome);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## React Hooks
|
|
127
|
+
|
|
128
|
+
```tsx
|
|
129
|
+
import { CypherProvider, useMarket, usePlaceBet } from "@cypher-zk/sdk/react";
|
|
130
|
+
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
131
|
+
|
|
132
|
+
const queryClient = new QueryClient();
|
|
133
|
+
|
|
134
|
+
function App() {
|
|
135
|
+
return (
|
|
136
|
+
<QueryClientProvider client={queryClient}>
|
|
137
|
+
<CypherProvider client={client}>
|
|
138
|
+
<MarketView />
|
|
139
|
+
</CypherProvider>
|
|
140
|
+
</QueryClientProvider>
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function MarketView() {
|
|
145
|
+
const { data: market, isLoading } = useMarket(0n);
|
|
146
|
+
const { mutateAsync: placeBet, isPending } = usePlaceBet();
|
|
147
|
+
|
|
148
|
+
if (isLoading) return <p>Loading…</p>;
|
|
149
|
+
|
|
150
|
+
return (
|
|
151
|
+
<div>
|
|
152
|
+
<h1>{market?.question}</h1>
|
|
153
|
+
<button
|
|
154
|
+
disabled={isPending}
|
|
155
|
+
onClick={() => placeBet({
|
|
156
|
+
payer: wallet.publicKey,
|
|
157
|
+
user: wallet.publicKey,
|
|
158
|
+
marketId: 0n,
|
|
159
|
+
marketType: 0,
|
|
160
|
+
side: 0,
|
|
161
|
+
amountUsdc: 1_000_000n,
|
|
162
|
+
})}
|
|
163
|
+
>
|
|
164
|
+
Bet YES ($1)
|
|
165
|
+
</button>
|
|
166
|
+
</div>
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Available Hooks
|
|
172
|
+
|
|
173
|
+
| Hook | Type | Description |
|
|
174
|
+
| --- | --- | --- |
|
|
175
|
+
| `useGlobalState()` | Query | Protocol config (fees, mint, admin) |
|
|
176
|
+
| `useMarket(id)` | Query | Single market by ID |
|
|
177
|
+
| `useMarkets(filter?)` | Query | All/filtered markets |
|
|
178
|
+
| `useUserPositions(user)` | Query | User's bet positions |
|
|
179
|
+
| `usePlaceBet()` | Mutation | End-to-end private bet |
|
|
180
|
+
| `useResolveMarket()` | Mutation | Resolve a market |
|
|
181
|
+
| `useClaimPayout()` | Mutation | Claim winning payout |
|
|
182
|
+
| `useClaimRefund()` | Mutation | Claim refund on unresolved market |
|
|
183
|
+
| `useCreateMarket()` | Mutation | Create a new market |
|
|
184
|
+
| `useCancelMarket()` | Mutation | Cancel a zero-bet market |
|
|
185
|
+
| `useMarketEvents()` | Subscription | Live event stream |
|
|
186
|
+
|
|
187
|
+
## Architecture
|
|
188
|
+
|
|
189
|
+
```
|
|
190
|
+
cypher-sdk/
|
|
191
|
+
├── src/ # Framework-agnostic core
|
|
192
|
+
│ ├── config.ts # Program ID, cluster presets, on-chain constants
|
|
193
|
+
│ ├── pda.ts # PDA derivation helpers
|
|
194
|
+
│ ├── wallet.ts # Wallet adapter interface
|
|
195
|
+
│ ├── fees.ts # Fee calculation (mirrors on-chain math)
|
|
196
|
+
│ ├── deadlines.ts # Market lifecycle phase computation
|
|
197
|
+
│ ├── errors.ts # Typed error codes + parsing
|
|
198
|
+
│ ├── client.ts # CypherClient — unified entry point
|
|
199
|
+
│ ├── accounts/ # Account fetchers (GlobalState, Market, Position, LP)
|
|
200
|
+
│ ├── arcium/ # MPC glue (cipher, encoding, queue accounts, offsets)
|
|
201
|
+
│ ├── instructions/ # Raw instruction builders (26 instructions)
|
|
202
|
+
│ ├── actions/ # High-level flows (encrypt → send → callback → refetch)
|
|
203
|
+
│ ├── events/ # Event parser + WebSocket/poll subscriptions
|
|
204
|
+
│ ├── idl/ # Synced Anchor IDL (source of truth)
|
|
205
|
+
│ └── node/ # Node-only admin helpers
|
|
206
|
+
├── react/src/ # Optional React hooks layer
|
|
207
|
+
│ ├── CypherProvider.tsx # Context + provider
|
|
208
|
+
│ ├── useGlobalState.ts # Read hook
|
|
209
|
+
│ ├── useMarket.ts # Read hooks (single + filtered)
|
|
210
|
+
│ ├── useUserPositions.ts # Read hook
|
|
211
|
+
│ ├── mutations.ts # Write hooks (all actions)
|
|
212
|
+
│ └── useMarketEvents.ts # Live event subscription hook
|
|
213
|
+
└── tests/
|
|
214
|
+
├── unit/ # 107 tests, 581 assertions
|
|
215
|
+
├── integration/ # Localnet lifecycle (INTEGRATION=1)
|
|
216
|
+
└── devnet/ # Devnet smoke test (DEVNET=1)
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## Cluster Configuration
|
|
220
|
+
|
|
221
|
+
The SDK is **cluster-agnostic** — it reads `GlobalState.accepted_mint` on-chain at runtime:
|
|
222
|
+
|
|
223
|
+
| Cluster | Accepted Mint | Arcium Cluster Offset |
|
|
224
|
+
| --- | --- | --- |
|
|
225
|
+
| `devnet` | CSDC (`8AF9BABN…`) | `456` |
|
|
226
|
+
| `mainnet` | USDC (`EPjFWdd5…`) | TBD |
|
|
227
|
+
| `localnet` | CSDC (same as devnet) | `1116522022` |
|
|
228
|
+
|
|
229
|
+
Override cluster detection:
|
|
230
|
+
|
|
231
|
+
```ts
|
|
232
|
+
// Explicit preset
|
|
233
|
+
const client = new CypherClient({ connection, wallet, cluster: "devnet" });
|
|
234
|
+
|
|
235
|
+
// Fully custom
|
|
236
|
+
const client = new CypherClient({
|
|
237
|
+
connection, wallet,
|
|
238
|
+
cluster: {
|
|
239
|
+
name: "devnet",
|
|
240
|
+
rpc: "https://my-helius-rpc.com",
|
|
241
|
+
arciumClusterOffset: 456,
|
|
242
|
+
expectedMint: new PublicKey("8AF9BABNWwEhipRxtXPYoWSZW24SKjUn6YqbKd9ZqhwB"),
|
|
243
|
+
},
|
|
244
|
+
});
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## Scripts
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
bun run build # Build dist/ with tsup
|
|
251
|
+
bun run typecheck # Type-check without emitting
|
|
252
|
+
bun run test # All unit tests
|
|
253
|
+
bun run test:unit # Unit tests only
|
|
254
|
+
bun run test:integration # Integration (requires localnet)
|
|
255
|
+
bun run test:devnet # Devnet smoke (requires DEVNET_KEYPAIR)
|
|
256
|
+
bun run sync:idl # Copy IDL from ../cypher-main
|
|
257
|
+
bun run clean # Remove dist/
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
## Security
|
|
261
|
+
|
|
262
|
+
The Cypher protocol has undergone a comprehensive security audit (June 2026). All 9 findings — including 3 critical, 2 high, and 4 medium/low — have been fully remediated and verified in a second-round audit. See `cypher-main/audit_report.md` for the full report.
|
|
263
|
+
|
|
264
|
+
## License
|
|
265
|
+
|
|
266
|
+
Source Available — use is permitted, redistribution is not. See [LICENSE](./LICENSE) for full terms.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
8
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
19
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
20
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
21
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
22
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
23
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
24
|
+
mod
|
|
25
|
+
));
|
|
26
|
+
|
|
27
|
+
export { __commonJS, __toESM };
|
|
28
|
+
//# sourceMappingURL=chunk-5WRI5ZAA.js.map
|
|
29
|
+
//# sourceMappingURL=chunk-5WRI5ZAA.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-5WRI5ZAA.js"}
|