@alpha-arcade/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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Alpha Market
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,367 @@
1
+ # @alpha-market/sdk
2
+
3
+ TypeScript SDK for trading on **Alpha Market** — Algorand prediction markets.
4
+
5
+ Place orders, manage positions, read orderbooks, and build automated trading bots — all directly on-chain.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install @alpha-market/sdk algosdk @algorandfoundation/algokit-utils
11
+ ```
12
+
13
+ `algosdk` and `@algorandfoundation/algokit-utils` are peer dependencies.
14
+
15
+ ## Quick Start
16
+
17
+ ```typescript
18
+ import { AlphaClient } from '@alpha-market/sdk';
19
+ import algosdk from 'algosdk';
20
+
21
+ // 1. Setup clients
22
+ const algodClient = new algosdk.Algodv2('', 'https://mainnet-api.algonode.cloud', 443);
23
+ const indexerClient = new algosdk.Indexer('', 'https://mainnet-idx.algonode.cloud', 443);
24
+
25
+ // 2. Setup signer from mnemonic (or use any TransactionSigner)
26
+ const account = algosdk.mnemonicToSecretKey('your twenty five word mnemonic ...');
27
+ const signer = algosdk.makeBasicAccountTransactionSigner(account);
28
+
29
+ // 3. Initialize the client
30
+ const client = new AlphaClient({
31
+ algodClient,
32
+ indexerClient,
33
+ signer,
34
+ activeAddress: account.addr,
35
+ matcherAppId: 741347297,
36
+ usdcAssetId: 31566704,
37
+ feeAddress: 'YOUR_FEE_ADDRESS',
38
+ apiKey: 'YOUR_API_KEY',
39
+ });
40
+
41
+ // 4. Fetch live markets
42
+ const markets = await client.getMarkets();
43
+ console.log(`Found ${markets.length} live markets`);
44
+
45
+ // 5. Place a limit buy order on the first market
46
+ const market = markets[0];
47
+ const result = await client.createLimitOrder({
48
+ marketAppId: market.marketAppId,
49
+ position: 1, // 1 = Yes
50
+ price: 500_000, // $0.50
51
+ quantity: 1_000_000, // 1 share
52
+ isBuying: true,
53
+ });
54
+
55
+ console.log(`Order created! Escrow app ID: ${result.escrowAppId}`);
56
+ ```
57
+
58
+ ## API Reference
59
+
60
+ ### AlphaClient
61
+
62
+ #### Constructor
63
+
64
+ ```typescript
65
+ new AlphaClient(config: AlphaClientConfig)
66
+ ```
67
+
68
+ | Parameter | Type | Required | Description |
69
+ |-----------|------|----------|-------------|
70
+ | `algodClient` | `algosdk.Algodv2` | Yes | Algorand algod client |
71
+ | `indexerClient` | `algosdk.Indexer` | Yes | Algorand indexer client |
72
+ | `signer` | `TransactionSigner` | Yes | Transaction signer |
73
+ | `activeAddress` | `string` | Yes | Your Algorand address |
74
+ | `matcherAppId` | `number` | Yes | Matcher contract app ID (mainnet: `741347297`) |
75
+ | `usdcAssetId` | `number` | Yes | USDC ASA ID (mainnet: `31566704`) |
76
+ | `feeAddress` | `string` | Yes | Platform fee address |
77
+ | `apiKey` | `string` | Yes | Alpha partners API key (x-api-key header) |
78
+ | `apiBaseUrl` | `string` | No | API base URL (default: `https://partners.alphaarcade.com/api`) |
79
+
80
+ ---
81
+
82
+ ### Trading
83
+
84
+ #### `createLimitOrder(params)`
85
+
86
+ Creates a limit order that sits on the orderbook at your price.
87
+
88
+ ```typescript
89
+ const result = await client.createLimitOrder({
90
+ marketAppId: 123456789,
91
+ position: 1, // 1 = Yes, 0 = No
92
+ price: 500_000, // $0.50 in microunits
93
+ quantity: 2_000_000, // 2 shares in microunits
94
+ isBuying: true,
95
+ });
96
+ // result: { escrowAppId, txIds, confirmedRound }
97
+ ```
98
+
99
+ #### `createMarketOrder(params)`
100
+
101
+ Creates a market order that auto-matches against the orderbook.
102
+
103
+ ```typescript
104
+ const result = await client.createMarketOrder({
105
+ marketAppId: 123456789,
106
+ position: 1,
107
+ price: 550_000, // willing to pay up to $0.55
108
+ quantity: 1_000_000,
109
+ isBuying: true,
110
+ slippage: 50_000, // $0.05 slippage tolerance
111
+ });
112
+ // result: { escrowAppId, matchedQuantity, txIds, confirmedRound }
113
+ ```
114
+
115
+ #### `cancelOrder(params)`
116
+
117
+ Cancels an open order and returns funds to the owner.
118
+
119
+ ```typescript
120
+ const result = await client.cancelOrder({
121
+ marketAppId: 123456789,
122
+ escrowAppId: 987654321,
123
+ orderOwner: 'ALGO_ADDRESS...',
124
+ });
125
+ // result: { success, txIds }
126
+ ```
127
+
128
+ #### `proposeMatch(params)`
129
+
130
+ Manually matches an existing maker order against a taker.
131
+
132
+ ```typescript
133
+ const result = await client.proposeMatch({
134
+ marketAppId: 123456789,
135
+ makerEscrowAppId: 987654321,
136
+ makerAddress: 'MAKER_ALGO_ADDRESS...',
137
+ quantityMatched: 500_000,
138
+ });
139
+ // result: { success, txIds }
140
+ ```
141
+
142
+ ---
143
+
144
+ ### Positions
145
+
146
+ #### `splitShares(params)`
147
+
148
+ Splits USDC into equal YES + NO tokens. 1 USDC = 1 YES + 1 NO.
149
+
150
+ ```typescript
151
+ const result = await client.splitShares({
152
+ marketAppId: 123456789,
153
+ amount: 5_000_000, // $5.00 USDC
154
+ });
155
+ // You now hold 5 YES + 5 NO tokens for this market
156
+ ```
157
+
158
+ #### `mergeShares(params)`
159
+
160
+ Merges equal YES + NO tokens back into USDC.
161
+
162
+ ```typescript
163
+ const result = await client.mergeShares({
164
+ marketAppId: 123456789,
165
+ amount: 3_000_000, // Merge 3 YES + 3 NO = $3.00 USDC
166
+ });
167
+ ```
168
+
169
+ #### `claim(params)`
170
+
171
+ Claims USDC from a resolved market.
172
+
173
+ ```typescript
174
+ const result = await client.claim({
175
+ marketAppId: 123456789,
176
+ assetId: 111222333, // The YES or NO token ASA ID
177
+ });
178
+ ```
179
+
180
+ #### `getPositions(walletAddress?)`
181
+
182
+ Gets all token positions across all markets.
183
+
184
+ ```typescript
185
+ const positions = await client.getPositions();
186
+ for (const pos of positions) {
187
+ console.log(`Market ${pos.marketAppId}: ${pos.yesBalance / 1e6} YES, ${pos.noBalance / 1e6} NO`);
188
+ }
189
+ ```
190
+
191
+ ---
192
+
193
+ ### Orderbook
194
+
195
+ #### `getOrderbook(marketAppId)`
196
+
197
+ Fetches the full on-chain orderbook.
198
+
199
+ ```typescript
200
+ const book = await client.getOrderbook(123456789);
201
+
202
+ console.log('Yes bids:', book.yes.bids.length);
203
+ console.log('Yes asks:', book.yes.asks.length);
204
+ console.log('No bids:', book.no.bids.length);
205
+ console.log('No asks:', book.no.asks.length);
206
+
207
+ // Best yes bid
208
+ if (book.yes.bids.length > 0) {
209
+ const best = book.yes.bids.sort((a, b) => b.price - a.price)[0];
210
+ console.log(`Best Yes bid: $${best.price / 1e6} for ${best.quantity / 1e6} shares`);
211
+ }
212
+ ```
213
+
214
+ #### `getOpenOrders(marketAppId, walletAddress?)`
215
+
216
+ Gets open orders for a wallet on a specific market.
217
+
218
+ ```typescript
219
+ const orders = await client.getOpenOrders(123456789);
220
+ for (const order of orders) {
221
+ const side = order.side === 1 ? 'BUY' : 'SELL';
222
+ const pos = order.position === 1 ? 'YES' : 'NO';
223
+ console.log(`${side} ${pos} @ $${order.price / 1e6} - ${order.quantity / 1e6} shares`);
224
+ }
225
+ ```
226
+
227
+ ---
228
+
229
+ ### Markets
230
+
231
+ #### `getMarkets()`
232
+
233
+ Fetches all live, tradeable markets.
234
+
235
+ ```typescript
236
+ const markets = await client.getMarkets();
237
+ for (const m of markets) {
238
+ console.log(`${m.title} — Yes: ${m.yesProb}%, Vol: $${m.volume}`);
239
+ }
240
+ ```
241
+
242
+ #### `getMarket(marketId)`
243
+
244
+ Fetches a single market by ID.
245
+
246
+ ```typescript
247
+ const market = await client.getMarket('abc123');
248
+ if (market) {
249
+ console.log(market.title, market.marketAppId);
250
+ }
251
+ ```
252
+
253
+ ---
254
+
255
+ ### Utility Functions
256
+
257
+ These are exported for advanced users:
258
+
259
+ ```typescript
260
+ import { calculateFee, calculateMatchingOrders, getMarketGlobalState } from '@alpha-market/sdk';
261
+
262
+ // Fee calculation
263
+ const fee = calculateFee(1_000_000, 500_000, 70_000); // quantity, price, feeBase
264
+
265
+ // Read market state directly
266
+ const state = await getMarketGlobalState(algodClient, marketAppId);
267
+ ```
268
+
269
+ ---
270
+
271
+ ## Units & Conventions
272
+
273
+ | Concept | Unit | Example |
274
+ |---------|------|---------|
275
+ | Prices | Microunits (1M = $1.00) | `500_000` = $0.50 |
276
+ | Quantities | Microunits (1M = 1 share) | `2_000_000` = 2 shares |
277
+ | Position | `1` = Yes, `0` = No | `position: 1` |
278
+ | Side | `1` = Buy, `0` = Sell | Order side |
279
+ | Fee base | Microunits | `70_000` = 7% |
280
+
281
+ ---
282
+
283
+ ## Building a Trading Bot
284
+
285
+ ```typescript
286
+ import { AlphaClient } from '@alpha-market/sdk';
287
+ import algosdk from 'algosdk';
288
+
289
+ const setup = () => {
290
+ const algodClient = new algosdk.Algodv2('', 'https://mainnet-api.algonode.cloud', 443);
291
+ const indexerClient = new algosdk.Indexer('', 'https://mainnet-idx.algonode.cloud', 443);
292
+ const account = algosdk.mnemonicToSecretKey(process.env.MNEMONIC!);
293
+
294
+ return new AlphaClient({
295
+ algodClient,
296
+ indexerClient,
297
+ signer: algosdk.makeBasicAccountTransactionSigner(account),
298
+ activeAddress: account.addr,
299
+ matcherAppId: 741347297,
300
+ usdcAssetId: 31566704,
301
+ feeAddress: 'YOUR_FEE_ADDRESS',
302
+ apiKey: 'YOUR_API_KEY',
303
+ });
304
+ };
305
+
306
+ const run = async () => {
307
+ const client = setup();
308
+ const markets = await client.getMarkets();
309
+
310
+ for (const market of markets) {
311
+ const book = await client.getOrderbook(market.marketAppId);
312
+
313
+ // Simple strategy: buy Yes if best ask < $0.30
314
+ const bestAsk = book.yes.asks.sort((a, b) => a.price - b.price)[0];
315
+ if (bestAsk && bestAsk.price < 300_000) {
316
+ console.log(`Buying Yes on "${market.title}" at $${bestAsk.price / 1e6}`);
317
+
318
+ await client.createMarketOrder({
319
+ marketAppId: market.marketAppId,
320
+ position: 1,
321
+ price: bestAsk.price,
322
+ quantity: 1_000_000,
323
+ isBuying: true,
324
+ slippage: 20_000, // $0.02 slippage
325
+ });
326
+ }
327
+ }
328
+ };
329
+
330
+ run().catch(console.error);
331
+ ```
332
+
333
+ ## Network Configuration
334
+
335
+ ### Mainnet (default)
336
+
337
+ ```typescript
338
+ const algodClient = new algosdk.Algodv2('', 'https://mainnet-api.algonode.cloud', 443);
339
+ const indexerClient = new algosdk.Indexer('', 'https://mainnet-idx.algonode.cloud', 443);
340
+ ```
341
+
342
+ ### Testnet
343
+
344
+ ```typescript
345
+ const algodClient = new algosdk.Algodv2('', 'https://testnet-api.algonode.cloud', 443);
346
+ const indexerClient = new algosdk.Indexer('', 'https://testnet-idx.algonode.cloud', 443);
347
+ ```
348
+
349
+ ## Error Handling
350
+
351
+ All methods throw on failure. Wrap calls in try/catch:
352
+
353
+ ```typescript
354
+ try {
355
+ const result = await client.createLimitOrder({ ... });
356
+ } catch (error) {
357
+ if (error.message.includes('balance')) {
358
+ console.error('Insufficient funds');
359
+ } else {
360
+ console.error('Order failed:', error.message);
361
+ }
362
+ }
363
+ ```
364
+
365
+ ## License
366
+
367
+ MIT