@acta-markets/ts-sdk 0.0.20-beta → 0.0.22-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/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/auth.js +14 -11
- package/dist/cjs/ws/client.js +225 -16
- package/dist/cjs/ws/client.test.js +1 -1
- package/dist/cjs/ws/index.js +1 -0
- package/dist/cjs/ws/referral.js +57 -0
- package/dist/cjs/ws/referral.test.js +55 -0
- 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/auth.d.ts +10 -7
- package/dist/ws/auth.js +14 -11
- package/dist/ws/client.d.ts +76 -4
- package/dist/ws/client.js +225 -16
- package/dist/ws/client.test.js +1 -1
- package/dist/ws/index.d.ts +1 -0
- package/dist/ws/index.js +1 -0
- package/dist/ws/referral.d.ts +53 -0
- package/dist/ws/referral.js +51 -0
- package/dist/ws/referral.test.d.ts +1 -0
- package/dist/ws/referral.test.js +53 -0
- package/dist/ws/types.d.ts +158 -50
- package/package.json +1 -1
|
@@ -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__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;
|
|
10
|
+
exports.ACTA_CONTRACT_ERROR__ORACLE_NOT_EXPIRED_YET = 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");
|
|
@@ -102,6 +102,8 @@ exports.ACTA_CONTRACT_ERROR__ORACLE_HAS_ACTIVE_MARKETS = 0x432; // 1074
|
|
|
102
102
|
exports.ACTA_CONTRACT_ERROR__DUPLICATE_ACCOUNT = 0x433; // 1075
|
|
103
103
|
/** MarketNotExpired: Market has not expired yet */
|
|
104
104
|
exports.ACTA_CONTRACT_ERROR__MARKET_NOT_EXPIRED = 0x434; // 1076
|
|
105
|
+
/** OracleNotExpiredYet: Oracle has not expired yet (cannot update price before expiry) */
|
|
106
|
+
exports.ACTA_CONTRACT_ERROR__ORACLE_NOT_EXPIRED_YET = 0x435; // 1077
|
|
105
107
|
let actaContractErrorMessages;
|
|
106
108
|
if (process.env.NODE_ENV !== "production") {
|
|
107
109
|
actaContractErrorMessages = {
|
|
@@ -138,6 +140,7 @@ if (process.env.NODE_ENV !== "production") {
|
|
|
138
140
|
[exports.ACTA_CONTRACT_ERROR__ORACLE_HAS_ACTIVE_MARKETS]: `Oracle is still linked to active markets`,
|
|
139
141
|
[exports.ACTA_CONTRACT_ERROR__ORACLE_INACTIVE]: `Oracle inactive`,
|
|
140
142
|
[exports.ACTA_CONTRACT_ERROR__ORACLE_INVALID_PRICE]: `Oracle price invalid (zero or negative)`,
|
|
143
|
+
[exports.ACTA_CONTRACT_ERROR__ORACLE_NOT_EXPIRED_YET]: `Oracle has not expired yet (cannot update price before expiry)`,
|
|
141
144
|
[exports.ACTA_CONTRACT_ERROR__ORACLE_SOURCE_LOCKED]: `Oracle source fields are locked after first update`,
|
|
142
145
|
[exports.ACTA_CONTRACT_ERROR__ORACLE_STALE]: `Oracle price is stale (updated_at before expiry)`,
|
|
143
146
|
[exports.ACTA_CONTRACT_ERROR__POSITION_ALREADY_FUNDED]: `Position already funded by maker`,
|
|
@@ -2312,6 +2312,11 @@
|
|
|
2312
2312
|
"code": 1076,
|
|
2313
2313
|
"name": "MarketNotExpired",
|
|
2314
2314
|
"msg": "Market has not expired yet"
|
|
2315
|
+
},
|
|
2316
|
+
{
|
|
2317
|
+
"code": 1077,
|
|
2318
|
+
"name": "OracleNotExpiredYet",
|
|
2319
|
+
"msg": "Oracle has not expired yet (cannot update price before expiry)"
|
|
2315
2320
|
}
|
|
2316
2321
|
]
|
|
2317
2322
|
}
|
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 = "2ccf0a77f682ff60b8201e2bca7f4bd026500a2fb9637d46dad7a8de3b2ee313";
|
package/dist/cjs/ws/auth.js
CHANGED
|
@@ -7,6 +7,9 @@
|
|
|
7
7
|
* - Client signs UTF-8 bytes of that text and responds:
|
|
8
8
|
* `AuthChallenge { challenge, signature: base58(ed25519(utf8(challenge))), pubkey }`
|
|
9
9
|
*
|
|
10
|
+
* The same `signMessage` primitive is reused for any UTF-8-bytes signing
|
|
11
|
+
* (e.g. `acta:redeem:v1:{pubkey}:{code}` for invite redemption).
|
|
12
|
+
*
|
|
10
13
|
* Source of truth (server):
|
|
11
14
|
* - rust-backend/rfq-server/src/server/ws.rs
|
|
12
15
|
* - rust-backend/rfq-server/src/session/handler.rs
|
|
@@ -52,9 +55,9 @@ class KeypairAuthProvider {
|
|
|
52
55
|
async getPublicKey() {
|
|
53
56
|
return this.address;
|
|
54
57
|
}
|
|
55
|
-
async
|
|
56
|
-
const
|
|
57
|
-
const signatureBytes = await (0, keys_1.signBytes)(this.privateKey,
|
|
58
|
+
async signMessage(message) {
|
|
59
|
+
const messageBytes = utf8ToBytes(message);
|
|
60
|
+
const signatureBytes = await (0, keys_1.signBytes)(this.privateKey, messageBytes);
|
|
58
61
|
return bytesToBase58(signatureBytes);
|
|
59
62
|
}
|
|
60
63
|
}
|
|
@@ -76,10 +79,10 @@ class WalletAuthProvider {
|
|
|
76
79
|
throw new Error("Wallet not connected (missing public key)");
|
|
77
80
|
return pk;
|
|
78
81
|
}
|
|
79
|
-
async
|
|
80
|
-
const
|
|
82
|
+
async signMessage(message) {
|
|
83
|
+
const messageBytes = utf8ToBytes(message);
|
|
81
84
|
// Some wallet APIs expect a mutable `Uint8Array`; codecs return `ReadonlyUint8Array`.
|
|
82
|
-
const sig = await this.wallet.signMessage(new Uint8Array(
|
|
85
|
+
const sig = await this.wallet.signMessage(new Uint8Array(messageBytes));
|
|
83
86
|
return bytesToBase58(sig);
|
|
84
87
|
}
|
|
85
88
|
}
|
|
@@ -89,16 +92,16 @@ exports.WalletAuthProvider = WalletAuthProvider;
|
|
|
89
92
|
*/
|
|
90
93
|
class CustomAuthProvider {
|
|
91
94
|
getPublicKeyFn;
|
|
92
|
-
|
|
93
|
-
constructor(getPublicKey,
|
|
95
|
+
signMessageFn;
|
|
96
|
+
constructor(getPublicKey, signMessage) {
|
|
94
97
|
this.getPublicKeyFn = getPublicKey;
|
|
95
|
-
this.
|
|
98
|
+
this.signMessageFn = signMessage;
|
|
96
99
|
}
|
|
97
100
|
async getPublicKey() {
|
|
98
101
|
return this.getPublicKeyFn();
|
|
99
102
|
}
|
|
100
|
-
async
|
|
101
|
-
return this.
|
|
103
|
+
async signMessage(message) {
|
|
104
|
+
return this.signMessageFn(message);
|
|
102
105
|
}
|
|
103
106
|
}
|
|
104
107
|
exports.CustomAuthProvider = CustomAuthProvider;
|
package/dist/cjs/ws/client.js
CHANGED
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
4
4
|
exports.ActaWsClient = void 0;
|
|
5
5
|
const flows_1 = require("./flows");
|
|
6
6
|
const wirePolicy_1 = require("./wirePolicy");
|
|
7
|
+
const referral_1 = require("./referral");
|
|
7
8
|
function toGenericServerError(err) {
|
|
8
9
|
const message = err instanceof Error ? err.message : String(err);
|
|
9
10
|
return { type: "generic", data: { code: "client_error", message } };
|
|
@@ -110,8 +111,8 @@ class ActaWsClient extends TypedEventEmitter {
|
|
|
110
111
|
pingTimer = null;
|
|
111
112
|
shouldReconnect = true;
|
|
112
113
|
subscribedChannels = new Set(["rfqs"]);
|
|
113
|
-
|
|
114
|
-
|
|
114
|
+
underlyingMintScope = null; // null = all
|
|
115
|
+
quoteMintScope = null; // null = all
|
|
115
116
|
marketDescriptorsByMarket = new Map();
|
|
116
117
|
state = {
|
|
117
118
|
stats: null,
|
|
@@ -339,9 +340,118 @@ class ActaWsClient extends TypedEventEmitter {
|
|
|
339
340
|
});
|
|
340
341
|
return requestId;
|
|
341
342
|
}
|
|
343
|
+
/** Maker-only: get balances per deposited token (total, locked, available). */
|
|
344
|
+
getMakerBalances() {
|
|
345
|
+
this.ensureAuthenticated();
|
|
346
|
+
const requestId = this.nextRequestId();
|
|
347
|
+
this.send({
|
|
348
|
+
type: "GetMakerBalances",
|
|
349
|
+
data: { request_id: requestId },
|
|
350
|
+
});
|
|
351
|
+
return requestId;
|
|
352
|
+
}
|
|
353
|
+
/** Maker-only: get open positions with optional filters. */
|
|
354
|
+
getMakerPositions(args) {
|
|
355
|
+
this.ensureAuthenticated();
|
|
356
|
+
const requestId = this.nextRequestId();
|
|
357
|
+
const data = {
|
|
358
|
+
request_id: requestId,
|
|
359
|
+
...args,
|
|
360
|
+
};
|
|
361
|
+
this.send({ type: "GetMakerPositions", data });
|
|
362
|
+
return requestId;
|
|
363
|
+
}
|
|
364
|
+
/** Maker-only: get trade history with keyset pagination. */
|
|
365
|
+
getMyTrades(args) {
|
|
366
|
+
this.ensureAuthenticated();
|
|
367
|
+
const requestId = this.nextRequestId();
|
|
368
|
+
const data = {
|
|
369
|
+
request_id: requestId,
|
|
370
|
+
...args,
|
|
371
|
+
};
|
|
372
|
+
this.send({ type: "GetMyTrades", data });
|
|
373
|
+
return requestId;
|
|
374
|
+
}
|
|
375
|
+
/** Maker-only: get position, notional, and balance caps. */
|
|
376
|
+
getMyCaps() {
|
|
377
|
+
this.ensureAuthenticated();
|
|
378
|
+
const requestId = this.nextRequestId();
|
|
379
|
+
this.send({
|
|
380
|
+
type: "GetMyCaps",
|
|
381
|
+
data: { request_id: requestId },
|
|
382
|
+
});
|
|
383
|
+
return requestId;
|
|
384
|
+
}
|
|
385
|
+
/** Maker-only: get markets where maker has deposits, with optional filters and stats. */
|
|
386
|
+
getMarketsForMaker(args) {
|
|
387
|
+
this.ensureAuthenticated();
|
|
388
|
+
const requestId = this.nextRequestId();
|
|
389
|
+
const data = {
|
|
390
|
+
request_id: requestId,
|
|
391
|
+
...args,
|
|
392
|
+
};
|
|
393
|
+
this.send({ type: "GetMarketsForMaker", data });
|
|
394
|
+
return requestId;
|
|
395
|
+
}
|
|
396
|
+
/** Maker-only: get submitted quotes with status. */
|
|
397
|
+
getMyQuotes(args) {
|
|
398
|
+
this.ensureAuthenticated();
|
|
399
|
+
const requestId = this.nextRequestId();
|
|
400
|
+
const data = {
|
|
401
|
+
request_id: requestId,
|
|
402
|
+
active_only: args?.active_only ?? true,
|
|
403
|
+
};
|
|
404
|
+
this.send({ type: "GetMyQuotes", data });
|
|
405
|
+
return requestId;
|
|
406
|
+
}
|
|
342
407
|
logout() {
|
|
343
408
|
this.send({ type: "Logout" });
|
|
344
409
|
}
|
|
410
|
+
// ========================================================================
|
|
411
|
+
// Referral / invite
|
|
412
|
+
// ========================================================================
|
|
413
|
+
/**
|
|
414
|
+
* Redeem an invite code. Authentication is proven by the session;
|
|
415
|
+
* no additional signature is required. Validation runs client-side —
|
|
416
|
+
* invalid inputs throw `ReferralCodeError` without a round-trip.
|
|
417
|
+
*/
|
|
418
|
+
redeemInvite(rawCode) {
|
|
419
|
+
this.ensureAuthenticated();
|
|
420
|
+
const parsed = (0, referral_1.parseReferralCode)(rawCode);
|
|
421
|
+
if (!parsed.ok)
|
|
422
|
+
throw new referral_1.ReferralCodeError(parsed.error);
|
|
423
|
+
const requestId = this.nextRequestId();
|
|
424
|
+
this.send({
|
|
425
|
+
type: "RedeemInvite",
|
|
426
|
+
data: { request_id: requestId, code: parsed.code },
|
|
427
|
+
});
|
|
428
|
+
return requestId;
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* Claim a vanity referral code (one-shot per taker). Validation
|
|
432
|
+
* runs client-side — invalid inputs throw `ReferralCodeError`.
|
|
433
|
+
*/
|
|
434
|
+
async claimReferralCode(rawCode) {
|
|
435
|
+
this.ensureAuthenticated();
|
|
436
|
+
const parsed = (0, referral_1.parseReferralCode)(rawCode);
|
|
437
|
+
if (!parsed.ok)
|
|
438
|
+
throw new referral_1.ReferralCodeError(parsed.error);
|
|
439
|
+
const requestId = this.nextRequestId();
|
|
440
|
+
this.send({
|
|
441
|
+
type: "ClaimReferralCode",
|
|
442
|
+
data: { request_id: requestId, code: parsed.code },
|
|
443
|
+
});
|
|
444
|
+
return requestId;
|
|
445
|
+
}
|
|
446
|
+
getMyReferralInfo() {
|
|
447
|
+
this.ensureAuthenticated();
|
|
448
|
+
const requestId = this.nextRequestId();
|
|
449
|
+
this.send({
|
|
450
|
+
type: "GetMyReferralInfo",
|
|
451
|
+
data: { request_id: requestId },
|
|
452
|
+
});
|
|
453
|
+
return requestId;
|
|
454
|
+
}
|
|
345
455
|
getOrderStatus(orderIdHex) {
|
|
346
456
|
this.ensureAuthenticated();
|
|
347
457
|
const requestId = this.nextRequestId();
|
|
@@ -395,21 +505,25 @@ class ActaWsClient extends TypedEventEmitter {
|
|
|
395
505
|
});
|
|
396
506
|
return requestId;
|
|
397
507
|
}
|
|
398
|
-
subscribe(channels,
|
|
508
|
+
subscribe(channels, opts) {
|
|
399
509
|
this.ensureAuthenticated();
|
|
400
510
|
const request_id = this.nextRequestId();
|
|
401
511
|
for (const c of channels)
|
|
402
512
|
this.subscribedChannels.add(c);
|
|
403
|
-
if (
|
|
404
|
-
this.
|
|
405
|
-
this.subscribedMarkets = new Set(markets);
|
|
513
|
+
if (opts?.underlying_mints) {
|
|
514
|
+
this.underlyingMintScope = new Set(opts.underlying_mints);
|
|
406
515
|
}
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
516
|
+
if (opts?.quote_mints) {
|
|
517
|
+
this.quoteMintScope = new Set(opts.quote_mints);
|
|
518
|
+
}
|
|
519
|
+
const data = { request_id, channels };
|
|
520
|
+
if (this.underlyingMintScope) {
|
|
521
|
+
data.underlying_mints = Array.from(this.underlyingMintScope);
|
|
522
|
+
}
|
|
523
|
+
if (this.quoteMintScope) {
|
|
524
|
+
data.quote_mints = Array.from(this.quoteMintScope);
|
|
525
|
+
}
|
|
526
|
+
this.send({ type: "Subscribe", data });
|
|
413
527
|
return request_id;
|
|
414
528
|
}
|
|
415
529
|
unsubscribe(channels) {
|
|
@@ -423,6 +537,58 @@ class ActaWsClient extends TypedEventEmitter {
|
|
|
423
537
|
});
|
|
424
538
|
return request_id;
|
|
425
539
|
}
|
|
540
|
+
addMints(opts) {
|
|
541
|
+
this.ensureAuthenticated();
|
|
542
|
+
const request_id = this.nextRequestId();
|
|
543
|
+
if (opts.underlying_mints) {
|
|
544
|
+
if (!this.underlyingMintScope)
|
|
545
|
+
this.underlyingMintScope = new Set();
|
|
546
|
+
for (const m of opts.underlying_mints)
|
|
547
|
+
this.underlyingMintScope.add(m);
|
|
548
|
+
}
|
|
549
|
+
if (opts.quote_mints) {
|
|
550
|
+
if (!this.quoteMintScope)
|
|
551
|
+
this.quoteMintScope = new Set();
|
|
552
|
+
for (const m of opts.quote_mints)
|
|
553
|
+
this.quoteMintScope.add(m);
|
|
554
|
+
}
|
|
555
|
+
this.send({ type: "AddMints", data: { request_id, ...opts } });
|
|
556
|
+
return request_id;
|
|
557
|
+
}
|
|
558
|
+
removeMints(opts) {
|
|
559
|
+
this.ensureAuthenticated();
|
|
560
|
+
const request_id = this.nextRequestId();
|
|
561
|
+
if (opts.underlying_mints && this.underlyingMintScope) {
|
|
562
|
+
for (const m of opts.underlying_mints)
|
|
563
|
+
this.underlyingMintScope.delete(m);
|
|
564
|
+
if (this.underlyingMintScope.size === 0)
|
|
565
|
+
this.underlyingMintScope = null;
|
|
566
|
+
}
|
|
567
|
+
if (opts.quote_mints && this.quoteMintScope) {
|
|
568
|
+
for (const m of opts.quote_mints)
|
|
569
|
+
this.quoteMintScope.delete(m);
|
|
570
|
+
if (this.quoteMintScope.size === 0)
|
|
571
|
+
this.quoteMintScope = null;
|
|
572
|
+
}
|
|
573
|
+
this.send({ type: "RemoveMints", data: { request_id, ...opts } });
|
|
574
|
+
return request_id;
|
|
575
|
+
}
|
|
576
|
+
addChannels(channels) {
|
|
577
|
+
this.ensureAuthenticated();
|
|
578
|
+
const request_id = this.nextRequestId();
|
|
579
|
+
for (const c of channels)
|
|
580
|
+
this.subscribedChannels.add(c);
|
|
581
|
+
this.send({ type: "AddChannels", data: { request_id, channels } });
|
|
582
|
+
return request_id;
|
|
583
|
+
}
|
|
584
|
+
removeChannels(channels) {
|
|
585
|
+
this.ensureAuthenticated();
|
|
586
|
+
const request_id = this.nextRequestId();
|
|
587
|
+
for (const c of channels)
|
|
588
|
+
this.subscribedChannels.delete(c);
|
|
589
|
+
this.send({ type: "RemoveChannels", data: { request_id, channels } });
|
|
590
|
+
return request_id;
|
|
591
|
+
}
|
|
426
592
|
ping() {
|
|
427
593
|
if (this.ws?.readyState === WS_OPEN) {
|
|
428
594
|
this.send({ type: "Ping" });
|
|
@@ -573,6 +739,21 @@ class ActaWsClient extends TypedEventEmitter {
|
|
|
573
739
|
case "MyCaps":
|
|
574
740
|
this.emit("myCaps", message.data);
|
|
575
741
|
break;
|
|
742
|
+
case "MakerBalances":
|
|
743
|
+
this.emit("makerBalances", message.data);
|
|
744
|
+
break;
|
|
745
|
+
case "MakerPositions":
|
|
746
|
+
this.emit("makerPositions", message.data);
|
|
747
|
+
break;
|
|
748
|
+
case "MyTrades":
|
|
749
|
+
this.emit("myTrades", message.data);
|
|
750
|
+
break;
|
|
751
|
+
case "MakerMarkets":
|
|
752
|
+
this.emit("makerMarkets", message.data);
|
|
753
|
+
break;
|
|
754
|
+
case "MyQuotes":
|
|
755
|
+
this.emit("myQuotes", message.data);
|
|
756
|
+
break;
|
|
576
757
|
case "MyActiveRfqs":
|
|
577
758
|
this.handleMyActiveRfqs(message.data);
|
|
578
759
|
break;
|
|
@@ -730,6 +911,30 @@ class ActaWsClient extends TypedEventEmitter {
|
|
|
730
911
|
case "UnsubscribeAck":
|
|
731
912
|
this.emit("unsubscribeAck", message.data);
|
|
732
913
|
break;
|
|
914
|
+
case "SubscriptionUpdated":
|
|
915
|
+
{
|
|
916
|
+
const d = message.data;
|
|
917
|
+
// Sync local state from the server's authoritative response.
|
|
918
|
+
this.subscribedChannels = new Set(d.channels);
|
|
919
|
+
this.underlyingMintScope =
|
|
920
|
+
d.underlying_mints != null ? new Set(d.underlying_mints) : null;
|
|
921
|
+
this.quoteMintScope =
|
|
922
|
+
d.quote_mints != null ? new Set(d.quote_mints) : null;
|
|
923
|
+
this.emit("subscriptionUpdated", d);
|
|
924
|
+
}
|
|
925
|
+
break;
|
|
926
|
+
case "RequireInvite":
|
|
927
|
+
this.emit("requireInvite");
|
|
928
|
+
break;
|
|
929
|
+
case "InviteRedeemed":
|
|
930
|
+
this.emit("inviteRedeemed", message.data);
|
|
931
|
+
break;
|
|
932
|
+
case "ReferralCodeClaimed":
|
|
933
|
+
this.emit("referralCodeClaimed", message.data);
|
|
934
|
+
break;
|
|
935
|
+
case "MyReferralInfo":
|
|
936
|
+
this.emit("myReferralInfo", message.data);
|
|
937
|
+
break;
|
|
733
938
|
}
|
|
734
939
|
}
|
|
735
940
|
/** Taker-only: request current indicative prices for a market + position_type. */
|
|
@@ -755,7 +960,7 @@ class ActaWsClient extends TypedEventEmitter {
|
|
|
755
960
|
try {
|
|
756
961
|
const [pubkey, signature] = await Promise.all([
|
|
757
962
|
this.authProvider.getPublicKey(),
|
|
758
|
-
this.authProvider.
|
|
963
|
+
this.authProvider.signMessage(challenge),
|
|
759
964
|
]);
|
|
760
965
|
this.send({
|
|
761
966
|
type: "AuthChallenge",
|
|
@@ -815,9 +1020,13 @@ class ActaWsClient extends TypedEventEmitter {
|
|
|
815
1020
|
if (this.subscribedChannels.size > 0) {
|
|
816
1021
|
const channels = Array.from(this.subscribedChannels);
|
|
817
1022
|
const request_id = this.nextRequestId();
|
|
818
|
-
const data =
|
|
819
|
-
|
|
820
|
-
|
|
1023
|
+
const data = { request_id, channels };
|
|
1024
|
+
if (this.underlyingMintScope) {
|
|
1025
|
+
data.underlying_mints = Array.from(this.underlyingMintScope);
|
|
1026
|
+
}
|
|
1027
|
+
if (this.quoteMintScope) {
|
|
1028
|
+
data.quote_mints = Array.from(this.quoteMintScope);
|
|
1029
|
+
}
|
|
821
1030
|
this.send({ type: "Subscribe", data });
|
|
822
1031
|
}
|
|
823
1032
|
}
|
|
@@ -53,7 +53,7 @@ function parseClientMessage(payload) {
|
|
|
53
53
|
function makeAuthProvider(pubkey = "pubkey", signature = "signature") {
|
|
54
54
|
return {
|
|
55
55
|
getPublicKey: jest.fn().mockResolvedValue(pubkey),
|
|
56
|
-
|
|
56
|
+
signMessage: jest.fn().mockResolvedValue(signature),
|
|
57
57
|
};
|
|
58
58
|
}
|
|
59
59
|
function makeHarness(overrides = {}) {
|
package/dist/cjs/ws/index.js
CHANGED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Referral / invite redemption helpers.
|
|
4
|
+
*
|
|
5
|
+
* Mirrors the server-side validation defined in
|
|
6
|
+
* rust-backend/acta-types/src/invite.rs (ReferralCode::parse).
|
|
7
|
+
* Client-side validation must stay bit-identical to the server on
|
|
8
|
+
* the same input. A hardcoded fixture table is kept here and on the
|
|
9
|
+
* rust side; if either drifts, the cross-impl test will catch it.
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.ReferralCodeError = exports.REFERRAL_CODE_MAX_LEN = exports.REFERRAL_CODE_MIN_LEN = void 0;
|
|
13
|
+
exports.normalizeReferralCode = normalizeReferralCode;
|
|
14
|
+
exports.parseReferralCode = parseReferralCode;
|
|
15
|
+
exports.REFERRAL_CODE_MIN_LEN = 4;
|
|
16
|
+
exports.REFERRAL_CODE_MAX_LEN = 16;
|
|
17
|
+
class ReferralCodeError extends Error {
|
|
18
|
+
detail;
|
|
19
|
+
constructor(detail) {
|
|
20
|
+
super(detail.kind === "length"
|
|
21
|
+
? `code length must be between ${detail.min} and ${detail.max}`
|
|
22
|
+
: "code must contain only ASCII letters and digits");
|
|
23
|
+
this.detail = detail;
|
|
24
|
+
this.name = "ReferralCodeError";
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.ReferralCodeError = ReferralCodeError;
|
|
28
|
+
/**
|
|
29
|
+
* Trim + ASCII uppercase. No length or charset check. Useful for
|
|
30
|
+
* showing a live preview as the user types.
|
|
31
|
+
*/
|
|
32
|
+
function normalizeReferralCode(input) {
|
|
33
|
+
return input.trim().toUpperCase();
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Parse + validate + normalize a user-supplied referral code.
|
|
37
|
+
* Mirrors `ReferralCode::parse` on the server. A successful result
|
|
38
|
+
* carries the canonical branded `ReferralCode`.
|
|
39
|
+
*/
|
|
40
|
+
function parseReferralCode(input) {
|
|
41
|
+
const normalized = normalizeReferralCode(input);
|
|
42
|
+
if (normalized.length < exports.REFERRAL_CODE_MIN_LEN ||
|
|
43
|
+
normalized.length > exports.REFERRAL_CODE_MAX_LEN) {
|
|
44
|
+
return {
|
|
45
|
+
ok: false,
|
|
46
|
+
error: {
|
|
47
|
+
kind: "length",
|
|
48
|
+
min: exports.REFERRAL_CODE_MIN_LEN,
|
|
49
|
+
max: exports.REFERRAL_CODE_MAX_LEN,
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
if (!/^[A-Z0-9]+$/.test(normalized)) {
|
|
54
|
+
return { ok: false, error: { kind: "charset" } };
|
|
55
|
+
}
|
|
56
|
+
return { ok: true, code: normalized };
|
|
57
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const referral_1 = require("./referral");
|
|
4
|
+
// =============================================================================
|
|
5
|
+
// Cross-impl fixture.
|
|
6
|
+
//
|
|
7
|
+
// Bit-for-bit identical to the fixture in
|
|
8
|
+
// rust-backend/acta-types/src/invite.rs::tests
|
|
9
|
+
// If either side changes, update both.
|
|
10
|
+
// =============================================================================
|
|
11
|
+
const ACCEPT_FIXTURES = [
|
|
12
|
+
["NIKITA", "NIKITA"],
|
|
13
|
+
["nikita", "NIKITA"],
|
|
14
|
+
[" abc1 ", "ABC1"],
|
|
15
|
+
["ABCD", "ABCD"],
|
|
16
|
+
["1234567890ABCDEF", "1234567890ABCDEF"],
|
|
17
|
+
];
|
|
18
|
+
describe("parseReferralCode", () => {
|
|
19
|
+
test.each(ACCEPT_FIXTURES)("accepts %j → %j", (input, expected) => {
|
|
20
|
+
const res = (0, referral_1.parseReferralCode)(input);
|
|
21
|
+
expect(res.ok).toBe(true);
|
|
22
|
+
if (res.ok)
|
|
23
|
+
expect(res.code).toBe(expected);
|
|
24
|
+
});
|
|
25
|
+
test("rejects too short", () => {
|
|
26
|
+
const res = (0, referral_1.parseReferralCode)("abc");
|
|
27
|
+
expect(res.ok).toBe(false);
|
|
28
|
+
if (!res.ok)
|
|
29
|
+
expect(res.error.kind).toBe("length");
|
|
30
|
+
});
|
|
31
|
+
test("rejects too long", () => {
|
|
32
|
+
const res = (0, referral_1.parseReferralCode)("A".repeat(17));
|
|
33
|
+
expect(res.ok).toBe(false);
|
|
34
|
+
if (!res.ok)
|
|
35
|
+
expect(res.error.kind).toBe("length");
|
|
36
|
+
});
|
|
37
|
+
test("rejects non-ascii", () => {
|
|
38
|
+
const res = (0, referral_1.parseReferralCode)("абвгд");
|
|
39
|
+
expect(res.ok).toBe(false);
|
|
40
|
+
// Cyrillic passes length but fails charset.
|
|
41
|
+
if (!res.ok)
|
|
42
|
+
expect(res.error.kind).toBe("charset");
|
|
43
|
+
});
|
|
44
|
+
test("rejects punctuation", () => {
|
|
45
|
+
const res = (0, referral_1.parseReferralCode)("ABC-12");
|
|
46
|
+
expect(res.ok).toBe(false);
|
|
47
|
+
if (!res.ok)
|
|
48
|
+
expect(res.error.kind).toBe("charset");
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
describe("normalizeReferralCode", () => {
|
|
52
|
+
test("trims and uppercases", () => {
|
|
53
|
+
expect((0, referral_1.normalizeReferralCode)(" nikita ")).toBe("NIKITA");
|
|
54
|
+
});
|
|
55
|
+
});
|
|
@@ -96,7 +96,9 @@ export declare const ACTA_CONTRACT_ERROR__ORACLE_HAS_ACTIVE_MARKETS = 1074;
|
|
|
96
96
|
export declare const ACTA_CONTRACT_ERROR__DUPLICATE_ACCOUNT = 1075;
|
|
97
97
|
/** MarketNotExpired: Market has not expired yet */
|
|
98
98
|
export declare const ACTA_CONTRACT_ERROR__MARKET_NOT_EXPIRED = 1076;
|
|
99
|
-
|
|
99
|
+
/** OracleNotExpiredYet: Oracle has not expired yet (cannot update price before expiry) */
|
|
100
|
+
export declare const ACTA_CONTRACT_ERROR__ORACLE_NOT_EXPIRED_YET = 1077;
|
|
101
|
+
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_NOT_EXPIRED_YET | 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;
|
|
100
102
|
export declare function getActaContractErrorMessage(code: ActaContractError): string;
|
|
101
103
|
export declare function isActaContractError<TProgramErrorCode extends ActaContractError>(error: unknown, transactionMessage: {
|
|
102
104
|
instructions: Record<number, {
|
|
@@ -97,6 +97,8 @@ export const ACTA_CONTRACT_ERROR__ORACLE_HAS_ACTIVE_MARKETS = 0x432; // 1074
|
|
|
97
97
|
export const ACTA_CONTRACT_ERROR__DUPLICATE_ACCOUNT = 0x433; // 1075
|
|
98
98
|
/** MarketNotExpired: Market has not expired yet */
|
|
99
99
|
export const ACTA_CONTRACT_ERROR__MARKET_NOT_EXPIRED = 0x434; // 1076
|
|
100
|
+
/** OracleNotExpiredYet: Oracle has not expired yet (cannot update price before expiry) */
|
|
101
|
+
export const ACTA_CONTRACT_ERROR__ORACLE_NOT_EXPIRED_YET = 0x435; // 1077
|
|
100
102
|
let actaContractErrorMessages;
|
|
101
103
|
if (process.env.NODE_ENV !== "production") {
|
|
102
104
|
actaContractErrorMessages = {
|
|
@@ -133,6 +135,7 @@ if (process.env.NODE_ENV !== "production") {
|
|
|
133
135
|
[ACTA_CONTRACT_ERROR__ORACLE_HAS_ACTIVE_MARKETS]: `Oracle is still linked to active markets`,
|
|
134
136
|
[ACTA_CONTRACT_ERROR__ORACLE_INACTIVE]: `Oracle inactive`,
|
|
135
137
|
[ACTA_CONTRACT_ERROR__ORACLE_INVALID_PRICE]: `Oracle price invalid (zero or negative)`,
|
|
138
|
+
[ACTA_CONTRACT_ERROR__ORACLE_NOT_EXPIRED_YET]: `Oracle has not expired yet (cannot update price before expiry)`,
|
|
136
139
|
[ACTA_CONTRACT_ERROR__ORACLE_SOURCE_LOCKED]: `Oracle source fields are locked after first update`,
|
|
137
140
|
[ACTA_CONTRACT_ERROR__ORACLE_STALE]: `Oracle price is stale (updated_at before expiry)`,
|
|
138
141
|
[ACTA_CONTRACT_ERROR__POSITION_ALREADY_FUNDED]: `Position already funded by maker`,
|
|
@@ -2312,6 +2312,11 @@
|
|
|
2312
2312
|
"code": 1076,
|
|
2313
2313
|
"name": "MarketNotExpired",
|
|
2314
2314
|
"msg": "Market has not expired yet"
|
|
2315
|
+
},
|
|
2316
|
+
{
|
|
2317
|
+
"code": 1077,
|
|
2318
|
+
"name": "OracleNotExpiredYet",
|
|
2319
|
+
"msg": "Oracle has not expired yet (cannot update price before expiry)"
|
|
2315
2320
|
}
|
|
2316
2321
|
]
|
|
2317
2322
|
}
|
package/dist/idl/hash.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const ACTA_IDL_SHA256 = "
|
|
1
|
+
export declare const ACTA_IDL_SHA256 = "2ccf0a77f682ff60b8201e2bca7f4bd026500a2fb9637d46dad7a8de3b2ee313";
|
package/dist/idl/hash.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const ACTA_IDL_SHA256 = "
|
|
1
|
+
export const ACTA_IDL_SHA256 = "2ccf0a77f682ff60b8201e2bca7f4bd026500a2fb9637d46dad7a8de3b2ee313";
|
package/dist/ws/auth.d.ts
CHANGED
|
@@ -6,6 +6,9 @@
|
|
|
6
6
|
* - Client signs UTF-8 bytes of that text and responds:
|
|
7
7
|
* `AuthChallenge { challenge, signature: base58(ed25519(utf8(challenge))), pubkey }`
|
|
8
8
|
*
|
|
9
|
+
* The same `signMessage` primitive is reused for any UTF-8-bytes signing
|
|
10
|
+
* (e.g. `acta:redeem:v1:{pubkey}:{code}` for invite redemption).
|
|
11
|
+
*
|
|
9
12
|
* Source of truth (server):
|
|
10
13
|
* - rust-backend/rfq-server/src/server/ws.rs
|
|
11
14
|
* - rust-backend/rfq-server/src/session/handler.rs
|
|
@@ -13,8 +16,8 @@
|
|
|
13
16
|
export interface AuthProvider {
|
|
14
17
|
/** Base58-encoded public key (address). */
|
|
15
18
|
getPublicKey(): Promise<string>;
|
|
16
|
-
/** Base58-encoded ed25519 signature over UTF-8 bytes of the
|
|
17
|
-
|
|
19
|
+
/** Base58-encoded ed25519 signature over UTF-8 bytes of the message. */
|
|
20
|
+
signMessage(message: string): Promise<string>;
|
|
18
21
|
}
|
|
19
22
|
/**
|
|
20
23
|
* Auth provider backed by a `CryptoKeyPair`.
|
|
@@ -31,7 +34,7 @@ export declare class KeypairAuthProvider implements AuthProvider {
|
|
|
31
34
|
/** Create from Solana CLI keypair JSON (array of numbers). */
|
|
32
35
|
static fromJson(json: number[] | string): Promise<KeypairAuthProvider>;
|
|
33
36
|
getPublicKey(): Promise<string>;
|
|
34
|
-
|
|
37
|
+
signMessage(message: string): Promise<string>;
|
|
35
38
|
}
|
|
36
39
|
/**
|
|
37
40
|
* Wallet-like provider (browser wallets, custom signers, etc.)
|
|
@@ -43,7 +46,7 @@ export declare class WalletAuthProvider implements AuthProvider {
|
|
|
43
46
|
private readonly wallet;
|
|
44
47
|
constructor(wallet: WalletLike);
|
|
45
48
|
getPublicKey(): Promise<string>;
|
|
46
|
-
|
|
49
|
+
signMessage(message: string): Promise<string>;
|
|
47
50
|
}
|
|
48
51
|
export type WalletLike = {
|
|
49
52
|
/** Preferred: base58 address string. */
|
|
@@ -60,8 +63,8 @@ export type WalletLike = {
|
|
|
60
63
|
*/
|
|
61
64
|
export declare class CustomAuthProvider implements AuthProvider {
|
|
62
65
|
private readonly getPublicKeyFn;
|
|
63
|
-
private readonly
|
|
64
|
-
constructor(getPublicKey: () => Promise<string>,
|
|
66
|
+
private readonly signMessageFn;
|
|
67
|
+
constructor(getPublicKey: () => Promise<string>, signMessage: (message: string) => Promise<string>);
|
|
65
68
|
getPublicKey(): Promise<string>;
|
|
66
|
-
|
|
69
|
+
signMessage(message: string): Promise<string>;
|
|
67
70
|
}
|