@acta-markets/ts-sdk 0.0.14-beta → 0.0.16-beta
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/README.md +15 -15
- package/dist/cjs/generated/errors/actaContract.js +4 -1
- package/dist/cjs/idl/acta_contract.json +5 -0
- package/dist/cjs/idl/hash.js +1 -1
- package/dist/cjs/ws/client.js +11 -11
- package/dist/cjs/ws/types.js +0 -12
- package/dist/generated/errors/actaContract.d.ts +3 -1
- package/dist/generated/errors/actaContract.js +3 -0
- package/dist/idl/acta_contract.json +5 -0
- package/dist/idl/hash.d.ts +1 -1
- package/dist/idl/hash.js +1 -1
- package/dist/ws/client.d.ts +3 -1
- package/dist/ws/client.js +11 -11
- package/dist/ws/types.d.ts +30 -18
- package/dist/ws/types.js +0 -12
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ Generated by Codama.
|
|
|
8
8
|
|
|
9
9
|
## Package
|
|
10
10
|
|
|
11
|
-
Published package:
|
|
11
|
+
Published package: `@acta-markets/ts-sdk@0.0.6-beta` (ESM-first, CJS fallback)
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
14
|
yarn add @acta-markets/ts-sdk@0.0.6-beta
|
|
@@ -49,7 +49,7 @@ const c2 = new ActaClient({ chain: { rpc, rpcSubscriptions, payer } });
|
|
|
49
49
|
|
|
50
50
|
## Web app quickstart (taker-only)
|
|
51
51
|
|
|
52
|
-
### 1) Connect to WS anonymously, then authenticate on
|
|
52
|
+
### 1) Connect to WS anonymously, then authenticate on "Connect wallet"
|
|
53
53
|
|
|
54
54
|
```ts
|
|
55
55
|
import { ActaClient } from "@acta-markets/ts-sdk";
|
|
@@ -64,7 +64,7 @@ const auth = new WalletAuthProvider({
|
|
|
64
64
|
// No wallet prompt:
|
|
65
65
|
client.ws!.connectAnonymous();
|
|
66
66
|
|
|
67
|
-
// Later, on
|
|
67
|
+
// Later, on "Connect wallet" button:
|
|
68
68
|
await client.ws!.authenticate(auth);
|
|
69
69
|
client.ws!.on("snapshot", (s) => console.log("snapshot", s));
|
|
70
70
|
client.ws!.on("chainEvent", (e) => console.log("chain event", e));
|
|
@@ -72,11 +72,11 @@ client.ws!.on("chainEvent", (e) => console.log("chain event", e));
|
|
|
72
72
|
|
|
73
73
|
#### Auth providers (why there are multiple)
|
|
74
74
|
|
|
75
|
-
-
|
|
76
|
-
-
|
|
77
|
-
-
|
|
78
|
-
-
|
|
79
|
-
-
|
|
75
|
+
- `WalletAuthProvider`: browser wallets (Phantom/Privy/etc.) that support `signMessage`.
|
|
76
|
+
- `KeypairAuthProvider`: Node scripts/CI/bots where you load a local keypair (e.g. from `KEYPAIR_PATH`).
|
|
77
|
+
- `CustomAuthProvider`: advanced integrations (remote signers, hardware wallets, nonstandard wallet APIs).
|
|
78
|
+
- `AuthProvider` (type): shared interface the WS client accepts.
|
|
79
|
+
- `WalletLike` (type): minimal wallet adapter shape (no dependency on wallet-adapter / web3.js types).
|
|
80
80
|
|
|
81
81
|
### Markets + positions without on-chain RPC (WS convenience)
|
|
82
82
|
|
|
@@ -152,7 +152,7 @@ client.ws!.on("message", (m) => {
|
|
|
152
152
|
if (m.type !== "Error") return;
|
|
153
153
|
switch (m.data.code) {
|
|
154
154
|
case "rfq_expired":
|
|
155
|
-
// show
|
|
155
|
+
// show "quotes expired" and offer a "Retry RFQ" button
|
|
156
156
|
break;
|
|
157
157
|
case "quote_expired":
|
|
158
158
|
case "quote_refresh_required":
|
|
@@ -164,7 +164,7 @@ client.ws!.on("message", (m) => {
|
|
|
164
164
|
|
|
165
165
|
### APR/APY (annualized premium yield) from quotes
|
|
166
166
|
|
|
167
|
-
Frontends often want to display a simple
|
|
167
|
+
Frontends often want to display a simple "premium yield" as an annualized percentage.
|
|
168
168
|
Given:
|
|
169
169
|
|
|
170
170
|
- `price` = gross premium per 1 underlying (1e9 scale)
|
|
@@ -188,7 +188,7 @@ import { ws } from "@acta-markets/ts-sdk";
|
|
|
188
188
|
|
|
189
189
|
const secondsToExpiry = rfq.market.expiry_ts - Math.floor(Date.now() / 1000);
|
|
190
190
|
|
|
191
|
-
// Example: if you already render quantity as
|
|
191
|
+
// Example: if you already render quantity as "10 SOL", pass underlyingAmount=10.
|
|
192
192
|
const { apr, apy, premiumNotional } = ws.computeApyFromScaledPrices({
|
|
193
193
|
positionType: "cash_secured_put",
|
|
194
194
|
underlyingAmount: 10,
|
|
@@ -199,7 +199,7 @@ const { apr, apy, premiumNotional } = ws.computeApyFromScaledPrices({
|
|
|
199
199
|
```
|
|
200
200
|
|
|
201
201
|
Note:
|
|
202
|
-
- This is a
|
|
202
|
+
- This is a display metric (premium / collateral annualized), not a promise of "guaranteed yield".
|
|
203
203
|
- For covered calls you also need `spotPrice1e9` (from your own spot feed) to value collateral in quote units.
|
|
204
204
|
|
|
205
205
|
### Chain flow helpers
|
|
@@ -305,9 +305,9 @@ const openIx = await buildOpenPositionIx({
|
|
|
305
305
|
|
|
306
306
|
## OrderId rules (SDK-wide)
|
|
307
307
|
|
|
308
|
-
-
|
|
309
|
-
-
|
|
310
|
-
-
|
|
308
|
+
- Canonical: `orderId` is always 32 bytes (`sha256(preimage182)`), same as the on-chain program expects.
|
|
309
|
+
- In code: use `Uint8Array(32)` everywhere.
|
|
310
|
+
- JSON / WS wire: when `order_id` must be a string, it is 64-char hex (32 bytes). SDK flow helpers handle encoding/decoding for you.
|
|
311
311
|
|
|
312
312
|
## WS order status events
|
|
313
313
|
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* @see https://github.com/codama-idl/codama
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.ACTA_CONTRACT_ERROR__DUPLICATE_ACCOUNT = exports.ACTA_CONTRACT_ERROR__ORACLE_HAS_ACTIVE_MARKETS = exports.ACTA_CONTRACT_ERROR__ORACLE_SOURCE_LOCKED = exports.ACTA_CONTRACT_ERROR__ORACLE_ALREADY_UPDATED = exports.ACTA_CONTRACT_ERROR__ORACLE_CLOSE_TOO_EARLY = exports.ACTA_CONTRACT_ERROR__UNAUTHORIZED = exports.ACTA_CONTRACT_ERROR__INVALID_TIMESTAMP = exports.ACTA_CONTRACT_ERROR__INVALID_PROGRAM_ID = exports.ACTA_CONTRACT_ERROR__INSUFFICIENT_FUNDS = exports.ACTA_CONTRACT_ERROR__MINT_MISMATCH = exports.ACTA_CONTRACT_ERROR__MATH_OVERFLOW = exports.ACTA_CONTRACT_ERROR__INVALID_INSTRUCTION_DATA = exports.ACTA_CONTRACT_ERROR__SIGNED_MESSAGE_MISMATCH = exports.ACTA_CONTRACT_ERROR__SIGNER_MISMATCH = exports.ACTA_CONTRACT_ERROR__INVALID_SIGNATURE_COUNT = exports.ACTA_CONTRACT_ERROR__INVALID_ORDER_ID = exports.ACTA_CONTRACT_ERROR__CANNOT_LIQUIDATE_FUNDED = exports.ACTA_CONTRACT_ERROR__POSITION_TYPE_MISMATCH = exports.ACTA_CONTRACT_ERROR__POSITION_NOT_ITM = exports.ACTA_CONTRACT_ERROR__POSITION_ALREADY_SETTLED = exports.ACTA_CONTRACT_ERROR__POSITION_NOT_FUNDED = exports.ACTA_CONTRACT_ERROR__POSITION_ALREADY_FUNDED = exports.ACTA_CONTRACT_ERROR__POSITION_NOT_OPEN = exports.ACTA_CONTRACT_ERROR__POSITION_ALREADY_OPEN = exports.ACTA_CONTRACT_ERROR__ORACLE_INVALID_PRICE = exports.ACTA_CONTRACT_ERROR__ORACLE_INACTIVE = exports.ACTA_CONTRACT_ERROR__ORACLE_STALE = exports.ACTA_CONTRACT_ERROR__ORACLE_EXPIRY_MISMATCH = exports.ACTA_CONTRACT_ERROR__INVALID_ORACLE_ACCOUNT = exports.ACTA_CONTRACT_ERROR__INVALID_ORACLE_TYPE = exports.ACTA_CONTRACT_ERROR__MARKET_NOT_EMPTY = exports.ACTA_CONTRACT_ERROR__MARKET_EXPIRED = exports.ACTA_CONTRACT_ERROR__MARKET_NOT_FINALIZED = exports.ACTA_CONTRACT_ERROR__MARKET_FINALIZED = exports.ACTA_CONTRACT_ERROR__MAKER_NOT_OWNER = exports.ACTA_CONTRACT_ERROR__MAKER_NOT_REGISTERED = exports.ACTA_CONTRACT_ERROR__MAKER_ALREADY_REGISTERED = exports.ACTA_CONTRACT_ERROR__ACCOUNT_ALREADY_INITIALIZED = exports.ACTA_CONTRACT_ERROR__INVALID_ACCOUNT_DATA = exports.ACTA_CONTRACT_ERROR__INVALID_ACCOUNT_COUNT = exports.ACTA_CONTRACT_ERROR__ACCOUNT_NOT_INITIALIZED = exports.ACTA_CONTRACT_ERROR__INVALID_PDA = exports.ACTA_CONTRACT_ERROR__INVALID_OWNER = exports.ACTA_CONTRACT_ERROR__NOT_SIGNED = void 0;
|
|
10
|
+
exports.ACTA_CONTRACT_ERROR__MARKET_NOT_EXPIRED = exports.ACTA_CONTRACT_ERROR__DUPLICATE_ACCOUNT = exports.ACTA_CONTRACT_ERROR__ORACLE_HAS_ACTIVE_MARKETS = exports.ACTA_CONTRACT_ERROR__ORACLE_SOURCE_LOCKED = exports.ACTA_CONTRACT_ERROR__ORACLE_ALREADY_UPDATED = exports.ACTA_CONTRACT_ERROR__ORACLE_CLOSE_TOO_EARLY = exports.ACTA_CONTRACT_ERROR__UNAUTHORIZED = exports.ACTA_CONTRACT_ERROR__INVALID_TIMESTAMP = exports.ACTA_CONTRACT_ERROR__INVALID_PROGRAM_ID = exports.ACTA_CONTRACT_ERROR__INSUFFICIENT_FUNDS = exports.ACTA_CONTRACT_ERROR__MINT_MISMATCH = exports.ACTA_CONTRACT_ERROR__MATH_OVERFLOW = exports.ACTA_CONTRACT_ERROR__INVALID_INSTRUCTION_DATA = exports.ACTA_CONTRACT_ERROR__SIGNED_MESSAGE_MISMATCH = exports.ACTA_CONTRACT_ERROR__SIGNER_MISMATCH = exports.ACTA_CONTRACT_ERROR__INVALID_SIGNATURE_COUNT = exports.ACTA_CONTRACT_ERROR__INVALID_ORDER_ID = exports.ACTA_CONTRACT_ERROR__CANNOT_LIQUIDATE_FUNDED = exports.ACTA_CONTRACT_ERROR__POSITION_TYPE_MISMATCH = exports.ACTA_CONTRACT_ERROR__POSITION_NOT_ITM = exports.ACTA_CONTRACT_ERROR__POSITION_ALREADY_SETTLED = exports.ACTA_CONTRACT_ERROR__POSITION_NOT_FUNDED = exports.ACTA_CONTRACT_ERROR__POSITION_ALREADY_FUNDED = exports.ACTA_CONTRACT_ERROR__POSITION_NOT_OPEN = exports.ACTA_CONTRACT_ERROR__POSITION_ALREADY_OPEN = exports.ACTA_CONTRACT_ERROR__ORACLE_INVALID_PRICE = exports.ACTA_CONTRACT_ERROR__ORACLE_INACTIVE = exports.ACTA_CONTRACT_ERROR__ORACLE_STALE = exports.ACTA_CONTRACT_ERROR__ORACLE_EXPIRY_MISMATCH = exports.ACTA_CONTRACT_ERROR__INVALID_ORACLE_ACCOUNT = exports.ACTA_CONTRACT_ERROR__INVALID_ORACLE_TYPE = exports.ACTA_CONTRACT_ERROR__MARKET_NOT_EMPTY = exports.ACTA_CONTRACT_ERROR__MARKET_EXPIRED = exports.ACTA_CONTRACT_ERROR__MARKET_NOT_FINALIZED = exports.ACTA_CONTRACT_ERROR__MARKET_FINALIZED = exports.ACTA_CONTRACT_ERROR__MAKER_NOT_OWNER = exports.ACTA_CONTRACT_ERROR__MAKER_NOT_REGISTERED = exports.ACTA_CONTRACT_ERROR__MAKER_ALREADY_REGISTERED = exports.ACTA_CONTRACT_ERROR__ACCOUNT_ALREADY_INITIALIZED = exports.ACTA_CONTRACT_ERROR__INVALID_ACCOUNT_DATA = exports.ACTA_CONTRACT_ERROR__INVALID_ACCOUNT_COUNT = exports.ACTA_CONTRACT_ERROR__ACCOUNT_NOT_INITIALIZED = exports.ACTA_CONTRACT_ERROR__INVALID_PDA = exports.ACTA_CONTRACT_ERROR__INVALID_OWNER = exports.ACTA_CONTRACT_ERROR__NOT_SIGNED = void 0;
|
|
11
11
|
exports.getActaContractErrorMessage = getActaContractErrorMessage;
|
|
12
12
|
exports.isActaContractError = isActaContractError;
|
|
13
13
|
const kit_1 = require("@solana/kit");
|
|
@@ -100,6 +100,8 @@ exports.ACTA_CONTRACT_ERROR__ORACLE_SOURCE_LOCKED = 0x431; // 1073
|
|
|
100
100
|
exports.ACTA_CONTRACT_ERROR__ORACLE_HAS_ACTIVE_MARKETS = 0x432; // 1074
|
|
101
101
|
/** DuplicateAccount: Duplicate account passed to instruction */
|
|
102
102
|
exports.ACTA_CONTRACT_ERROR__DUPLICATE_ACCOUNT = 0x433; // 1075
|
|
103
|
+
/** MarketNotExpired: Market has not expired yet */
|
|
104
|
+
exports.ACTA_CONTRACT_ERROR__MARKET_NOT_EXPIRED = 0x434; // 1076
|
|
103
105
|
let actaContractErrorMessages;
|
|
104
106
|
if (process.env.NODE_ENV !== "production") {
|
|
105
107
|
actaContractErrorMessages = {
|
|
@@ -125,6 +127,7 @@ if (process.env.NODE_ENV !== "production") {
|
|
|
125
127
|
[exports.ACTA_CONTRACT_ERROR__MARKET_EXPIRED]: `Market expired`,
|
|
126
128
|
[exports.ACTA_CONTRACT_ERROR__MARKET_FINALIZED]: `Market already finalized`,
|
|
127
129
|
[exports.ACTA_CONTRACT_ERROR__MARKET_NOT_EMPTY]: `Market has open positions (cannot close)`,
|
|
130
|
+
[exports.ACTA_CONTRACT_ERROR__MARKET_NOT_EXPIRED]: `Market has not expired yet`,
|
|
128
131
|
[exports.ACTA_CONTRACT_ERROR__MARKET_NOT_FINALIZED]: `Market not yet finalized`,
|
|
129
132
|
[exports.ACTA_CONTRACT_ERROR__MATH_OVERFLOW]: `Arithmetic overflow`,
|
|
130
133
|
[exports.ACTA_CONTRACT_ERROR__MINT_MISMATCH]: `Mint mismatch between token accounts`,
|
package/dist/cjs/idl/hash.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ACTA_IDL_SHA256 = void 0;
|
|
4
|
-
exports.ACTA_IDL_SHA256 = "
|
|
4
|
+
exports.ACTA_IDL_SHA256 = "8072bc43541635b8c359d8c0209c3ab63f6a264d6843997d20c9d6c9473130c9";
|
package/dist/cjs/ws/client.js
CHANGED
|
@@ -319,6 +319,14 @@ class ActaWsClient extends TypedEventEmitter {
|
|
|
319
319
|
});
|
|
320
320
|
return requestId;
|
|
321
321
|
}
|
|
322
|
+
getEarnSummary() {
|
|
323
|
+
const requestId = this.nextRequestId();
|
|
324
|
+
this.send({
|
|
325
|
+
type: "GetEarnSummary",
|
|
326
|
+
data: { request_id: requestId },
|
|
327
|
+
});
|
|
328
|
+
return requestId;
|
|
329
|
+
}
|
|
322
330
|
logout() {
|
|
323
331
|
this.send({ type: "Logout" });
|
|
324
332
|
}
|
|
@@ -558,6 +566,9 @@ class ActaWsClient extends TypedEventEmitter {
|
|
|
558
566
|
case "StatsUpdate":
|
|
559
567
|
this.handleStatsUpdate(message.data.stats);
|
|
560
568
|
break;
|
|
569
|
+
case "EarnSummary":
|
|
570
|
+
this.emit("earnSummary", message.data);
|
|
571
|
+
break;
|
|
561
572
|
case "RfqBroadcast":
|
|
562
573
|
// Keep local RFQ state reasonably fresh even without a new snapshot.
|
|
563
574
|
if (!this.state.activeRfqs.has(message.data.rfq_id)) {
|
|
@@ -801,17 +812,6 @@ class ActaWsClient extends TypedEventEmitter {
|
|
|
801
812
|
this.emit("error", new Error(`Authentication failed: ${details}`));
|
|
802
813
|
}
|
|
803
814
|
handleSnapshot(snapshot) {
|
|
804
|
-
this.state.stats = snapshot.stats;
|
|
805
|
-
this.state.activeRfqs.clear();
|
|
806
|
-
for (const rfq of snapshot.active_rfqs) {
|
|
807
|
-
this.state.activeRfqs.set(rfq.rfq_id, rfq);
|
|
808
|
-
}
|
|
809
|
-
this.state.myActiveRfqs.clear();
|
|
810
|
-
this.state.positions.clear();
|
|
811
|
-
for (const position of snapshot.positions ?? []) {
|
|
812
|
-
this.state.positions.set(position.pda, position);
|
|
813
|
-
}
|
|
814
|
-
this.state.recentTrades = snapshot.recent_trades ?? [];
|
|
815
815
|
this.state.markets.clear();
|
|
816
816
|
for (const market of snapshot.markets) {
|
|
817
817
|
this.state.markets.set(market.pda, market);
|
package/dist/cjs/ws/types.js
CHANGED
|
@@ -1,14 +1,2 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* WebSocket protocol types for Acta RFQ server.
|
|
4
|
-
*
|
|
5
|
-
* Source of truth:
|
|
6
|
-
* - docs/state-machines-eng.md (protocol spec)
|
|
7
|
-
* - rust-backend/shared/src/types/ws.rs (as-built reference)
|
|
8
|
-
*
|
|
9
|
-
* Notes:
|
|
10
|
-
* - UUIDs are represented as strings in JSON.
|
|
11
|
-
* - Rust uses u64 in many places; we model them as `number` for now.
|
|
12
|
-
* If/when we need precision beyond JS safe integer, we can migrate to `bigint | string`.
|
|
13
|
-
*/
|
|
14
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -94,7 +94,9 @@ export declare const ACTA_CONTRACT_ERROR__ORACLE_SOURCE_LOCKED = 1073;
|
|
|
94
94
|
export declare const ACTA_CONTRACT_ERROR__ORACLE_HAS_ACTIVE_MARKETS = 1074;
|
|
95
95
|
/** DuplicateAccount: Duplicate account passed to instruction */
|
|
96
96
|
export declare const ACTA_CONTRACT_ERROR__DUPLICATE_ACCOUNT = 1075;
|
|
97
|
-
|
|
97
|
+
/** MarketNotExpired: Market has not expired yet */
|
|
98
|
+
export declare const ACTA_CONTRACT_ERROR__MARKET_NOT_EXPIRED = 1076;
|
|
99
|
+
export type ActaContractError = typeof ACTA_CONTRACT_ERROR__ACCOUNT_ALREADY_INITIALIZED | typeof ACTA_CONTRACT_ERROR__ACCOUNT_NOT_INITIALIZED | typeof ACTA_CONTRACT_ERROR__CANNOT_LIQUIDATE_FUNDED | typeof ACTA_CONTRACT_ERROR__DUPLICATE_ACCOUNT | typeof ACTA_CONTRACT_ERROR__INSUFFICIENT_FUNDS | typeof ACTA_CONTRACT_ERROR__INVALID_ACCOUNT_COUNT | typeof ACTA_CONTRACT_ERROR__INVALID_ACCOUNT_DATA | typeof ACTA_CONTRACT_ERROR__INVALID_INSTRUCTION_DATA | typeof ACTA_CONTRACT_ERROR__INVALID_ORACLE_ACCOUNT | typeof ACTA_CONTRACT_ERROR__INVALID_ORACLE_TYPE | typeof ACTA_CONTRACT_ERROR__INVALID_ORDER_ID | typeof ACTA_CONTRACT_ERROR__INVALID_OWNER | typeof ACTA_CONTRACT_ERROR__INVALID_PDA | typeof ACTA_CONTRACT_ERROR__INVALID_PROGRAM_ID | typeof ACTA_CONTRACT_ERROR__INVALID_SIGNATURE_COUNT | typeof ACTA_CONTRACT_ERROR__INVALID_TIMESTAMP | typeof ACTA_CONTRACT_ERROR__MAKER_ALREADY_REGISTERED | typeof ACTA_CONTRACT_ERROR__MAKER_NOT_OWNER | typeof ACTA_CONTRACT_ERROR__MAKER_NOT_REGISTERED | typeof ACTA_CONTRACT_ERROR__MARKET_EXPIRED | typeof ACTA_CONTRACT_ERROR__MARKET_FINALIZED | typeof ACTA_CONTRACT_ERROR__MARKET_NOT_EMPTY | typeof ACTA_CONTRACT_ERROR__MARKET_NOT_EXPIRED | typeof ACTA_CONTRACT_ERROR__MARKET_NOT_FINALIZED | typeof ACTA_CONTRACT_ERROR__MATH_OVERFLOW | typeof ACTA_CONTRACT_ERROR__MINT_MISMATCH | typeof ACTA_CONTRACT_ERROR__NOT_SIGNED | typeof ACTA_CONTRACT_ERROR__ORACLE_ALREADY_UPDATED | typeof ACTA_CONTRACT_ERROR__ORACLE_CLOSE_TOO_EARLY | typeof ACTA_CONTRACT_ERROR__ORACLE_EXPIRY_MISMATCH | typeof ACTA_CONTRACT_ERROR__ORACLE_HAS_ACTIVE_MARKETS | typeof ACTA_CONTRACT_ERROR__ORACLE_INACTIVE | typeof ACTA_CONTRACT_ERROR__ORACLE_INVALID_PRICE | typeof ACTA_CONTRACT_ERROR__ORACLE_SOURCE_LOCKED | typeof ACTA_CONTRACT_ERROR__ORACLE_STALE | typeof ACTA_CONTRACT_ERROR__POSITION_ALREADY_FUNDED | typeof ACTA_CONTRACT_ERROR__POSITION_ALREADY_OPEN | typeof ACTA_CONTRACT_ERROR__POSITION_ALREADY_SETTLED | typeof ACTA_CONTRACT_ERROR__POSITION_NOT_FUNDED | typeof ACTA_CONTRACT_ERROR__POSITION_NOT_ITM | typeof ACTA_CONTRACT_ERROR__POSITION_NOT_OPEN | typeof ACTA_CONTRACT_ERROR__POSITION_TYPE_MISMATCH | typeof ACTA_CONTRACT_ERROR__SIGNED_MESSAGE_MISMATCH | typeof ACTA_CONTRACT_ERROR__SIGNER_MISMATCH | typeof ACTA_CONTRACT_ERROR__UNAUTHORIZED;
|
|
98
100
|
export declare function getActaContractErrorMessage(code: ActaContractError): string;
|
|
99
101
|
export declare function isActaContractError<TProgramErrorCode extends ActaContractError>(error: unknown, transactionMessage: {
|
|
100
102
|
instructions: Record<number, {
|
|
@@ -95,6 +95,8 @@ export const ACTA_CONTRACT_ERROR__ORACLE_SOURCE_LOCKED = 0x431; // 1073
|
|
|
95
95
|
export const ACTA_CONTRACT_ERROR__ORACLE_HAS_ACTIVE_MARKETS = 0x432; // 1074
|
|
96
96
|
/** DuplicateAccount: Duplicate account passed to instruction */
|
|
97
97
|
export const ACTA_CONTRACT_ERROR__DUPLICATE_ACCOUNT = 0x433; // 1075
|
|
98
|
+
/** MarketNotExpired: Market has not expired yet */
|
|
99
|
+
export const ACTA_CONTRACT_ERROR__MARKET_NOT_EXPIRED = 0x434; // 1076
|
|
98
100
|
let actaContractErrorMessages;
|
|
99
101
|
if (process.env.NODE_ENV !== "production") {
|
|
100
102
|
actaContractErrorMessages = {
|
|
@@ -120,6 +122,7 @@ if (process.env.NODE_ENV !== "production") {
|
|
|
120
122
|
[ACTA_CONTRACT_ERROR__MARKET_EXPIRED]: `Market expired`,
|
|
121
123
|
[ACTA_CONTRACT_ERROR__MARKET_FINALIZED]: `Market already finalized`,
|
|
122
124
|
[ACTA_CONTRACT_ERROR__MARKET_NOT_EMPTY]: `Market has open positions (cannot close)`,
|
|
125
|
+
[ACTA_CONTRACT_ERROR__MARKET_NOT_EXPIRED]: `Market has not expired yet`,
|
|
123
126
|
[ACTA_CONTRACT_ERROR__MARKET_NOT_FINALIZED]: `Market not yet finalized`,
|
|
124
127
|
[ACTA_CONTRACT_ERROR__MATH_OVERFLOW]: `Arithmetic overflow`,
|
|
125
128
|
[ACTA_CONTRACT_ERROR__MINT_MISMATCH]: `Mint mismatch between token accounts`,
|
package/dist/idl/hash.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const ACTA_IDL_SHA256 = "
|
|
1
|
+
export declare const ACTA_IDL_SHA256 = "8072bc43541635b8c359d8c0209c3ab63f6a264d6843997d20c9d6c9473130c9";
|
package/dist/idl/hash.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const ACTA_IDL_SHA256 = "
|
|
1
|
+
export const ACTA_IDL_SHA256 = "8072bc43541635b8c359d8c0209c3ab63f6a264d6843997d20c9d6c9473130c9";
|
package/dist/ws/client.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import type { AuthProvider } from "./auth";
|
|
3
3
|
import type { SignerLike } from "../chain/orders";
|
|
4
4
|
import type { Address } from "@solana/addresses";
|
|
5
|
-
import type { ActiveRfqInfo, ChainEventMessage, GlobalStats, MarketDescriptorInfo, MarketInfo, MyActiveRfqInfo, MyActiveRfqsMessage, OrderStatusMessage, PositionInfo, QuoteAcknowledgedMessage, QuoteBestStatusMessage, QuoteCancelledMessage, QuoteMessage, QuoteRefreshRequestedMessage, QuoteOutbidMessage, QuoteReceivedMessage, QuoteSelectedMessage, QuotesUpdateMessage, RfqBroadcastMessage, RfqClosedMessage, RfqCreatedMessage, RfqSkippedMessage, RfqRequestMessage, RfqAvailableAgainMessage, QuoteExpiredMessage, QuoteFilledMessage, IndicativePricesMessage, IndicativePricesRequestMessage, IndicativePricesResponseMessage, GetIndicativePricesMessage, RequestId, ServerMessage, SnapshotMessage, StatsDelta, SubscriptionsMessage, TokenInfo, TradeInfo, UuidString, VersionMismatchMessage, WelcomeMessage, WsChannel } from "./types";
|
|
5
|
+
import type { ActiveRfqInfo, ChainEventMessage, EarnSummaryData, GlobalStats, MarketDescriptorInfo, MarketInfo, MyActiveRfqInfo, MyActiveRfqsMessage, OrderStatusMessage, PositionInfo, QuoteAcknowledgedMessage, QuoteBestStatusMessage, QuoteCancelledMessage, QuoteMessage, QuoteRefreshRequestedMessage, QuoteOutbidMessage, QuoteReceivedMessage, QuoteSelectedMessage, QuotesUpdateMessage, RfqBroadcastMessage, RfqClosedMessage, RfqCreatedMessage, RfqSkippedMessage, RfqRequestMessage, RfqAvailableAgainMessage, QuoteExpiredMessage, QuoteFilledMessage, IndicativePricesMessage, IndicativePricesRequestMessage, IndicativePricesResponseMessage, GetIndicativePricesMessage, RequestId, ServerMessage, SnapshotMessage, StatsDelta, SubscriptionsMessage, TokenInfo, TradeInfo, UuidString, VersionMismatchMessage, WelcomeMessage, WsChannel } from "./types";
|
|
6
6
|
export type ConnectionState = "disconnected" | "connecting" | "authenticating" | "authenticated" | "error";
|
|
7
7
|
export type ClientRole = "taker" | "maker";
|
|
8
8
|
export type PendingMessagesOverflowPolicy = "drop_oldest" | "drop_newest" | "throw";
|
|
@@ -73,6 +73,7 @@ export type ActaWsClientEvents = {
|
|
|
73
73
|
quotesByUnderlying: Record<string, TokenInfo[]>;
|
|
74
74
|
}) => void;
|
|
75
75
|
statsUpdate: (stats: GlobalStats) => void;
|
|
76
|
+
earnSummary: (data: EarnSummaryData) => void;
|
|
76
77
|
subscriptions: (msg: SubscriptionsMessage) => void;
|
|
77
78
|
activeRfqs: (rfqs: ActiveRfqInfo[]) => void;
|
|
78
79
|
rfqBroadcast: (rfq: RfqBroadcastMessage) => void;
|
|
@@ -217,6 +218,7 @@ export declare class ActaWsClient extends TypedEventEmitter<ActaWsClientEvents>
|
|
|
217
218
|
getTokenCaps(args?: {
|
|
218
219
|
include_markets?: boolean;
|
|
219
220
|
}): RequestId;
|
|
221
|
+
getEarnSummary(): RequestId;
|
|
220
222
|
logout(): void;
|
|
221
223
|
getOrderStatus(orderIdHex: string): RequestId;
|
|
222
224
|
cancelRfq(rfqId: string): RequestId;
|
package/dist/ws/client.js
CHANGED
|
@@ -316,6 +316,14 @@ export class ActaWsClient extends TypedEventEmitter {
|
|
|
316
316
|
});
|
|
317
317
|
return requestId;
|
|
318
318
|
}
|
|
319
|
+
getEarnSummary() {
|
|
320
|
+
const requestId = this.nextRequestId();
|
|
321
|
+
this.send({
|
|
322
|
+
type: "GetEarnSummary",
|
|
323
|
+
data: { request_id: requestId },
|
|
324
|
+
});
|
|
325
|
+
return requestId;
|
|
326
|
+
}
|
|
319
327
|
logout() {
|
|
320
328
|
this.send({ type: "Logout" });
|
|
321
329
|
}
|
|
@@ -555,6 +563,9 @@ export class ActaWsClient extends TypedEventEmitter {
|
|
|
555
563
|
case "StatsUpdate":
|
|
556
564
|
this.handleStatsUpdate(message.data.stats);
|
|
557
565
|
break;
|
|
566
|
+
case "EarnSummary":
|
|
567
|
+
this.emit("earnSummary", message.data);
|
|
568
|
+
break;
|
|
558
569
|
case "RfqBroadcast":
|
|
559
570
|
// Keep local RFQ state reasonably fresh even without a new snapshot.
|
|
560
571
|
if (!this.state.activeRfqs.has(message.data.rfq_id)) {
|
|
@@ -798,17 +809,6 @@ export class ActaWsClient extends TypedEventEmitter {
|
|
|
798
809
|
this.emit("error", new Error(`Authentication failed: ${details}`));
|
|
799
810
|
}
|
|
800
811
|
handleSnapshot(snapshot) {
|
|
801
|
-
this.state.stats = snapshot.stats;
|
|
802
|
-
this.state.activeRfqs.clear();
|
|
803
|
-
for (const rfq of snapshot.active_rfqs) {
|
|
804
|
-
this.state.activeRfqs.set(rfq.rfq_id, rfq);
|
|
805
|
-
}
|
|
806
|
-
this.state.myActiveRfqs.clear();
|
|
807
|
-
this.state.positions.clear();
|
|
808
|
-
for (const position of snapshot.positions ?? []) {
|
|
809
|
-
this.state.positions.set(position.pda, position);
|
|
810
|
-
}
|
|
811
|
-
this.state.recentTrades = snapshot.recent_trades ?? [];
|
|
812
812
|
this.state.markets.clear();
|
|
813
813
|
for (const market of snapshot.markets) {
|
|
814
814
|
this.state.markets.set(market.pda, market);
|
package/dist/ws/types.d.ts
CHANGED
|
@@ -1,15 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* WebSocket protocol types for Acta RFQ server.
|
|
3
|
-
*
|
|
4
|
-
* Source of truth:
|
|
5
|
-
* - docs/state-machines-eng.md (protocol spec)
|
|
6
|
-
* - rust-backend/shared/src/types/ws.rs (as-built reference)
|
|
7
|
-
*
|
|
8
|
-
* Notes:
|
|
9
|
-
* - UUIDs are represented as strings in JSON.
|
|
10
|
-
* - Rust uses u64 in many places; we model them as `number` for now.
|
|
11
|
-
* If/when we need precision beyond JS safe integer, we can migrate to `bigint | string`.
|
|
12
|
-
*/
|
|
13
1
|
import type { Address } from "@solana/addresses";
|
|
14
2
|
export type UuidString = string;
|
|
15
3
|
export type RequestId = string;
|
|
@@ -163,6 +151,9 @@ export type ClientMessage = {
|
|
|
163
151
|
} | {
|
|
164
152
|
type: "GetMyCaps";
|
|
165
153
|
data: GetMyCapsMessage;
|
|
154
|
+
} | {
|
|
155
|
+
type: "GetEarnSummary";
|
|
156
|
+
data: GetEarnSummaryMessage;
|
|
166
157
|
} | {
|
|
167
158
|
type: "GetSubscriptions";
|
|
168
159
|
data: GetSubscriptionsMessage;
|
|
@@ -466,6 +457,9 @@ export type ServerMessage = {
|
|
|
466
457
|
} | {
|
|
467
458
|
type: "StatsUpdate";
|
|
468
459
|
data: StatsUpdateMessage;
|
|
460
|
+
} | {
|
|
461
|
+
type: "EarnSummary";
|
|
462
|
+
data: EarnSummaryData;
|
|
469
463
|
} | {
|
|
470
464
|
type: "RfqSkipped";
|
|
471
465
|
data: RfqSkippedMessage;
|
|
@@ -741,7 +735,7 @@ export type MakerPositionInfo = {
|
|
|
741
735
|
quantity: WsU64;
|
|
742
736
|
price: WsU64;
|
|
743
737
|
/** Net premium amount from on-chain position state (quote token base units). */
|
|
744
|
-
total_premium
|
|
738
|
+
total_premium: WsU64;
|
|
745
739
|
collateral_locked: WsU64;
|
|
746
740
|
created_at: WsU64;
|
|
747
741
|
expiry_ts: WsU64;
|
|
@@ -949,10 +943,6 @@ export type TokensMessage = {
|
|
|
949
943
|
quotes_by_underlying: Record<Address<string>, TokenInfo[]>;
|
|
950
944
|
};
|
|
951
945
|
export type SnapshotMessage = {
|
|
952
|
-
stats: GlobalStats;
|
|
953
|
-
active_rfqs: ActiveRfqInfo[];
|
|
954
|
-
positions?: PositionInfo[];
|
|
955
|
-
recent_trades?: TradeInfo[];
|
|
956
946
|
markets: MarketInfo[];
|
|
957
947
|
};
|
|
958
948
|
export type MyActiveRfqsMessage = {
|
|
@@ -1014,7 +1004,7 @@ export type PositionInfo = {
|
|
|
1014
1004
|
quantity: WsU64;
|
|
1015
1005
|
price: WsU64;
|
|
1016
1006
|
/** Net premium amount from on-chain position state (quote token base units). */
|
|
1017
|
-
total_premium
|
|
1007
|
+
total_premium: WsU64;
|
|
1018
1008
|
created_at: WsU64;
|
|
1019
1009
|
/** Market expiry timestamp (unix seconds), sourced from markets table join. */
|
|
1020
1010
|
expiry_ts: WsU64;
|
|
@@ -1052,6 +1042,28 @@ export type PositionUpdateType = string;
|
|
|
1052
1042
|
export type StatsUpdateMessage = {
|
|
1053
1043
|
stats: GlobalStats;
|
|
1054
1044
|
};
|
|
1045
|
+
export type GetEarnSummaryMessage = {
|
|
1046
|
+
request_id: RequestId;
|
|
1047
|
+
};
|
|
1048
|
+
export type EarnAssetSummary = {
|
|
1049
|
+
underlying_mint: string;
|
|
1050
|
+
underlying_symbol: string;
|
|
1051
|
+
quote_mint: string;
|
|
1052
|
+
quote_symbol: string;
|
|
1053
|
+
position_type: PositionType;
|
|
1054
|
+
min_apr: number | null;
|
|
1055
|
+
max_apr: number | null;
|
|
1056
|
+
cap_filled_pct: number;
|
|
1057
|
+
cap_total: WsU64;
|
|
1058
|
+
cap_used: WsU64;
|
|
1059
|
+
strikes_count: number;
|
|
1060
|
+
nearest_expiry_ts: number;
|
|
1061
|
+
};
|
|
1062
|
+
export type EarnSummaryData = {
|
|
1063
|
+
request_id: RequestId;
|
|
1064
|
+
assets: EarnAssetSummary[];
|
|
1065
|
+
computed_at: number;
|
|
1066
|
+
};
|
|
1055
1067
|
export type StatsDelta = {
|
|
1056
1068
|
volume_added?: WsU64 | null;
|
|
1057
1069
|
trades_added?: WsU32 | null;
|
package/dist/ws/types.js
CHANGED
|
@@ -1,13 +1 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* WebSocket protocol types for Acta RFQ server.
|
|
3
|
-
*
|
|
4
|
-
* Source of truth:
|
|
5
|
-
* - docs/state-machines-eng.md (protocol spec)
|
|
6
|
-
* - rust-backend/shared/src/types/ws.rs (as-built reference)
|
|
7
|
-
*
|
|
8
|
-
* Notes:
|
|
9
|
-
* - UUIDs are represented as strings in JSON.
|
|
10
|
-
* - Rust uses u64 in many places; we model them as `number` for now.
|
|
11
|
-
* If/when we need precision beyond JS safe integer, we can migrate to `bigint | string`.
|
|
12
|
-
*/
|
|
13
1
|
export {};
|