@shuffle-protocol/sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +119 -0
- package/dist/cli/commands.d.ts +54 -0
- package/dist/cli/commands.js +1229 -0
- package/dist/cli/config.d.ts +50 -0
- package/dist/cli/config.js +247 -0
- package/dist/cli/devnet.d.ts +81 -0
- package/dist/cli/devnet.js +106 -0
- package/dist/cli/index.d.ts +8 -0
- package/dist/cli/index.js +155 -0
- package/dist/cli/output.d.ts +102 -0
- package/dist/cli/output.js +251 -0
- package/dist/client.d.ts +121 -0
- package/dist/client.js +691 -0
- package/dist/constants.d.ts +30 -0
- package/dist/constants.js +61 -0
- package/dist/encryption.d.ts +24 -0
- package/dist/encryption.js +90 -0
- package/dist/errors.d.ts +12 -0
- package/dist/errors.js +45 -0
- package/dist/idl/shuffle_protocol.json +6333 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +42 -0
- package/dist/pda.d.ts +7 -0
- package/dist/pda.js +59 -0
- package/dist/types.d.ts +83 -0
- package/dist/types.js +7 -0
- package/package.json +58 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { PublicKey } from "@solana/web3.js";
|
|
2
|
+
export declare const PROGRAM_ID: PublicKey;
|
|
3
|
+
export declare enum AssetId {
|
|
4
|
+
USDC = 0,
|
|
5
|
+
TSLA = 1,
|
|
6
|
+
SPY = 2,
|
|
7
|
+
AAPL = 3
|
|
8
|
+
}
|
|
9
|
+
export declare enum PairId {
|
|
10
|
+
TSLA_USDC = 0,
|
|
11
|
+
SPY_USDC = 1,
|
|
12
|
+
AAPL_USDC = 2,
|
|
13
|
+
TSLA_SPY = 3,
|
|
14
|
+
TSLA_AAPL = 4,
|
|
15
|
+
SPY_AAPL = 5
|
|
16
|
+
}
|
|
17
|
+
export declare enum Direction {
|
|
18
|
+
AtoB = 0,
|
|
19
|
+
BtoA = 1
|
|
20
|
+
}
|
|
21
|
+
export declare const NUM_PAIRS = 6;
|
|
22
|
+
export declare const NUM_ASSETS = 4;
|
|
23
|
+
export declare const POOL_SEED = "pool";
|
|
24
|
+
export declare const USER_SEED = "user";
|
|
25
|
+
export declare const BATCH_ACCUMULATOR_SEED = "batch_accumulator";
|
|
26
|
+
export declare const BATCH_LOG_SEED = "batch_log";
|
|
27
|
+
export declare const VAULT_SEED = "vault";
|
|
28
|
+
export declare const VAULT_ASSET_SEEDS: Record<AssetId, string>;
|
|
29
|
+
export declare const ASSET_LABELS: Record<AssetId, string>;
|
|
30
|
+
export declare const PAIR_TOKENS: Record<PairId, [AssetId, AssetId]>;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PAIR_TOKENS = exports.ASSET_LABELS = exports.VAULT_ASSET_SEEDS = exports.VAULT_SEED = exports.BATCH_LOG_SEED = exports.BATCH_ACCUMULATOR_SEED = exports.USER_SEED = exports.POOL_SEED = exports.NUM_ASSETS = exports.NUM_PAIRS = exports.Direction = exports.PairId = exports.AssetId = exports.PROGRAM_ID = void 0;
|
|
4
|
+
const web3_js_1 = require("@solana/web3.js");
|
|
5
|
+
// Program ID (localnet default from Anchor.toml)
|
|
6
|
+
exports.PROGRAM_ID = new web3_js_1.PublicKey("BzaakuSahkVtEXKqZnD9tSPBoiJCMLa1nzQHUjtY1xRM");
|
|
7
|
+
// Asset IDs matching contract/programs/shuffle_protocol/src/constants.rs
|
|
8
|
+
var AssetId;
|
|
9
|
+
(function (AssetId) {
|
|
10
|
+
AssetId[AssetId["USDC"] = 0] = "USDC";
|
|
11
|
+
AssetId[AssetId["TSLA"] = 1] = "TSLA";
|
|
12
|
+
AssetId[AssetId["SPY"] = 2] = "SPY";
|
|
13
|
+
AssetId[AssetId["AAPL"] = 3] = "AAPL";
|
|
14
|
+
})(AssetId || (exports.AssetId = AssetId = {}));
|
|
15
|
+
// Pair IDs for the 6 trading pairs (4 choose 2)
|
|
16
|
+
var PairId;
|
|
17
|
+
(function (PairId) {
|
|
18
|
+
PairId[PairId["TSLA_USDC"] = 0] = "TSLA_USDC";
|
|
19
|
+
PairId[PairId["SPY_USDC"] = 1] = "SPY_USDC";
|
|
20
|
+
PairId[PairId["AAPL_USDC"] = 2] = "AAPL_USDC";
|
|
21
|
+
PairId[PairId["TSLA_SPY"] = 3] = "TSLA_SPY";
|
|
22
|
+
PairId[PairId["TSLA_AAPL"] = 4] = "TSLA_AAPL";
|
|
23
|
+
PairId[PairId["SPY_AAPL"] = 5] = "SPY_AAPL";
|
|
24
|
+
})(PairId || (exports.PairId = PairId = {}));
|
|
25
|
+
// Order direction
|
|
26
|
+
var Direction;
|
|
27
|
+
(function (Direction) {
|
|
28
|
+
Direction[Direction["AtoB"] = 0] = "AtoB";
|
|
29
|
+
Direction[Direction["BtoA"] = 1] = "BtoA";
|
|
30
|
+
})(Direction || (exports.Direction = Direction = {}));
|
|
31
|
+
exports.NUM_PAIRS = 6;
|
|
32
|
+
exports.NUM_ASSETS = 4;
|
|
33
|
+
// PDA seeds (must match Rust constants)
|
|
34
|
+
exports.POOL_SEED = "pool";
|
|
35
|
+
exports.USER_SEED = "user";
|
|
36
|
+
exports.BATCH_ACCUMULATOR_SEED = "batch_accumulator";
|
|
37
|
+
exports.BATCH_LOG_SEED = "batch_log";
|
|
38
|
+
exports.VAULT_SEED = "vault";
|
|
39
|
+
// Per-asset vault sub-seeds
|
|
40
|
+
exports.VAULT_ASSET_SEEDS = {
|
|
41
|
+
[AssetId.USDC]: "usdc",
|
|
42
|
+
[AssetId.TSLA]: "tsla",
|
|
43
|
+
[AssetId.SPY]: "spy",
|
|
44
|
+
[AssetId.AAPL]: "aapl",
|
|
45
|
+
};
|
|
46
|
+
// Asset labels for display
|
|
47
|
+
exports.ASSET_LABELS = {
|
|
48
|
+
[AssetId.USDC]: "USDC",
|
|
49
|
+
[AssetId.TSLA]: "TSLA",
|
|
50
|
+
[AssetId.SPY]: "SPY",
|
|
51
|
+
[AssetId.AAPL]: "AAPL",
|
|
52
|
+
};
|
|
53
|
+
// Pair token mapping: pairId -> [baseAsset, quoteAsset]
|
|
54
|
+
exports.PAIR_TOKENS = {
|
|
55
|
+
[PairId.TSLA_USDC]: [AssetId.TSLA, AssetId.USDC],
|
|
56
|
+
[PairId.SPY_USDC]: [AssetId.SPY, AssetId.USDC],
|
|
57
|
+
[PairId.AAPL_USDC]: [AssetId.AAPL, AssetId.USDC],
|
|
58
|
+
[PairId.TSLA_SPY]: [AssetId.TSLA, AssetId.SPY],
|
|
59
|
+
[PairId.TSLA_AAPL]: [AssetId.TSLA, AssetId.AAPL],
|
|
60
|
+
[PairId.SPY_AAPL]: [AssetId.SPY, AssetId.AAPL],
|
|
61
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { RescueCipher, deserializeLE } from "@arcium-hq/client";
|
|
2
|
+
import * as anchor from "@coral-xyz/anchor";
|
|
3
|
+
import { PublicKey } from "@solana/web3.js";
|
|
4
|
+
export { RescueCipher, deserializeLE };
|
|
5
|
+
export interface EncryptionKeypair {
|
|
6
|
+
privateKey: Uint8Array;
|
|
7
|
+
publicKey: Uint8Array;
|
|
8
|
+
}
|
|
9
|
+
export interface EncryptedValue {
|
|
10
|
+
ciphertext: Uint8Array;
|
|
11
|
+
nonce: Uint8Array;
|
|
12
|
+
}
|
|
13
|
+
/** Generate a new x25519 keypair for Arcium encryption */
|
|
14
|
+
export declare function generateEncryptionKeypair(): EncryptionKeypair;
|
|
15
|
+
/** Create a RescueCipher from user's private key and MXE public key */
|
|
16
|
+
export declare function createCipher(privateKey: Uint8Array, mxePublicKey: Uint8Array): RescueCipher;
|
|
17
|
+
/** Encrypt a single value, returning ciphertext and nonce */
|
|
18
|
+
export declare function encryptValue(cipher: RescueCipher, value: bigint, nonce?: Uint8Array): EncryptedValue;
|
|
19
|
+
/** Decrypt a ciphertext back to a bigint value */
|
|
20
|
+
export declare function decryptValue(cipher: RescueCipher, ciphertext: Uint8Array, nonce: Uint8Array): bigint;
|
|
21
|
+
/** Fetch MXE public key with retry logic */
|
|
22
|
+
export declare function fetchMXEPublicKey(provider: anchor.AnchorProvider, programId: PublicKey, maxRetries?: number): Promise<Uint8Array>;
|
|
23
|
+
/** Convert a nonce Uint8Array to anchor.BN (for instruction args) */
|
|
24
|
+
export declare function nonceToBN(nonce: Uint8Array): anchor.BN;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.deserializeLE = exports.RescueCipher = void 0;
|
|
37
|
+
exports.generateEncryptionKeypair = generateEncryptionKeypair;
|
|
38
|
+
exports.createCipher = createCipher;
|
|
39
|
+
exports.encryptValue = encryptValue;
|
|
40
|
+
exports.decryptValue = decryptValue;
|
|
41
|
+
exports.fetchMXEPublicKey = fetchMXEPublicKey;
|
|
42
|
+
exports.nonceToBN = nonceToBN;
|
|
43
|
+
const client_1 = require("@arcium-hq/client");
|
|
44
|
+
Object.defineProperty(exports, "RescueCipher", { enumerable: true, get: function () { return client_1.RescueCipher; } });
|
|
45
|
+
Object.defineProperty(exports, "deserializeLE", { enumerable: true, get: function () { return client_1.deserializeLE; } });
|
|
46
|
+
const crypto_1 = require("crypto");
|
|
47
|
+
const anchor = __importStar(require("@coral-xyz/anchor"));
|
|
48
|
+
/** Generate a new x25519 keypair for Arcium encryption */
|
|
49
|
+
function generateEncryptionKeypair() {
|
|
50
|
+
const privateKey = client_1.x25519.utils.randomSecretKey();
|
|
51
|
+
const publicKey = client_1.x25519.getPublicKey(privateKey);
|
|
52
|
+
return { privateKey, publicKey };
|
|
53
|
+
}
|
|
54
|
+
/** Create a RescueCipher from user's private key and MXE public key */
|
|
55
|
+
function createCipher(privateKey, mxePublicKey) {
|
|
56
|
+
const sharedSecret = client_1.x25519.getSharedSecret(privateKey, mxePublicKey);
|
|
57
|
+
return new client_1.RescueCipher(sharedSecret);
|
|
58
|
+
}
|
|
59
|
+
/** Encrypt a single value, returning ciphertext and nonce */
|
|
60
|
+
function encryptValue(cipher, value, nonce) {
|
|
61
|
+
const nonceBytes = nonce || (0, crypto_1.randomBytes)(16);
|
|
62
|
+
const encrypted = cipher.encrypt([value], nonceBytes);
|
|
63
|
+
return {
|
|
64
|
+
ciphertext: encrypted[0],
|
|
65
|
+
nonce: nonceBytes,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/** Decrypt a ciphertext back to a bigint value */
|
|
69
|
+
function decryptValue(cipher, ciphertext, nonce) {
|
|
70
|
+
const decrypted = cipher.decrypt([ciphertext], nonce);
|
|
71
|
+
return decrypted[0];
|
|
72
|
+
}
|
|
73
|
+
/** Fetch MXE public key with retry logic */
|
|
74
|
+
async function fetchMXEPublicKey(provider, programId, maxRetries = 5) {
|
|
75
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
76
|
+
try {
|
|
77
|
+
return await (0, client_1.getMXEPublicKey)(provider, programId);
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
if (attempt === maxRetries)
|
|
81
|
+
throw error;
|
|
82
|
+
await new Promise((r) => setTimeout(r, 2000 * attempt));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
throw new Error("Failed to fetch MXE public key");
|
|
86
|
+
}
|
|
87
|
+
/** Convert a nonce Uint8Array to anchor.BN (for instruction args) */
|
|
88
|
+
function nonceToBN(nonce) {
|
|
89
|
+
return new anchor.BN((0, client_1.deserializeLE)(nonce).toString());
|
|
90
|
+
}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** Maps Anchor error codes (6000+) to readable names and messages */
|
|
2
|
+
export declare const ERROR_MAP: Record<number, {
|
|
3
|
+
name: string;
|
|
4
|
+
message: string;
|
|
5
|
+
}>;
|
|
6
|
+
export declare class ShuffleError extends Error {
|
|
7
|
+
code: number;
|
|
8
|
+
errorName: string;
|
|
9
|
+
constructor(code: number);
|
|
10
|
+
}
|
|
11
|
+
/** Extract a readable error from an Anchor error object */
|
|
12
|
+
export declare function parseError(error: any): ShuffleError | Error;
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ShuffleError = exports.ERROR_MAP = void 0;
|
|
4
|
+
exports.parseError = parseError;
|
|
5
|
+
/** Maps Anchor error codes (6000+) to readable names and messages */
|
|
6
|
+
exports.ERROR_MAP = {
|
|
7
|
+
6000: { name: "ProtocolPaused", message: "Protocol is paused" },
|
|
8
|
+
6001: { name: "Unauthorized", message: "Unauthorized" },
|
|
9
|
+
6002: { name: "InvalidAmount", message: "Invalid amount" },
|
|
10
|
+
6003: { name: "InvalidAsset", message: "Invalid asset" },
|
|
11
|
+
6004: { name: "InvalidAssetId", message: "Invalid asset ID (must be 0-3)" },
|
|
12
|
+
6005: { name: "InvalidPairId", message: "Invalid pair ID (must be 0-5)" },
|
|
13
|
+
6006: { name: "InvalidMint", message: "Invalid token mint" },
|
|
14
|
+
6007: { name: "InvalidOwner", message: "Invalid token account owner" },
|
|
15
|
+
6008: { name: "FeeTooHigh", message: "Fee too high (max 10%)" },
|
|
16
|
+
6009: { name: "PendingOrderExists", message: "User has a pending order - settle before placing a new one" },
|
|
17
|
+
6010: { name: "NoPendingOrder", message: "No pending order to settle" },
|
|
18
|
+
6011: { name: "BatchNotFinalized", message: "Batch not yet executed" },
|
|
19
|
+
6012: { name: "BatchIdMismatch", message: "Batch ID mismatch" },
|
|
20
|
+
6013: { name: "InsufficientBalance", message: "Insufficient balance" },
|
|
21
|
+
6014: { name: "MinOutputNotMet", message: "Minimum output not met" },
|
|
22
|
+
6015: { name: "DivisionByZero", message: "Division by zero in settlement" },
|
|
23
|
+
6016: { name: "AbortedComputation", message: "The computation was aborted" },
|
|
24
|
+
6017: { name: "ComputationFailed", message: "MPC computation failed" },
|
|
25
|
+
6018: { name: "ClusterNotSet", message: "Cluster not set" },
|
|
26
|
+
6019: { name: "RecipientAccountNotFound", message: "Recipient account not found" },
|
|
27
|
+
};
|
|
28
|
+
class ShuffleError extends Error {
|
|
29
|
+
constructor(code) {
|
|
30
|
+
const info = exports.ERROR_MAP[code] || { name: "Unknown", message: `Unknown error code: ${code}` };
|
|
31
|
+
super(info.message);
|
|
32
|
+
this.code = code;
|
|
33
|
+
this.errorName = info.name;
|
|
34
|
+
this.name = "ShuffleError";
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
exports.ShuffleError = ShuffleError;
|
|
38
|
+
/** Extract a readable error from an Anchor error object */
|
|
39
|
+
function parseError(error) {
|
|
40
|
+
const code = error?.error?.errorCode?.number;
|
|
41
|
+
if (code && exports.ERROR_MAP[code]) {
|
|
42
|
+
return new ShuffleError(code);
|
|
43
|
+
}
|
|
44
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
45
|
+
}
|