@catalyst-team/poly-sdk 0.2.0 → 0.2.1
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 +1 -1
- package/README.en.md +8 -44
- package/README.md +5 -3
- package/README.zh-CN.md +502 -0
- package/dist/__tests__/clob-api.test.d.ts +5 -0
- package/dist/__tests__/clob-api.test.d.ts.map +1 -0
- package/dist/__tests__/clob-api.test.js +240 -0
- package/dist/__tests__/clob-api.test.js.map +1 -0
- package/dist/__tests__/integration/bridge-client.integration.test.d.ts +11 -0
- package/dist/__tests__/integration/bridge-client.integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration/bridge-client.integration.test.js +260 -0
- package/dist/__tests__/integration/bridge-client.integration.test.js.map +1 -0
- package/dist/__tests__/integration/clob-api.integration.test.d.ts +13 -0
- package/dist/__tests__/integration/clob-api.integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration/clob-api.integration.test.js +170 -0
- package/dist/__tests__/integration/clob-api.integration.test.js.map +1 -0
- package/dist/__tests__/integration/ctf-client.integration.test.d.ts +17 -0
- package/dist/__tests__/integration/ctf-client.integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration/ctf-client.integration.test.js +234 -0
- package/dist/__tests__/integration/ctf-client.integration.test.js.map +1 -0
- package/dist/__tests__/integration/data-api.integration.test.d.ts +9 -0
- package/dist/__tests__/integration/data-api.integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration/data-api.integration.test.js +161 -0
- package/dist/__tests__/integration/data-api.integration.test.js.map +1 -0
- package/dist/__tests__/integration/gamma-api.integration.test.d.ts +9 -0
- package/dist/__tests__/integration/gamma-api.integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration/gamma-api.integration.test.js +170 -0
- package/dist/__tests__/integration/gamma-api.integration.test.js.map +1 -0
- package/dist/__tests__/test-utils.d.ts +92 -0
- package/dist/__tests__/test-utils.d.ts.map +1 -0
- package/dist/__tests__/test-utils.js +143 -0
- package/dist/__tests__/test-utils.js.map +1 -0
- package/dist/clients/bridge-client.d.ts +388 -0
- package/dist/clients/bridge-client.d.ts.map +1 -0
- package/dist/clients/bridge-client.js +587 -0
- package/dist/clients/bridge-client.js.map +1 -0
- package/dist/clients/clob-api.d.ts +318 -0
- package/dist/clients/clob-api.d.ts.map +1 -0
- package/dist/clients/clob-api.js +388 -0
- package/dist/clients/clob-api.js.map +1 -0
- package/dist/clients/ctf-client.d.ts +473 -0
- package/dist/clients/ctf-client.d.ts.map +1 -0
- package/dist/clients/ctf-client.js +915 -0
- package/dist/clients/ctf-client.js.map +1 -0
- package/dist/clients/data-api.d.ts +134 -0
- package/dist/clients/data-api.d.ts.map +1 -0
- package/dist/clients/data-api.js +265 -0
- package/dist/clients/data-api.js.map +1 -0
- package/dist/clients/gamma-api.d.ts +401 -0
- package/dist/clients/gamma-api.d.ts.map +1 -0
- package/dist/clients/gamma-api.js +352 -0
- package/dist/clients/gamma-api.js.map +1 -0
- package/dist/clients/trading-client.d.ts +252 -0
- package/dist/clients/trading-client.d.ts.map +1 -0
- package/dist/clients/trading-client.js +543 -0
- package/dist/clients/trading-client.js.map +1 -0
- package/dist/clients/websocket-manager.d.ts +100 -0
- package/dist/clients/websocket-manager.d.ts.map +1 -0
- package/dist/clients/websocket-manager.js +193 -0
- package/dist/clients/websocket-manager.js.map +1 -0
- package/dist/core/cache-adapter-bridge.d.ts +36 -0
- package/dist/core/cache-adapter-bridge.d.ts.map +1 -0
- package/dist/core/cache-adapter-bridge.js +81 -0
- package/dist/core/cache-adapter-bridge.js.map +1 -0
- package/dist/core/cache.d.ts +40 -0
- package/dist/core/cache.d.ts.map +1 -0
- package/dist/core/cache.js +71 -0
- package/dist/core/cache.js.map +1 -0
- package/dist/core/errors.d.ts +38 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +84 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/rate-limiter.d.ts +31 -0
- package/dist/core/rate-limiter.d.ts.map +1 -0
- package/dist/core/rate-limiter.js +70 -0
- package/dist/core/rate-limiter.js.map +1 -0
- package/{src/core/types.ts → dist/core/types.d.ts} +169 -215
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +19 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/unified-cache.d.ts +63 -0
- package/dist/core/unified-cache.d.ts.map +1 -0
- package/dist/core/unified-cache.js +114 -0
- package/dist/core/unified-cache.js.map +1 -0
- package/dist/index.d.ts +93 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +255 -0
- package/dist/index.js.map +1 -0
- package/dist/services/arbitrage-service.d.ts +408 -0
- package/dist/services/arbitrage-service.d.ts.map +1 -0
- package/dist/services/arbitrage-service.js +1422 -0
- package/dist/services/arbitrage-service.js.map +1 -0
- package/dist/services/authorization-service.d.ts +97 -0
- package/dist/services/authorization-service.d.ts.map +1 -0
- package/dist/services/authorization-service.js +279 -0
- package/dist/services/authorization-service.js.map +1 -0
- package/dist/services/market-service.d.ts +108 -0
- package/dist/services/market-service.d.ts.map +1 -0
- package/dist/services/market-service.js +458 -0
- package/dist/services/market-service.js.map +1 -0
- package/dist/services/realtime-service.d.ts +82 -0
- package/dist/services/realtime-service.d.ts.map +1 -0
- package/dist/services/realtime-service.js +150 -0
- package/dist/services/realtime-service.js.map +1 -0
- package/dist/services/swap-service.d.ts +217 -0
- package/dist/services/swap-service.d.ts.map +1 -0
- package/dist/services/swap-service.js +695 -0
- package/dist/services/swap-service.js.map +1 -0
- package/dist/services/wallet-service.d.ts +94 -0
- package/dist/services/wallet-service.d.ts.map +1 -0
- package/dist/services/wallet-service.js +173 -0
- package/dist/services/wallet-service.js.map +1 -0
- package/dist/utils/price-utils.d.ts +153 -0
- package/dist/utils/price-utils.d.ts.map +1 -0
- package/dist/utils/price-utils.js +236 -0
- package/dist/utils/price-utils.js.map +1 -0
- package/package.json +7 -2
- package/docs/00-design.md +0 -760
- package/docs/02-API.md +0 -1148
- package/docs/arb/test-plan.md +0 -387
- package/docs/arb/test-results.md +0 -336
- package/docs/arbitrage.md +0 -754
- package/docs/reports/smart-money-analysis-2025-12-23-cn.md +0 -840
- package/examples/01-basic-usage.ts +0 -68
- package/examples/02-smart-money.ts +0 -95
- package/examples/03-market-analysis.ts +0 -108
- package/examples/04-kline-aggregation.ts +0 -158
- package/examples/05-follow-wallet-strategy.ts +0 -156
- package/examples/06-services-demo.ts +0 -124
- package/examples/07-realtime-websocket.ts +0 -117
- package/examples/08-trading-orders.ts +0 -278
- package/examples/09-rewards-tracking.ts +0 -187
- package/examples/10-ctf-operations.ts +0 -336
- package/examples/11-live-arbitrage-scan.ts +0 -221
- package/examples/12-trending-arb-monitor.ts +0 -406
- package/examples/13-arbitrage-service.ts +0 -211
- package/examples/README.md +0 -179
- package/scripts/README.md +0 -163
- package/scripts/approvals/approve-erc1155.ts +0 -129
- package/scripts/approvals/approve-neg-risk-erc1155.ts +0 -149
- package/scripts/approvals/approve-neg-risk.ts +0 -102
- package/scripts/approvals/check-all-allowances.ts +0 -150
- package/scripts/approvals/check-allowance.ts +0 -129
- package/scripts/approvals/check-ctf-approval.ts +0 -158
- package/scripts/arb/faze-bo3-arb.ts +0 -385
- package/scripts/arb/settle-position.ts +0 -190
- package/scripts/arb/token-rebalancer.ts +0 -420
- package/scripts/arb-tests/01-unit-tests.ts +0 -495
- package/scripts/arb-tests/02-integration-tests.ts +0 -412
- package/scripts/arb-tests/03-e2e-tests.ts +0 -503
- package/scripts/arb-tests/README.md +0 -109
- package/scripts/datas/001-report.md +0 -486
- package/scripts/datas/clone-modal-screenshot.png +0 -0
- package/scripts/deposit/deposit-native-usdc.ts +0 -179
- package/scripts/deposit/deposit-usdc.ts +0 -155
- package/scripts/deposit/swap-usdc-to-usdce.ts +0 -375
- package/scripts/research/research-markets.ts +0 -166
- package/scripts/trading/check-orders.ts +0 -50
- package/scripts/trading/sell-nvidia-positions.ts +0 -206
- package/scripts/trading/test-order.ts +0 -172
- package/scripts/verify/test-approve-trading.ts +0 -98
- package/scripts/verify/test-provider-fix.ts +0 -43
- package/scripts/verify/test-search-mcp.ts +0 -113
- package/scripts/verify/verify-all-apis.ts +0 -160
- package/scripts/wallet/check-wallet-balances.ts +0 -75
- package/scripts/wallet/test-wallet-operations.ts +0 -191
- package/scripts/wallet/verify-wallet-tools.ts +0 -124
- package/src/__tests__/clob-api.test.ts +0 -301
- package/src/__tests__/integration/bridge-client.integration.test.ts +0 -314
- package/src/__tests__/integration/clob-api.integration.test.ts +0 -218
- package/src/__tests__/integration/ctf-client.integration.test.ts +0 -331
- package/src/__tests__/integration/data-api.integration.test.ts +0 -194
- package/src/__tests__/integration/gamma-api.integration.test.ts +0 -206
- package/src/__tests__/test-utils.ts +0 -170
- package/src/clients/bridge-client.ts +0 -841
- package/src/clients/clob-api.ts +0 -629
- package/src/clients/ctf-client.ts +0 -1216
- package/src/clients/data-api.ts +0 -469
- package/src/clients/gamma-api.ts +0 -597
- package/src/clients/trading-client.ts +0 -749
- package/src/clients/websocket-manager.ts +0 -267
- package/src/core/cache-adapter-bridge.ts +0 -94
- package/src/core/cache.ts +0 -85
- package/src/core/errors.ts +0 -117
- package/src/core/rate-limiter.ts +0 -74
- package/src/core/unified-cache.ts +0 -153
- package/src/index.ts +0 -461
- package/src/services/arbitrage-service.ts +0 -1807
- package/src/services/authorization-service.ts +0 -357
- package/src/services/market-service.ts +0 -544
- package/src/services/realtime-service.ts +0 -196
- package/src/services/swap-service.ts +0 -896
- package/src/services/wallet-service.ts +0 -259
- package/src/utils/price-utils.ts +0 -307
- package/tsconfig.json +0 -8
- package/vitest.config.ts +0 -19
- package/vitest.integration.config.ts +0 -18
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Verify Wallet Tools Implementation
|
|
3
|
-
*
|
|
4
|
-
* This script tests the wallet-related SDK and MCP tools:
|
|
5
|
-
* 1. BridgeClient.getSupportedAssets() - Get supported deposit assets
|
|
6
|
-
* 2. BridgeClient.createDepositAddresses() - Get deposit addresses
|
|
7
|
-
* 3. AuthorizationService.checkAllowances() - Check allowances
|
|
8
|
-
*
|
|
9
|
-
* Usage:
|
|
10
|
-
* npx tsx scripts/verify-wallet-tools.ts
|
|
11
|
-
* POLY_PRIVKEY=0x... npx tsx scripts/verify-wallet-tools.ts
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
import { Wallet, providers } from 'ethers';
|
|
15
|
-
import { BridgeClient, AuthorizationService } from '../src/index.js';
|
|
16
|
-
|
|
17
|
-
const PRIVATE_KEY = process.env.POLY_PRIVKEY || process.env.POLY_PRIVATE_KEY;
|
|
18
|
-
const RPC_URL = 'https://polygon-rpc.com';
|
|
19
|
-
|
|
20
|
-
async function main() {
|
|
21
|
-
console.log('╔════════════════════════════════════════════════════════════╗');
|
|
22
|
-
console.log('║ WALLET TOOLS VERIFICATION ║');
|
|
23
|
-
console.log('╚════════════════════════════════════════════════════════════╝');
|
|
24
|
-
console.log('');
|
|
25
|
-
|
|
26
|
-
// Test 1: Get Supported Assets
|
|
27
|
-
console.log('─── Test 1: BridgeClient.getSupportedAssets() ───');
|
|
28
|
-
try {
|
|
29
|
-
const bridge = new BridgeClient();
|
|
30
|
-
const assets = await bridge.getSupportedAssets();
|
|
31
|
-
console.log(`✅ Found ${assets.length} supported assets`);
|
|
32
|
-
|
|
33
|
-
// Group by chain
|
|
34
|
-
const chains = new Set<string>();
|
|
35
|
-
for (const asset of assets) {
|
|
36
|
-
chains.add(asset.chainName);
|
|
37
|
-
}
|
|
38
|
-
console.log(` Chains: ${Array.from(chains).join(', ')}`);
|
|
39
|
-
|
|
40
|
-
// Show first 3 assets as sample
|
|
41
|
-
console.log(' Sample assets:');
|
|
42
|
-
for (const asset of assets.slice(0, 3)) {
|
|
43
|
-
console.log(` - ${asset.chainName} ${asset.tokenSymbol}: min $${asset.minDepositUsd}`);
|
|
44
|
-
}
|
|
45
|
-
} catch (err) {
|
|
46
|
-
console.log(`❌ Error: ${err instanceof Error ? err.message : err}`);
|
|
47
|
-
}
|
|
48
|
-
console.log('');
|
|
49
|
-
|
|
50
|
-
// Test 2: Get Deposit Addresses (requires address, not private key)
|
|
51
|
-
console.log('─── Test 2: BridgeClient.createDepositAddresses() ───');
|
|
52
|
-
try {
|
|
53
|
-
const bridge = new BridgeClient();
|
|
54
|
-
// Use a test address
|
|
55
|
-
const testAddress = '0xc2e7800b5af46e6093872b177b7a5e7f0563be51';
|
|
56
|
-
const result = await bridge.createDepositAddresses(testAddress);
|
|
57
|
-
console.log(`✅ Got deposit addresses for ${testAddress.slice(0, 10)}...`);
|
|
58
|
-
console.log(` EVM: ${result.address.evm.slice(0, 20)}...`);
|
|
59
|
-
console.log(` Solana: ${result.address.svm.slice(0, 20)}...`);
|
|
60
|
-
console.log(` Bitcoin: ${result.address.btc.slice(0, 20)}...`);
|
|
61
|
-
} catch (err) {
|
|
62
|
-
console.log(`❌ Error: ${err instanceof Error ? err.message : err}`);
|
|
63
|
-
}
|
|
64
|
-
console.log('');
|
|
65
|
-
|
|
66
|
-
// Test 3: Check Allowances (requires private key)
|
|
67
|
-
console.log('─── Test 3: AuthorizationService.checkAllowances() ───');
|
|
68
|
-
if (!PRIVATE_KEY) {
|
|
69
|
-
console.log('⚠️ Skipped: Set POLY_PRIVKEY to test allowance checking');
|
|
70
|
-
} else {
|
|
71
|
-
try {
|
|
72
|
-
const provider = new providers.JsonRpcProvider(RPC_URL);
|
|
73
|
-
const wallet = new Wallet(PRIVATE_KEY, provider);
|
|
74
|
-
console.log(` Wallet: ${wallet.address}`);
|
|
75
|
-
|
|
76
|
-
const authService = new AuthorizationService(wallet);
|
|
77
|
-
const result = await authService.checkAllowances();
|
|
78
|
-
|
|
79
|
-
console.log(`✅ Allowance check completed`);
|
|
80
|
-
console.log(` USDC Balance: ${result.usdcBalance}`);
|
|
81
|
-
console.log(` Trading Ready: ${result.tradingReady ? '✅ Yes' : '❌ No'}`);
|
|
82
|
-
|
|
83
|
-
if (result.issues.length > 0) {
|
|
84
|
-
console.log(' Issues:');
|
|
85
|
-
for (const issue of result.issues) {
|
|
86
|
-
console.log(` - ${issue}`);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
console.log(' ERC20 Allowances:');
|
|
91
|
-
for (const a of result.erc20Allowances) {
|
|
92
|
-
console.log(` - ${a.contract}: ${a.approved ? '✅' : '❌'} (${a.allowance || 'N/A'})`);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
console.log(' ERC1155 Approvals:');
|
|
96
|
-
for (const a of result.erc1155Approvals) {
|
|
97
|
-
console.log(` - ${a.contract}: ${a.approved ? '✅' : '❌'}`);
|
|
98
|
-
}
|
|
99
|
-
} catch (err) {
|
|
100
|
-
console.log(`❌ Error: ${err instanceof Error ? err.message : err}`);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
console.log('');
|
|
104
|
-
|
|
105
|
-
console.log('═══════════════════════════════════════════════════════════');
|
|
106
|
-
console.log('Verification complete.');
|
|
107
|
-
console.log('');
|
|
108
|
-
console.log('Architecture:');
|
|
109
|
-
console.log(' SDK Layer:');
|
|
110
|
-
console.log(' - BridgeClient.getSupportedAssets()');
|
|
111
|
-
console.log(' - BridgeClient.createDepositAddresses()');
|
|
112
|
-
console.log(' - depositUsdc() function');
|
|
113
|
-
console.log(' - AuthorizationService.checkAllowances()');
|
|
114
|
-
console.log(' - AuthorizationService.approveAll()');
|
|
115
|
-
console.log('');
|
|
116
|
-
console.log(' MCP Tools (call SDK):');
|
|
117
|
-
console.log(' - get_supported_deposit_assets → BridgeClient');
|
|
118
|
-
console.log(' - get_deposit_addresses → BridgeClient');
|
|
119
|
-
console.log(' - deposit_usdc → depositUsdc()');
|
|
120
|
-
console.log(' - check_allowances → AuthorizationService');
|
|
121
|
-
console.log(' - approve_trading → AuthorizationService');
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
main().catch(console.error);
|
|
@@ -1,301 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CLOB API Client Unit Tests
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
6
|
-
import { ClobApiClient } from '../clients/clob-api.js';
|
|
7
|
-
import {
|
|
8
|
-
MockRateLimiter,
|
|
9
|
-
MockCache,
|
|
10
|
-
mockClobMarket,
|
|
11
|
-
mockOrderbook,
|
|
12
|
-
mockNoOrderbook,
|
|
13
|
-
expectOrderbookSorted,
|
|
14
|
-
} from './test-utils.js';
|
|
15
|
-
|
|
16
|
-
describe('ClobApiClient', () => {
|
|
17
|
-
let client: ClobApiClient;
|
|
18
|
-
let mockFetch: ReturnType<typeof vi.fn>;
|
|
19
|
-
|
|
20
|
-
beforeEach(() => {
|
|
21
|
-
mockFetch = vi.fn();
|
|
22
|
-
global.fetch = mockFetch;
|
|
23
|
-
client = new ClobApiClient(
|
|
24
|
-
new MockRateLimiter() as never,
|
|
25
|
-
new MockCache() as never
|
|
26
|
-
);
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
afterEach(() => {
|
|
30
|
-
vi.restoreAllMocks();
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
describe('getMarket', () => {
|
|
34
|
-
it('should fetch and normalize market data', async () => {
|
|
35
|
-
mockFetch.mockResolvedValueOnce({
|
|
36
|
-
ok: true,
|
|
37
|
-
json: async () => ({
|
|
38
|
-
condition_id: mockClobMarket.conditionId,
|
|
39
|
-
question: mockClobMarket.question,
|
|
40
|
-
description: mockClobMarket.description,
|
|
41
|
-
market_slug: mockClobMarket.marketSlug,
|
|
42
|
-
tokens: mockClobMarket.tokens.map((t) => ({
|
|
43
|
-
token_id: t.tokenId,
|
|
44
|
-
outcome: t.outcome,
|
|
45
|
-
price: t.price,
|
|
46
|
-
})),
|
|
47
|
-
accepting_orders: true,
|
|
48
|
-
end_date_iso: mockClobMarket.endDateIso,
|
|
49
|
-
active: true,
|
|
50
|
-
closed: false,
|
|
51
|
-
}),
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
const market = await client.getMarket(mockClobMarket.conditionId);
|
|
55
|
-
|
|
56
|
-
expect(market.conditionId).toBe(mockClobMarket.conditionId);
|
|
57
|
-
expect(market.question).toBe(mockClobMarket.question);
|
|
58
|
-
expect(market.tokens).toHaveLength(2);
|
|
59
|
-
expect(market.tokens[0].tokenId).toBe(mockClobMarket.tokens[0].tokenId);
|
|
60
|
-
expect(market.acceptingOrders).toBe(true);
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it('should throw error for non-existent market', async () => {
|
|
64
|
-
mockFetch.mockResolvedValueOnce({
|
|
65
|
-
ok: false,
|
|
66
|
-
status: 404,
|
|
67
|
-
json: async () => ({ error: 'Market not found' }),
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
await expect(client.getMarket('invalid-id')).rejects.toThrow();
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it('should cache market data', async () => {
|
|
74
|
-
mockFetch.mockResolvedValue({
|
|
75
|
-
ok: true,
|
|
76
|
-
json: async () => ({
|
|
77
|
-
condition_id: mockClobMarket.conditionId,
|
|
78
|
-
question: mockClobMarket.question,
|
|
79
|
-
tokens: [],
|
|
80
|
-
accepting_orders: true,
|
|
81
|
-
active: true,
|
|
82
|
-
closed: false,
|
|
83
|
-
}),
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
// First call
|
|
87
|
-
await client.getMarket(mockClobMarket.conditionId);
|
|
88
|
-
// Second call should use cache
|
|
89
|
-
await client.getMarket(mockClobMarket.conditionId);
|
|
90
|
-
|
|
91
|
-
// Should only fetch once due to caching
|
|
92
|
-
expect(mockFetch).toHaveBeenCalledTimes(1);
|
|
93
|
-
});
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
describe('getOrderbook', () => {
|
|
97
|
-
it('should fetch and sort orderbook correctly', async () => {
|
|
98
|
-
// Return unsorted data to test sorting
|
|
99
|
-
mockFetch.mockResolvedValueOnce({
|
|
100
|
-
ok: true,
|
|
101
|
-
json: async () => ({
|
|
102
|
-
bids: [
|
|
103
|
-
{ price: '0.53', size: '750' },
|
|
104
|
-
{ price: '0.55', size: '1000' },
|
|
105
|
-
{ price: '0.54', size: '500' },
|
|
106
|
-
],
|
|
107
|
-
asks: [
|
|
108
|
-
{ price: '0.58', size: '600' },
|
|
109
|
-
{ price: '0.57', size: '800' },
|
|
110
|
-
{ price: '0.59', size: '400' },
|
|
111
|
-
],
|
|
112
|
-
}),
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
const orderbook = await client.getOrderbook('test-token-id');
|
|
116
|
-
|
|
117
|
-
// Check bids are sorted descending
|
|
118
|
-
expect(orderbook.bids[0].price).toBe(0.55);
|
|
119
|
-
expect(orderbook.bids[1].price).toBe(0.54);
|
|
120
|
-
expect(orderbook.bids[2].price).toBe(0.53);
|
|
121
|
-
|
|
122
|
-
// Check asks are sorted ascending
|
|
123
|
-
expect(orderbook.asks[0].price).toBe(0.57);
|
|
124
|
-
expect(orderbook.asks[1].price).toBe(0.58);
|
|
125
|
-
expect(orderbook.asks[2].price).toBe(0.59);
|
|
126
|
-
|
|
127
|
-
expectOrderbookSorted(orderbook);
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
it('should handle empty orderbook', async () => {
|
|
131
|
-
mockFetch.mockResolvedValueOnce({
|
|
132
|
-
ok: true,
|
|
133
|
-
json: async () => ({ bids: [], asks: [] }),
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
const orderbook = await client.getOrderbook('test-token-id');
|
|
137
|
-
|
|
138
|
-
expect(orderbook.bids).toHaveLength(0);
|
|
139
|
-
expect(orderbook.asks).toHaveLength(0);
|
|
140
|
-
expect(orderbook.timestamp).toBeGreaterThan(0);
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
it('should convert string prices to numbers', async () => {
|
|
144
|
-
mockFetch.mockResolvedValueOnce({
|
|
145
|
-
ok: true,
|
|
146
|
-
json: async () => ({
|
|
147
|
-
bids: [{ price: '0.55', size: '1000.5' }],
|
|
148
|
-
asks: [{ price: '0.57', size: '800.25' }],
|
|
149
|
-
}),
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
const orderbook = await client.getOrderbook('test-token-id');
|
|
153
|
-
|
|
154
|
-
expect(typeof orderbook.bids[0].price).toBe('number');
|
|
155
|
-
expect(typeof orderbook.bids[0].size).toBe('number');
|
|
156
|
-
expect(orderbook.bids[0].price).toBe(0.55);
|
|
157
|
-
expect(orderbook.bids[0].size).toBe(1000.5);
|
|
158
|
-
});
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
describe('getProcessedOrderbook', () => {
|
|
162
|
-
it('should calculate effective prices correctly', async () => {
|
|
163
|
-
// First call: getMarket
|
|
164
|
-
mockFetch.mockResolvedValueOnce({
|
|
165
|
-
ok: true,
|
|
166
|
-
json: async () => ({
|
|
167
|
-
condition_id: mockClobMarket.conditionId,
|
|
168
|
-
tokens: [
|
|
169
|
-
{ token_id: 'yes-token', outcome: 'Yes', price: 0.55 },
|
|
170
|
-
{ token_id: 'no-token', outcome: 'No', price: 0.45 },
|
|
171
|
-
],
|
|
172
|
-
accepting_orders: true,
|
|
173
|
-
active: true,
|
|
174
|
-
closed: false,
|
|
175
|
-
}),
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
// Second call: getOrderbook for YES
|
|
179
|
-
mockFetch.mockResolvedValueOnce({
|
|
180
|
-
ok: true,
|
|
181
|
-
json: async () => ({
|
|
182
|
-
bids: [{ price: '0.55', size: '1000' }],
|
|
183
|
-
asks: [{ price: '0.57', size: '800' }],
|
|
184
|
-
}),
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
// Third call: getOrderbook for NO
|
|
188
|
-
mockFetch.mockResolvedValueOnce({
|
|
189
|
-
ok: true,
|
|
190
|
-
json: async () => ({
|
|
191
|
-
bids: [{ price: '0.43', size: '900' }],
|
|
192
|
-
asks: [{ price: '0.45', size: '700' }],
|
|
193
|
-
}),
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
const processed = await client.getProcessedOrderbook(mockClobMarket.conditionId);
|
|
197
|
-
|
|
198
|
-
// Check YES orderbook
|
|
199
|
-
expect(processed.yes.bid).toBe(0.55);
|
|
200
|
-
expect(processed.yes.ask).toBe(0.57);
|
|
201
|
-
|
|
202
|
-
// Check NO orderbook
|
|
203
|
-
expect(processed.no.bid).toBe(0.43);
|
|
204
|
-
expect(processed.no.ask).toBe(0.45);
|
|
205
|
-
|
|
206
|
-
// Check effective prices
|
|
207
|
-
// effectiveBuyYes = min(YES.ask, 1 - NO.bid) = min(0.57, 0.57) = 0.57
|
|
208
|
-
expect(processed.summary.effectivePrices.effectiveBuyYes).toBeCloseTo(0.57, 6);
|
|
209
|
-
// effectiveBuyNo = min(NO.ask, 1 - YES.bid) = min(0.45, 0.45) = 0.45
|
|
210
|
-
expect(processed.summary.effectivePrices.effectiveBuyNo).toBeCloseTo(0.45, 6);
|
|
211
|
-
|
|
212
|
-
// Long cost = effectiveBuyYes + effectiveBuyNo = 0.57 + 0.45 = 1.02
|
|
213
|
-
expect(processed.summary.effectiveLongCost).toBeCloseTo(1.02, 2);
|
|
214
|
-
|
|
215
|
-
// Long arb profit = 1 - longCost = -0.02 (no opportunity)
|
|
216
|
-
expect(processed.summary.longArbProfit).toBeCloseTo(-0.02, 2);
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
it('should detect long arbitrage opportunity', async () => {
|
|
220
|
-
mockFetch.mockResolvedValueOnce({
|
|
221
|
-
ok: true,
|
|
222
|
-
json: async () => ({
|
|
223
|
-
condition_id: mockClobMarket.conditionId,
|
|
224
|
-
tokens: [
|
|
225
|
-
{ token_id: 'yes-token', outcome: 'Yes', price: 0.50 },
|
|
226
|
-
{ token_id: 'no-token', outcome: 'No', price: 0.50 },
|
|
227
|
-
],
|
|
228
|
-
accepting_orders: true,
|
|
229
|
-
active: true,
|
|
230
|
-
closed: false,
|
|
231
|
-
}),
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
// YES orderbook with low ask
|
|
235
|
-
mockFetch.mockResolvedValueOnce({
|
|
236
|
-
ok: true,
|
|
237
|
-
json: async () => ({
|
|
238
|
-
bids: [{ price: '0.48', size: '1000' }],
|
|
239
|
-
asks: [{ price: '0.49', size: '800' }], // Low ask
|
|
240
|
-
}),
|
|
241
|
-
});
|
|
242
|
-
|
|
243
|
-
// NO orderbook with low ask
|
|
244
|
-
mockFetch.mockResolvedValueOnce({
|
|
245
|
-
ok: true,
|
|
246
|
-
json: async () => ({
|
|
247
|
-
bids: [{ price: '0.48', size: '900' }],
|
|
248
|
-
asks: [{ price: '0.49', size: '700' }], // Low ask
|
|
249
|
-
}),
|
|
250
|
-
});
|
|
251
|
-
|
|
252
|
-
const processed = await client.getProcessedOrderbook(mockClobMarket.conditionId);
|
|
253
|
-
|
|
254
|
-
// Long cost = 0.49 + 0.49 = 0.98 < 1.00
|
|
255
|
-
// Long arb profit = 1 - 0.98 = 0.02 (2% opportunity!)
|
|
256
|
-
expect(processed.summary.longArbProfit).toBeGreaterThan(0);
|
|
257
|
-
expect(processed.summary.longArbProfit).toBeCloseTo(0.02, 2);
|
|
258
|
-
});
|
|
259
|
-
|
|
260
|
-
it('should throw error if tokens are missing', async () => {
|
|
261
|
-
mockFetch.mockResolvedValueOnce({
|
|
262
|
-
ok: true,
|
|
263
|
-
json: async () => ({
|
|
264
|
-
condition_id: mockClobMarket.conditionId,
|
|
265
|
-
tokens: [], // No tokens
|
|
266
|
-
accepting_orders: true,
|
|
267
|
-
active: true,
|
|
268
|
-
closed: false,
|
|
269
|
-
}),
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
await expect(
|
|
273
|
-
client.getProcessedOrderbook(mockClobMarket.conditionId)
|
|
274
|
-
).rejects.toThrow('Missing tokens');
|
|
275
|
-
});
|
|
276
|
-
});
|
|
277
|
-
|
|
278
|
-
describe('hasTradingCapabilities', () => {
|
|
279
|
-
it('should return false without config', () => {
|
|
280
|
-
expect(client.hasTradingCapabilities()).toBe(false);
|
|
281
|
-
});
|
|
282
|
-
|
|
283
|
-
it('should return true with signer', () => {
|
|
284
|
-
const clientWithSigner = new ClobApiClient(
|
|
285
|
-
new MockRateLimiter() as never,
|
|
286
|
-
new MockCache() as never,
|
|
287
|
-
{ signer: {} }
|
|
288
|
-
);
|
|
289
|
-
expect(clientWithSigner.hasTradingCapabilities()).toBe(true);
|
|
290
|
-
});
|
|
291
|
-
|
|
292
|
-
it('should return true with credentials', () => {
|
|
293
|
-
const clientWithCreds = new ClobApiClient(
|
|
294
|
-
new MockRateLimiter() as never,
|
|
295
|
-
new MockCache() as never,
|
|
296
|
-
{ creds: { key: 'k', secret: 's', passphrase: 'p' } }
|
|
297
|
-
);
|
|
298
|
-
expect(clientWithCreds.hasTradingCapabilities()).toBe(true);
|
|
299
|
-
});
|
|
300
|
-
});
|
|
301
|
-
});
|