@depthhq/sdk 0.1.6 → 0.1.8
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/index.d.ts +1 -0
- package/dist/index.js +79 -29
- package/dist/trade/snapshot.d.ts +7 -0
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -34,3 +34,4 @@ export { DepthProvider } from "./chain/provider.js";
|
|
|
34
34
|
export { authenticateManifest, captureDeployment, manifestBytes, verifyDeployment, } from "./chain/manifest.js";
|
|
35
35
|
export type { DeploymentManifest, SignedManifest, DeploymentPolicy, } from "./chain/manifest.js";
|
|
36
36
|
export { ViewSession } from "./view/session.js";
|
|
37
|
+
export { HttpConnection } from "./chain/connection.js";
|
package/dist/index.js
CHANGED
|
@@ -43622,7 +43622,7 @@ import {
|
|
|
43622
43622
|
circuits as circuits2,
|
|
43623
43623
|
computationName,
|
|
43624
43624
|
DEPTH_IDL as DEPTH_IDL3,
|
|
43625
|
-
DEPTH_PROGRAM_ID as
|
|
43625
|
+
DEPTH_PROGRAM_ID as DEPTH_PROGRAM_ID9,
|
|
43626
43626
|
marketAddress as marketAddress8,
|
|
43627
43627
|
protocolAddress as protocolAddress4,
|
|
43628
43628
|
recoveryConfigAddress as recoveryConfigAddress2,
|
|
@@ -46676,6 +46676,37 @@ function tradeLimit(input, direction, oraclePriceE8) {
|
|
|
46676
46676
|
return price;
|
|
46677
46677
|
}
|
|
46678
46678
|
|
|
46679
|
+
// src/trade/snapshot.ts
|
|
46680
|
+
import { DEPTH_PROGRAM_ID as DEPTH_PROGRAM_ID6 } from "@depthhq/bindings";
|
|
46681
|
+
async function quoteSnapshot(connection, program, address2, initial) {
|
|
46682
|
+
let market = initial;
|
|
46683
|
+
for (let attempt = 0;attempt < 4; attempt++) {
|
|
46684
|
+
const quotes = market.activeQuotes.slice(0, market.activeQuoteCount);
|
|
46685
|
+
const keys = [market.backstopOffer, ...quotes];
|
|
46686
|
+
const [account, ...records] = await connection.getMultipleAccountsInfo([address2, ...keys], "confirmed");
|
|
46687
|
+
if (!account?.owner.equals(DEPTH_PROGRAM_ID6))
|
|
46688
|
+
throw new Error("Market account is unavailable");
|
|
46689
|
+
const latest = program.coder.accounts.decode("market", account.data);
|
|
46690
|
+
if (!latest.backstopOffer.equals(market.backstopOffer) || latest.activeQuoteCount !== quotes.length || latest.activeQuotes.slice(0, latest.activeQuoteCount).some((key, index) => !key.equals(quotes[index]))) {
|
|
46691
|
+
market = latest;
|
|
46692
|
+
continue;
|
|
46693
|
+
}
|
|
46694
|
+
if (market.activeQuoteCount === 0)
|
|
46695
|
+
throw new Error("Waiting for maker liquidity");
|
|
46696
|
+
for (const [index, record] of records.entries()) {
|
|
46697
|
+
if (!record?.owner.equals(DEPTH_PROGRAM_ID6))
|
|
46698
|
+
throw new Error(`Market quote snapshot missing account ${index}`);
|
|
46699
|
+
if (index === 0)
|
|
46700
|
+
continue;
|
|
46701
|
+
const quote = program.coder.accounts.decode("quoteRecord", record.data);
|
|
46702
|
+
if (!("active" in quote.status) || quote.expiry.toNumber() <= Math.floor(Date.now() / 1000) || !quote.market.equals(address2))
|
|
46703
|
+
throw new Error("Waiting for maker liquidity");
|
|
46704
|
+
}
|
|
46705
|
+
return { market: latest, keys };
|
|
46706
|
+
}
|
|
46707
|
+
throw new Error("Market is processing another order");
|
|
46708
|
+
}
|
|
46709
|
+
|
|
46679
46710
|
// src/trade/flow.ts
|
|
46680
46711
|
import { transferAddress as transferAddress4 } from "@depthhq/bindings";
|
|
46681
46712
|
|
|
@@ -46741,7 +46772,7 @@ class TradeFlow {
|
|
|
46741
46772
|
|
|
46742
46773
|
// src/view/view.ts
|
|
46743
46774
|
init_buffer();
|
|
46744
|
-
import { circuits, DEPTH_PROGRAM_ID as
|
|
46775
|
+
import { circuits, DEPTH_PROGRAM_ID as DEPTH_PROGRAM_ID7 } from "@depthhq/bindings";
|
|
46745
46776
|
var mask64 = (1n << 64n) - 1n;
|
|
46746
46777
|
var mask128 = (1n << 128n) - 1n;
|
|
46747
46778
|
var fillPacker = createPacker([
|
|
@@ -46808,7 +46839,7 @@ class DepthView {
|
|
|
46808
46839
|
}
|
|
46809
46840
|
async status() {
|
|
46810
46841
|
const response = await this.connection.getAccountInfoAndContext(this.id, "confirmed");
|
|
46811
|
-
if (!response.value || !response.value.owner.equals(
|
|
46842
|
+
if (!response.value || !response.value.owner.equals(DEPTH_PROGRAM_ID7)) {
|
|
46812
46843
|
throw new Error("Private view account is unavailable");
|
|
46813
46844
|
}
|
|
46814
46845
|
const state = this.program.coder.accounts.decode(this.kind === "balance" ? "balanceView" : this.kind === "market" ? "marketView" : this.kind === "fill" ? "fillView" : "quoteView", response.value.data);
|
|
@@ -46917,7 +46948,7 @@ class DepthView {
|
|
|
46917
46948
|
init_buffer();
|
|
46918
46949
|
import * as anchor8 from "@anchor-lang/core";
|
|
46919
46950
|
import {
|
|
46920
|
-
DEPTH_PROGRAM_ID as
|
|
46951
|
+
DEPTH_PROGRAM_ID as DEPTH_PROGRAM_ID8,
|
|
46921
46952
|
marketAddress as marketAddress7,
|
|
46922
46953
|
viewPermitAddress
|
|
46923
46954
|
} from "@depthhq/bindings";
|
|
@@ -47140,7 +47171,7 @@ class ViewSession {
|
|
|
47140
47171
|
const info = await this.connection.getAccountInfo(keys.permit, "confirmed");
|
|
47141
47172
|
if (!info)
|
|
47142
47173
|
return { active: false, id: keys.permit.toBase58() };
|
|
47143
|
-
if (!info.owner.equals(
|
|
47174
|
+
if (!info.owner.equals(DEPTH_PROGRAM_ID8))
|
|
47144
47175
|
throw new Error("Invalid private read permission owner");
|
|
47145
47176
|
const permit = this.program.coder.accounts.decode("viewPermit", info.data);
|
|
47146
47177
|
const expiresAt = permit.expiresAt.toNumber();
|
|
@@ -47193,7 +47224,7 @@ class ViewSession {
|
|
|
47193
47224
|
async post(request, action) {
|
|
47194
47225
|
const { signing } = await this.keys();
|
|
47195
47226
|
request.expiresAt = Math.floor(Date.now() / 1000) + 120;
|
|
47196
|
-
request.signature = Buffer2.from(await sign(new TextEncoder().encode(viewMessage(
|
|
47227
|
+
request.signature = Buffer2.from(await sign(new TextEncoder().encode(viewMessage(DEPTH_PROGRAM_ID8.toBase58(), request, action)), signing)).toString("base64");
|
|
47197
47228
|
return fetch(`${this.serviceUrl}/v1/views${action === "close" ? "/close" : ""}`, {
|
|
47198
47229
|
method: "POST",
|
|
47199
47230
|
headers: { "content-type": "application/json" },
|
|
@@ -47253,10 +47284,10 @@ class ViewSession {
|
|
|
47253
47284
|
payer.toBuffer(),
|
|
47254
47285
|
nonce
|
|
47255
47286
|
];
|
|
47256
|
-
const id = PublicKey10.findProgramAddressSync(seeds,
|
|
47287
|
+
const id = PublicKey10.findProgramAddressSync(seeds, DEPTH_PROGRAM_ID8)[0];
|
|
47257
47288
|
if (receipt.id !== id.toBase58() || typeof receipt.signature !== "string")
|
|
47258
47289
|
throw new Error("Invalid private read receipt");
|
|
47259
|
-
const mxeKey = await getMXEPublicKey(this.program.provider,
|
|
47290
|
+
const mxeKey = await getMXEPublicKey(this.program.provider, DEPTH_PROGRAM_ID8);
|
|
47260
47291
|
if (!mxeKey)
|
|
47261
47292
|
throw new Error("MXE public key is unavailable");
|
|
47262
47293
|
return new DepthView(id, receipt.signature, kind, payer, keys.secret, keys.viewKey, mxeKey, this.program, this.connection, source, async () => {
|
|
@@ -47271,7 +47302,7 @@ class ViewSession {
|
|
|
47271
47302
|
}
|
|
47272
47303
|
|
|
47273
47304
|
// src/client/client.ts
|
|
47274
|
-
function pda(seeds, programId =
|
|
47305
|
+
function pda(seeds, programId = DEPTH_PROGRAM_ID9) {
|
|
47275
47306
|
return PublicKey11.findProgramAddressSync(seeds, programId)[0];
|
|
47276
47307
|
}
|
|
47277
47308
|
function nonce() {
|
|
@@ -47291,7 +47322,7 @@ class DepthClient {
|
|
|
47291
47322
|
position;
|
|
47292
47323
|
marketAddress = marketAddress8();
|
|
47293
47324
|
protocolAddress = protocolAddress4();
|
|
47294
|
-
mxeAddress = getMXEAccAddress(
|
|
47325
|
+
mxeAddress = getMXEAccAddress(DEPTH_PROGRAM_ID9);
|
|
47295
47326
|
get catalog() {
|
|
47296
47327
|
return new MarketCatalog(this);
|
|
47297
47328
|
}
|
|
@@ -47310,7 +47341,7 @@ class DepthClient {
|
|
|
47310
47341
|
}
|
|
47311
47342
|
constructor(options) {
|
|
47312
47343
|
this.options = options;
|
|
47313
|
-
const scope = `${"manifest" in options.deployment ? options.deployment.manifest.payload.genesisHash : "localnet"}:${
|
|
47344
|
+
const scope = `${"manifest" in options.deployment ? options.deployment.manifest.payload.genesisHash : "localnet"}:${DEPTH_PROGRAM_ID9.toBase58()}:${options.wallet.publicKey.toBase58()}`;
|
|
47314
47345
|
const storage = options.privateViews === "device" && "manifest" in options.deployment && typeof indexedDB !== "undefined" && globalThis.crypto?.subtle ? new DeviceViews : undefined;
|
|
47315
47346
|
this.viewCache = new ViewCache(scope, storage);
|
|
47316
47347
|
this.provider = new DepthProvider(options.connection, options.wallet, {
|
|
@@ -47335,7 +47366,7 @@ class DepthClient {
|
|
|
47335
47366
|
}
|
|
47336
47367
|
async verifyDeployment() {
|
|
47337
47368
|
const [programInfo, protocol, market, app, mxe] = await Promise.all([
|
|
47338
|
-
this.options.connection.getAccountInfo(
|
|
47369
|
+
this.options.connection.getAccountInfo(DEPTH_PROGRAM_ID9, "confirmed"),
|
|
47339
47370
|
this.read("Protocol", this.protocolAddress),
|
|
47340
47371
|
this.read("Market", this.marketAddress),
|
|
47341
47372
|
this.options.appId ? this.read("AppConfig", appAddress2(this.options.appId)) : Promise.resolve(undefined),
|
|
@@ -47343,13 +47374,13 @@ class DepthClient {
|
|
|
47343
47374
|
]);
|
|
47344
47375
|
if (!programInfo?.executable)
|
|
47345
47376
|
throw new Error("Depth program is not deployed");
|
|
47346
|
-
if (!market.settlementMint.equals(protocol.settlementMint) || !market.vault.equals(protocol.vault) || this.options.appId && !app?.app.equals(this.options.appId) || !mxe.mxeProgramId.equals(
|
|
47377
|
+
if (!market.settlementMint.equals(protocol.settlementMint) || !market.vault.equals(protocol.vault) || this.options.appId && !app?.app.equals(this.options.appId) || !mxe.mxeProgramId.equals(DEPTH_PROGRAM_ID9)) {
|
|
47347
47378
|
throw new Error("Depth deployment accounts disagree");
|
|
47348
47379
|
}
|
|
47349
47380
|
}
|
|
47350
47381
|
async read(name2, address2) {
|
|
47351
47382
|
const info = await this.options.connection.getAccountInfo(address2, "confirmed");
|
|
47352
|
-
if (!info || !info.owner.equals(
|
|
47383
|
+
if (!info || !info.owner.equals(DEPTH_PROGRAM_ID9)) {
|
|
47353
47384
|
throw new Error(`${name2} account is unavailable`);
|
|
47354
47385
|
}
|
|
47355
47386
|
return this.program.coder.accounts.decode(name2[0].toLowerCase() + name2.slice(1), info.data);
|
|
@@ -47357,7 +47388,7 @@ class DepthClient {
|
|
|
47357
47388
|
async queue(name2, offset2) {
|
|
47358
47389
|
const mxe = await arciumAccount(this.provider).fetch(this.mxeAddress);
|
|
47359
47390
|
const cluster = mxe.cluster;
|
|
47360
|
-
const definition = getCompDefAccAddress(
|
|
47391
|
+
const definition = getCompDefAccAddress(DEPTH_PROGRAM_ID9, Buffer2.from(getCompDefAccOffset(computationName(name2))).readUInt32LE());
|
|
47361
47392
|
const definitionInfo = await this.options.connection.getAccountInfo(definition, "confirmed");
|
|
47362
47393
|
if (!definitionInfo)
|
|
47363
47394
|
throw new Error(`${name2} computation is not deployed`);
|
|
@@ -47379,7 +47410,7 @@ class DepthClient {
|
|
|
47379
47410
|
}
|
|
47380
47411
|
async market() {
|
|
47381
47412
|
const response = await this.options.connection.getAccountInfoAndContext(this.marketAddress, "confirmed");
|
|
47382
|
-
if (!response.value || !response.value.owner.equals(
|
|
47413
|
+
if (!response.value || !response.value.owner.equals(DEPTH_PROGRAM_ID9)) {
|
|
47383
47414
|
throw new Error("Depth market is unavailable");
|
|
47384
47415
|
}
|
|
47385
47416
|
return {
|
|
@@ -47457,7 +47488,7 @@ class DepthClient {
|
|
|
47457
47488
|
const source = accounts2.balance ?? accounts2.marketAccount ?? accounts2.order ?? accounts2.quote;
|
|
47458
47489
|
if (this.options.viewAuthorization === "session" || this.options.viewAuthorization !== "wallet" && this.options.privateViews === "device" && this.options.serviceUrl)
|
|
47459
47490
|
return this.views.request(kind, source);
|
|
47460
|
-
const mxePublicKey = await getMXEPublicKey(this.provider,
|
|
47491
|
+
const mxePublicKey = await getMXEPublicKey(this.provider, DEPTH_PROGRAM_ID9);
|
|
47461
47492
|
if (!mxePublicKey)
|
|
47462
47493
|
throw new Error("MXE public key is unavailable");
|
|
47463
47494
|
const secret = x25519.utils.randomSecretKey();
|
|
@@ -47690,7 +47721,7 @@ class DepthClient {
|
|
|
47690
47721
|
async deferViewClose(kind, id) {
|
|
47691
47722
|
const view = new PublicKey11(id);
|
|
47692
47723
|
const info = await this.options.connection.getAccountInfo(view, "confirmed");
|
|
47693
|
-
if (!info?.owner.equals(
|
|
47724
|
+
if (!info?.owner.equals(DEPTH_PROGRAM_ID9))
|
|
47694
47725
|
return;
|
|
47695
47726
|
const receipt = this.program.coder.accounts.decode(kind === "balance" ? "balanceView" : "marketView", info.data);
|
|
47696
47727
|
if (!receipt.owner.equals(this.options.wallet.publicKey) || "pending" in receipt.status)
|
|
@@ -47842,17 +47873,31 @@ class DepthClient {
|
|
|
47842
47873
|
u64(position.collateral, "collateral");
|
|
47843
47874
|
if (position.collateral === 0n)
|
|
47844
47875
|
throw new Error("The market account has no collateral");
|
|
47845
|
-
|
|
47846
|
-
|
|
47847
|
-
|
|
47848
|
-
|
|
47849
|
-
|
|
47850
|
-
|
|
47851
|
-
|
|
47852
|
-
|
|
47876
|
+
let keys = [];
|
|
47877
|
+
const quoteDeadline = Date.now() + 60000;
|
|
47878
|
+
for (;; ) {
|
|
47879
|
+
try {
|
|
47880
|
+
const snapshot = await quoteSnapshot(this.options.connection, this.program, this.marketAddress, market.state);
|
|
47881
|
+
market = { ...market, state: snapshot.market };
|
|
47882
|
+
deadline = tradeDeadline(input, Math.floor(Date.now() / 1000), market.state.config.maxOrderQueueSeconds);
|
|
47883
|
+
this.validateTrade(market.state, protocol, account, app, appId, intent, deadline);
|
|
47884
|
+
if (!account.version.eq(new anchor9.BN(position.version.toString())))
|
|
47885
|
+
throw new Error("Private position changed while preparing the trade");
|
|
47886
|
+
keys = snapshot.keys;
|
|
47887
|
+
break;
|
|
47888
|
+
} catch (error) {
|
|
47889
|
+
if (!(error instanceof Error) || ![
|
|
47890
|
+
"Waiting for maker liquidity",
|
|
47891
|
+
"Market is processing another order",
|
|
47892
|
+
"Waiting for a fresh oracle update",
|
|
47893
|
+
"Oracle update is stale"
|
|
47894
|
+
].includes(error.message) || Date.now() >= quoteDeadline)
|
|
47895
|
+
throw error;
|
|
47896
|
+
[market, protocol, account, app] = await this.waitForMarket(input, appId, intent);
|
|
47897
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
47853
47898
|
}
|
|
47854
|
-
}
|
|
47855
|
-
const mxePublicKey = await getMXEPublicKey(this.provider,
|
|
47899
|
+
}
|
|
47900
|
+
const mxePublicKey = await getMXEPublicKey(this.provider, DEPTH_PROGRAM_ID9);
|
|
47856
47901
|
if (!mxePublicKey)
|
|
47857
47902
|
throw new Error("MXE public key is unavailable");
|
|
47858
47903
|
const secret = x25519.utils.randomSecretKey();
|
|
@@ -47909,7 +47954,9 @@ class DepthClient {
|
|
|
47909
47954
|
} catch (error) {
|
|
47910
47955
|
if (!(error instanceof Error) || ![
|
|
47911
47956
|
"Waiting for maker liquidity",
|
|
47912
|
-
"Market is processing another order"
|
|
47957
|
+
"Market is processing another order",
|
|
47958
|
+
"Waiting for a fresh oracle update",
|
|
47959
|
+
"Oracle update is stale"
|
|
47913
47960
|
].includes(error.message) || Date.now() >= until)
|
|
47914
47961
|
throw error;
|
|
47915
47962
|
}
|
|
@@ -47936,6 +47983,8 @@ class DepthClient {
|
|
|
47936
47983
|
if (age < 0 || age > market.config.maxOracleAgeSeconds) {
|
|
47937
47984
|
throw new Error("Oracle update is stale");
|
|
47938
47985
|
}
|
|
47986
|
+
if (age > market.config.maxOracleAgeSeconds - Math.min(60, Math.floor(market.config.maxOracleAgeSeconds / 2)))
|
|
47987
|
+
throw new Error("Waiting for a fresh oracle update");
|
|
47939
47988
|
if (deadline <= now || deadline - now > market.config.maxOrderQueueSeconds) {
|
|
47940
47989
|
throw new Error("Order deadline is outside market policy");
|
|
47941
47990
|
}
|
|
@@ -48099,6 +48148,7 @@ export {
|
|
|
48099
48148
|
TradeFlow,
|
|
48100
48149
|
MarketData,
|
|
48101
48150
|
MarketCatalog,
|
|
48151
|
+
HttpConnection,
|
|
48102
48152
|
FundingDiscovery,
|
|
48103
48153
|
FundingClient,
|
|
48104
48154
|
ExecutionHistory,
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type * as anchor from "@anchor-lang/core";
|
|
2
|
+
import { Connection, PublicKey } from "@solana/web3.js";
|
|
3
|
+
import type { MarketState } from "../client/types.js";
|
|
4
|
+
export declare function quoteSnapshot(connection: Connection, program: anchor.Program, address: PublicKey, initial: MarketState): Promise<{
|
|
5
|
+
market: MarketState;
|
|
6
|
+
keys: anchor.web3.PublicKey[];
|
|
7
|
+
}>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@depthhq/sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"@noble/hashes": "1.8.0",
|
|
45
45
|
"@solana/web3.js": "1.99.0",
|
|
46
46
|
"buffer": "6.0.3",
|
|
47
|
-
"@depthhq/bindings": "0.1.
|
|
47
|
+
"@depthhq/bindings": "0.1.4",
|
|
48
48
|
"@depthhq/schema": "0.1.2"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|