@depthhq/sdk 0.1.3 → 0.1.5
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/client/client.d.ts +4 -1
- package/dist/client/types.d.ts +2 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +331 -36
- package/dist/view/cache.d.ts +9 -0
- package/dist/view/session.d.ts +28 -0
- package/dist/view/view.d.ts +3 -1
- package/dist/view/view.js +14 -1
- package/package.json +3 -3
package/dist/client/client.d.ts
CHANGED
|
@@ -12,13 +12,15 @@ import { ExecutionHistory } from "../history/history.js";
|
|
|
12
12
|
import type { AmountSelector } from "../trade/amount.js";
|
|
13
13
|
import { TradeFlow } from "../trade/flow.js";
|
|
14
14
|
import { DepthView } from "../view/view.js";
|
|
15
|
+
import { ViewSession } from "../view/session.js";
|
|
15
16
|
import type { BalanceSnapshot } from "../view/view.js";
|
|
16
17
|
import type { CloseInput, DepthOptions, ResolvedDepthOptions, MarketState, ReductionInput, ReverseInput, TradeInput } from "./types.js";
|
|
17
18
|
export declare class DepthClient {
|
|
18
19
|
readonly options: ResolvedDepthOptions;
|
|
19
20
|
readonly program: anchor.Program;
|
|
20
21
|
readonly provider: DepthProvider;
|
|
21
|
-
private readonly
|
|
22
|
+
private readonly viewCache;
|
|
23
|
+
readonly views: ViewSession;
|
|
22
24
|
private readonly viewReads;
|
|
23
25
|
readonly position: ReturnType<DepthClient["positionActions"]>;
|
|
24
26
|
readonly marketAddress: anchor.web3.PublicKey;
|
|
@@ -42,6 +44,7 @@ export declare class DepthClient {
|
|
|
42
44
|
slot: number;
|
|
43
45
|
}>;
|
|
44
46
|
operation(id: PublicKey): DepthOperation;
|
|
47
|
+
requestQuoteView(quote: PublicKey): Promise<DepthView>;
|
|
45
48
|
requestBalanceView(): Promise<DepthView>;
|
|
46
49
|
requestMarketView(): Promise<DepthView>;
|
|
47
50
|
requestFillView(order: PublicKey): Promise<DepthView>;
|
package/dist/client/types.d.ts
CHANGED
|
@@ -12,12 +12,14 @@ export type DepthOptions = ConnectionOptions & {
|
|
|
12
12
|
appId?: PublicKey | string;
|
|
13
13
|
wallet: DepthWallet;
|
|
14
14
|
privateViews?: "memory" | "device";
|
|
15
|
+
viewAuthorization?: "session" | "wallet";
|
|
15
16
|
settlement?: "keeper" | "wallet";
|
|
16
17
|
};
|
|
17
18
|
export type ResolvedDepthOptions = ResolvedConnection & {
|
|
18
19
|
appId?: PublicKey;
|
|
19
20
|
wallet: DepthWallet;
|
|
20
21
|
privateViews?: "memory" | "device";
|
|
22
|
+
viewAuthorization?: "session" | "wallet";
|
|
21
23
|
settlement?: "keeper" | "wallet";
|
|
22
24
|
};
|
|
23
25
|
export type TradeTerms = {
|
package/dist/index.d.ts
CHANGED
|
@@ -33,3 +33,4 @@ export { DepthError } from "./operation/error.js";
|
|
|
33
33
|
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
|
+
export { ViewSession } from "./view/session.js";
|
package/dist/index.js
CHANGED
|
@@ -18122,7 +18122,7 @@ https://github.com/browserify/crypto-browserify`);
|
|
|
18122
18122
|
|
|
18123
18123
|
// src/client/client.ts
|
|
18124
18124
|
init_buffer();
|
|
18125
|
-
import * as
|
|
18125
|
+
import * as anchor9 from "@anchor-lang/core";
|
|
18126
18126
|
|
|
18127
18127
|
// ../../node_modules/@noble/hashes/esm/crypto.js
|
|
18128
18128
|
var crypto2 = typeof globalThis === "object" && "crypto" in globalThis ? globalThis.crypto : undefined;
|
|
@@ -43622,13 +43622,13 @@ import {
|
|
|
43622
43622
|
circuits as circuits2,
|
|
43623
43623
|
computationName,
|
|
43624
43624
|
DEPTH_IDL as DEPTH_IDL3,
|
|
43625
|
-
DEPTH_PROGRAM_ID as
|
|
43626
|
-
marketAddress as
|
|
43625
|
+
DEPTH_PROGRAM_ID as DEPTH_PROGRAM_ID8,
|
|
43626
|
+
marketAddress as marketAddress8,
|
|
43627
43627
|
protocolAddress as protocolAddress4,
|
|
43628
43628
|
recoveryConfigAddress as recoveryConfigAddress2,
|
|
43629
43629
|
SOL_USD_MARKET_ID as SOL_USD_MARKET_ID3
|
|
43630
43630
|
} from "@depthhq/bindings";
|
|
43631
|
-
import { PublicKey as
|
|
43631
|
+
import { PublicKey as PublicKey11 } from "@solana/web3.js";
|
|
43632
43632
|
|
|
43633
43633
|
// src/chain/random.ts
|
|
43634
43634
|
function randomBytes3(length) {
|
|
@@ -44335,9 +44335,21 @@ async function getExtendedPublicKey(key) {
|
|
|
44335
44335
|
function getExtendedPublicKeySync(key) {
|
|
44336
44336
|
return getKeyFromHash(sha512s(checkPrivateKey(key)));
|
|
44337
44337
|
}
|
|
44338
|
+
async function getPublicKey(privateKey) {
|
|
44339
|
+
return (await getExtendedPublicKey(privateKey)).pointBytes;
|
|
44340
|
+
}
|
|
44338
44341
|
function getPublicKeySync(privateKey) {
|
|
44339
44342
|
return getExtendedPublicKeySync(privateKey).pointBytes;
|
|
44340
44343
|
}
|
|
44344
|
+
async function sign(message, privateKey) {
|
|
44345
|
+
message = ensureBytes2(message);
|
|
44346
|
+
const { prefix, scalar, pointBytes } = await getExtendedPublicKey(privateKey);
|
|
44347
|
+
const r = modlLE(await utils.sha512(prefix, message));
|
|
44348
|
+
const R = Point.BASE.multiply(r);
|
|
44349
|
+
const k = modlLE(await utils.sha512(R.toRawBytes(), pointBytes, message));
|
|
44350
|
+
const s = mod2(r + k * scalar, CURVE.l);
|
|
44351
|
+
return new Signature(R, s).toRawBytes();
|
|
44352
|
+
}
|
|
44341
44353
|
function signSync(message, privateKey) {
|
|
44342
44354
|
message = ensureBytes2(message);
|
|
44343
44355
|
const { prefix, scalar, pointBytes } = getExtendedPublicKeySync(privateKey);
|
|
@@ -46014,22 +46026,22 @@ function positionPnl(position, priceE8, fundingIndex, fill) {
|
|
|
46014
46026
|
if (position.status !== "ready" || position.position === undefined || position.position === 0n || position.entryPriceE8 === undefined || position.fundingCheckpoint === undefined || position.collateral !== undefined && position.collateral < 0n || priceE8 <= 0n)
|
|
46015
46027
|
throw new Error("A ready open position and a positive price are required");
|
|
46016
46028
|
const size = position.position < 0n ? -position.position : position.position;
|
|
46017
|
-
const
|
|
46029
|
+
const sign2 = position.position > 0n ? 1n : -1n;
|
|
46018
46030
|
let closing = size;
|
|
46019
46031
|
let fee = 0n;
|
|
46020
46032
|
let state = "open";
|
|
46021
46033
|
if (fill) {
|
|
46022
|
-
if (fill.status !== "ready" || fill.side !== -
|
|
46034
|
+
if (fill.status !== "ready" || fill.side !== -sign2 || fill.size === undefined || fill.size <= 0n || fill.executionPriceE8 !== priceE8 || fill.fee === undefined || fill.fee < 0n)
|
|
46023
46035
|
throw new Error("A ready opposite-side execution is required");
|
|
46024
46036
|
closing = fill.size < size ? fill.size : size;
|
|
46025
46037
|
fee = fill.fee;
|
|
46026
46038
|
state = fill.size === size ? "closed" : fill.size < size ? "reduced" : "reversed";
|
|
46027
46039
|
}
|
|
46028
|
-
const gross =
|
|
46040
|
+
const gross = sign2 * closing * (priceE8 - position.entryPriceE8) / scale;
|
|
46029
46041
|
const funding = position.position * (fundingIndex - position.fundingCheckpoint) / scale;
|
|
46030
46042
|
const net = gross - funding - fee;
|
|
46031
46043
|
return {
|
|
46032
|
-
side:
|
|
46044
|
+
side: sign2 > 0n ? "long" : "short",
|
|
46033
46045
|
state,
|
|
46034
46046
|
entryPriceE8: position.entryPriceE8,
|
|
46035
46047
|
priceE8,
|
|
@@ -46765,7 +46777,9 @@ class DepthView {
|
|
|
46765
46777
|
mxePublicKey;
|
|
46766
46778
|
program;
|
|
46767
46779
|
connection;
|
|
46768
|
-
|
|
46780
|
+
source;
|
|
46781
|
+
release;
|
|
46782
|
+
constructor(id, signature, kind, owner, secret, publicKey, mxePublicKey, program, connection, source, release) {
|
|
46769
46783
|
this.id = id;
|
|
46770
46784
|
this.signature = signature;
|
|
46771
46785
|
this.kind = kind;
|
|
@@ -46775,6 +46789,8 @@ class DepthView {
|
|
|
46775
46789
|
this.mxePublicKey = mxePublicKey;
|
|
46776
46790
|
this.program = program;
|
|
46777
46791
|
this.connection = connection;
|
|
46792
|
+
this.source = source;
|
|
46793
|
+
this.release = release;
|
|
46778
46794
|
}
|
|
46779
46795
|
async status() {
|
|
46780
46796
|
const response = await this.connection.getAccountInfoAndContext(this.id, "confirmed");
|
|
@@ -46785,6 +46801,9 @@ class DepthView {
|
|
|
46785
46801
|
if (!state.owner.equals(this.owner) || !Buffer2.from(state.viewKey).equals(Buffer2.from(this.publicKey))) {
|
|
46786
46802
|
throw new Error("Private view authorization does not match this request");
|
|
46787
46803
|
}
|
|
46804
|
+
const source = this.kind === "balance" ? state.balance : this.kind === "market" ? state.marketAccount : this.kind === "fill" ? state.order : state.quote;
|
|
46805
|
+
if (this.source && !source?.equals(this.source))
|
|
46806
|
+
throw new Error("Private view source does not match this request");
|
|
46788
46807
|
const current = Object.keys(state.status)[0];
|
|
46789
46808
|
if (current !== "pending" && current !== "ready" && current !== "stale") {
|
|
46790
46809
|
throw new Error("Private view has an unknown status");
|
|
@@ -46850,6 +46869,10 @@ class DepthView {
|
|
|
46850
46869
|
}
|
|
46851
46870
|
}
|
|
46852
46871
|
async deferClose() {
|
|
46872
|
+
if (this.release) {
|
|
46873
|
+
await this.close();
|
|
46874
|
+
return;
|
|
46875
|
+
}
|
|
46853
46876
|
const provider = this.program.provider;
|
|
46854
46877
|
if (typeof provider.deferClose !== "function") {
|
|
46855
46878
|
await this.close();
|
|
@@ -46870,10 +46893,25 @@ class DepthView {
|
|
|
46870
46893
|
if (snapshot.status === "pending") {
|
|
46871
46894
|
throw new Error("Private view computation is still pending");
|
|
46872
46895
|
}
|
|
46896
|
+
if (this.release)
|
|
46897
|
+
return this.release();
|
|
46873
46898
|
return this.closeBuilder().rpc({ commitment: "confirmed" });
|
|
46874
46899
|
}
|
|
46875
46900
|
}
|
|
46876
46901
|
|
|
46902
|
+
// src/view/session.ts
|
|
46903
|
+
init_buffer();
|
|
46904
|
+
import * as anchor8 from "@anchor-lang/core";
|
|
46905
|
+
import {
|
|
46906
|
+
DEPTH_PROGRAM_ID as DEPTH_PROGRAM_ID7,
|
|
46907
|
+
marketAddress as marketAddress7,
|
|
46908
|
+
viewPermitAddress
|
|
46909
|
+
} from "@depthhq/bindings";
|
|
46910
|
+
import {
|
|
46911
|
+
viewMessage
|
|
46912
|
+
} from "@depthhq/schema";
|
|
46913
|
+
import { PublicKey as PublicKey10 } from "@solana/web3.js";
|
|
46914
|
+
|
|
46877
46915
|
// src/view/cache.ts
|
|
46878
46916
|
class DeviceViews {
|
|
46879
46917
|
database;
|
|
@@ -46928,6 +46966,40 @@ class DeviceViews {
|
|
|
46928
46966
|
}
|
|
46929
46967
|
}
|
|
46930
46968
|
|
|
46969
|
+
class EncryptedViews {
|
|
46970
|
+
scope;
|
|
46971
|
+
storage;
|
|
46972
|
+
key;
|
|
46973
|
+
constructor(scope, storage) {
|
|
46974
|
+
this.scope = scope;
|
|
46975
|
+
this.storage = storage;
|
|
46976
|
+
}
|
|
46977
|
+
encryptionKey() {
|
|
46978
|
+
return this.key ??= crypto.subtle.generateKey({ name: "AES-GCM", length: 256 }, false, [
|
|
46979
|
+
"encrypt",
|
|
46980
|
+
"decrypt"
|
|
46981
|
+
]).then((key) => this.storage.key(this.scope, key));
|
|
46982
|
+
}
|
|
46983
|
+
async read(name2) {
|
|
46984
|
+
const id = `${this.scope}:${name2}`;
|
|
46985
|
+
const envelope = await this.storage.read(id);
|
|
46986
|
+
if (!envelope)
|
|
46987
|
+
return;
|
|
46988
|
+
const bytes = await crypto.subtle.decrypt({
|
|
46989
|
+
name: "AES-GCM",
|
|
46990
|
+
iv: envelope.iv,
|
|
46991
|
+
additionalData: new TextEncoder().encode(id)
|
|
46992
|
+
}, await this.encryptionKey(), envelope.data);
|
|
46993
|
+
return JSON.parse(new TextDecoder().decode(bytes));
|
|
46994
|
+
}
|
|
46995
|
+
async write(name2, value2) {
|
|
46996
|
+
const id = `${this.scope}:${name2}`;
|
|
46997
|
+
const iv = crypto.getRandomValues(new Uint8Array(12));
|
|
46998
|
+
const data = await crypto.subtle.encrypt({ name: "AES-GCM", iv, additionalData: new TextEncoder().encode(id) }, await this.encryptionKey(), new TextEncoder().encode(JSON.stringify(value2)));
|
|
46999
|
+
await this.storage.write(id, { iv, data });
|
|
47000
|
+
}
|
|
47001
|
+
}
|
|
47002
|
+
|
|
46931
47003
|
class ViewCache {
|
|
46932
47004
|
scope;
|
|
46933
47005
|
storage;
|
|
@@ -46991,12 +47063,205 @@ class ViewCache {
|
|
|
46991
47063
|
}
|
|
46992
47064
|
}
|
|
46993
47065
|
|
|
47066
|
+
// src/view/session.ts
|
|
47067
|
+
var identities = new Map;
|
|
47068
|
+
var approvals = new Map;
|
|
47069
|
+
var requests = new Map;
|
|
47070
|
+
var disabled = new Set;
|
|
47071
|
+
|
|
47072
|
+
class ViewSession {
|
|
47073
|
+
program;
|
|
47074
|
+
connection;
|
|
47075
|
+
owner;
|
|
47076
|
+
serviceUrl;
|
|
47077
|
+
scope;
|
|
47078
|
+
storage;
|
|
47079
|
+
pending = new Map;
|
|
47080
|
+
constructor(program, connection, owner, serviceUrl, scope, storage) {
|
|
47081
|
+
this.program = program;
|
|
47082
|
+
this.connection = connection;
|
|
47083
|
+
this.owner = owner;
|
|
47084
|
+
this.serviceUrl = serviceUrl;
|
|
47085
|
+
this.scope = scope;
|
|
47086
|
+
if (storage)
|
|
47087
|
+
this.storage = new EncryptedViews(scope, storage);
|
|
47088
|
+
}
|
|
47089
|
+
identity() {
|
|
47090
|
+
let value2 = identities.get(this.scope);
|
|
47091
|
+
if (!value2) {
|
|
47092
|
+
value2 = (async () => {
|
|
47093
|
+
const saved = await this.storage?.read("authorization");
|
|
47094
|
+
if (saved) {
|
|
47095
|
+
if (![saved.signing, saved.encryption].every((key) => Array.isArray(key) && key.length === 32 && key.every((v) => Number.isInteger(v) && v >= 0 && v <= 255)))
|
|
47096
|
+
throw new Error("Invalid private read identity");
|
|
47097
|
+
return saved;
|
|
47098
|
+
}
|
|
47099
|
+
const identity = {
|
|
47100
|
+
signing: Array.from(randomBytes3(32)),
|
|
47101
|
+
encryption: Array.from(x25519.utils.randomSecretKey())
|
|
47102
|
+
};
|
|
47103
|
+
await this.storage?.write("authorization", identity);
|
|
47104
|
+
return identity;
|
|
47105
|
+
})();
|
|
47106
|
+
identities.set(this.scope, value2);
|
|
47107
|
+
value2.catch(() => identities.delete(this.scope));
|
|
47108
|
+
}
|
|
47109
|
+
return value2;
|
|
47110
|
+
}
|
|
47111
|
+
async keys() {
|
|
47112
|
+
const identity = await this.identity();
|
|
47113
|
+
const secret = Uint8Array.from(identity.encryption);
|
|
47114
|
+
const signing = Uint8Array.from(identity.signing);
|
|
47115
|
+
const reader = new PublicKey10(await getPublicKey(signing));
|
|
47116
|
+
return {
|
|
47117
|
+
signing,
|
|
47118
|
+
secret,
|
|
47119
|
+
reader,
|
|
47120
|
+
viewKey: x25519.getPublicKey(secret),
|
|
47121
|
+
permit: viewPermitAddress(this.owner, reader)
|
|
47122
|
+
};
|
|
47123
|
+
}
|
|
47124
|
+
async status() {
|
|
47125
|
+
const keys = await this.keys();
|
|
47126
|
+
const info = await this.connection.getAccountInfo(keys.permit, "confirmed");
|
|
47127
|
+
if (!info)
|
|
47128
|
+
return { active: false, id: keys.permit.toBase58() };
|
|
47129
|
+
if (!info.owner.equals(DEPTH_PROGRAM_ID7))
|
|
47130
|
+
throw new Error("Invalid private read permission owner");
|
|
47131
|
+
const permit = this.program.coder.accounts.decode("viewPermit", info.data);
|
|
47132
|
+
const expiresAt = permit.expiresAt.toNumber();
|
|
47133
|
+
if (!permit.owner.equals(this.owner) || !permit.reader.equals(keys.reader) || !permit.market.equals(marketAddress7()) || !Buffer2.from(permit.viewKey).equals(Buffer2.from(keys.viewKey)))
|
|
47134
|
+
throw new Error("Private read permission does not match this device");
|
|
47135
|
+
return {
|
|
47136
|
+
id: keys.permit.toBase58(),
|
|
47137
|
+
active: permit.active && expiresAt > Math.floor(Date.now() / 1000) && permit.scopes === 15,
|
|
47138
|
+
expiresAt
|
|
47139
|
+
};
|
|
47140
|
+
}
|
|
47141
|
+
async capability() {
|
|
47142
|
+
if (!this.serviceUrl)
|
|
47143
|
+
throw new Error("A Depth service is required for automatic private reads");
|
|
47144
|
+
const response = await fetch(`${this.serviceUrl}/v1/views`, {
|
|
47145
|
+
cache: "no-store",
|
|
47146
|
+
signal: AbortSignal.timeout(15000)
|
|
47147
|
+
});
|
|
47148
|
+
if (!response.ok || (await response.json()).enabled !== true)
|
|
47149
|
+
throw new Error("Automatic private reads are unavailable");
|
|
47150
|
+
}
|
|
47151
|
+
async authorize() {
|
|
47152
|
+
const { permit, reader, viewKey } = await this.keys();
|
|
47153
|
+
const id = permit.toBase58();
|
|
47154
|
+
const existing = approvals.get(id);
|
|
47155
|
+
if (existing)
|
|
47156
|
+
return existing;
|
|
47157
|
+
const approval = (async () => {
|
|
47158
|
+
if ((await this.status()).active) {
|
|
47159
|
+
disabled.delete(this.scope);
|
|
47160
|
+
await this.storage?.write("disabled", false);
|
|
47161
|
+
return;
|
|
47162
|
+
}
|
|
47163
|
+
await this.capability();
|
|
47164
|
+
const expiresAt = new anchor8.BN(Math.floor(Date.now() / 1000) + 7 * 86400 - 60);
|
|
47165
|
+
await this.program.methods.authorizeViews(reader, Array.from(viewKey), expiresAt, 15).accountsPartial({ owner: this.owner, market: marketAddress7(), permit }).rpc({ commitment: "confirmed" });
|
|
47166
|
+
disabled.delete(this.scope);
|
|
47167
|
+
await this.storage?.write("disabled", false);
|
|
47168
|
+
})().finally(() => approvals.delete(id));
|
|
47169
|
+
approvals.set(id, approval);
|
|
47170
|
+
return approval;
|
|
47171
|
+
}
|
|
47172
|
+
async revoke() {
|
|
47173
|
+
const { permit } = await this.keys();
|
|
47174
|
+
const signature = await this.program.methods.revokeViews().accountsPartial({ owner: this.owner, permit }).rpc({ commitment: "confirmed" });
|
|
47175
|
+
disabled.add(this.scope);
|
|
47176
|
+
await this.storage?.write("disabled", true);
|
|
47177
|
+
return signature;
|
|
47178
|
+
}
|
|
47179
|
+
async post(request, action) {
|
|
47180
|
+
const { signing } = await this.keys();
|
|
47181
|
+
request.expiresAt = Math.floor(Date.now() / 1000) + 120;
|
|
47182
|
+
request.signature = Buffer2.from(await sign(new TextEncoder().encode(viewMessage(DEPTH_PROGRAM_ID7.toBase58(), request, action)), signing)).toString("base64");
|
|
47183
|
+
return fetch(`${this.serviceUrl}/v1/views${action === "close" ? "/close" : ""}`, {
|
|
47184
|
+
method: "POST",
|
|
47185
|
+
headers: { "content-type": "application/json" },
|
|
47186
|
+
body: JSON.stringify(request),
|
|
47187
|
+
signal: AbortSignal.timeout(60000)
|
|
47188
|
+
});
|
|
47189
|
+
}
|
|
47190
|
+
request(kind, source) {
|
|
47191
|
+
const key = `${this.scope}:${kind}:${source.toBase58()}`;
|
|
47192
|
+
const pending = requests.get(key);
|
|
47193
|
+
if (pending)
|
|
47194
|
+
return pending;
|
|
47195
|
+
const request = this.read(kind, source).finally(() => requests.delete(key));
|
|
47196
|
+
requests.set(key, request);
|
|
47197
|
+
return request;
|
|
47198
|
+
}
|
|
47199
|
+
async read(kind, source, retry = true) {
|
|
47200
|
+
if (disabled.has(this.scope) || await this.storage?.read("disabled"))
|
|
47201
|
+
throw new Error("Private reads are disabled on this device");
|
|
47202
|
+
await this.authorize();
|
|
47203
|
+
const keys = await this.keys();
|
|
47204
|
+
const name2 = `request:${kind}:${source.toBase58()}`;
|
|
47205
|
+
let pending = this.pending.get(name2) ?? await this.storage?.read(name2);
|
|
47206
|
+
if (!pending) {
|
|
47207
|
+
pending = { nonce: new anchor8.BN(randomBytes3(8), "le").toString() };
|
|
47208
|
+
await this.storage?.write(name2, pending);
|
|
47209
|
+
this.pending.set(name2, pending);
|
|
47210
|
+
}
|
|
47211
|
+
const request = {
|
|
47212
|
+
owner: this.owner.toBase58(),
|
|
47213
|
+
reader: keys.reader.toBase58(),
|
|
47214
|
+
permit: keys.permit.toBase58(),
|
|
47215
|
+
kind,
|
|
47216
|
+
source: source.toBase58(),
|
|
47217
|
+
nonce: pending.nonce,
|
|
47218
|
+
expiresAt: 0,
|
|
47219
|
+
signature: ""
|
|
47220
|
+
};
|
|
47221
|
+
const response = await this.post(request, "read");
|
|
47222
|
+
if (response.status === 410 && retry) {
|
|
47223
|
+
this.pending.delete(name2);
|
|
47224
|
+
await this.storage?.write(name2, null);
|
|
47225
|
+
return this.read(kind, source, false);
|
|
47226
|
+
}
|
|
47227
|
+
if (!response.ok) {
|
|
47228
|
+
const error = await response.json().catch(() => ({}));
|
|
47229
|
+
if (error.error === "view_source_busy")
|
|
47230
|
+
throw new Error("Private account is processing another operation");
|
|
47231
|
+
throw new Error(`Private read service returned HTTP ${response.status}`);
|
|
47232
|
+
}
|
|
47233
|
+
const receipt = await response.json();
|
|
47234
|
+
const payer = new PublicKey10(receipt.payer);
|
|
47235
|
+
const nonce = new anchor8.BN(request.nonce).toArrayLike(Buffer2, "le", 8);
|
|
47236
|
+
const seeds = kind === "balance" ? [Buffer2.from("view"), payer.toBuffer(), nonce] : kind === "market" ? [Buffer2.from("market-view"), source.toBuffer(), nonce] : [
|
|
47237
|
+
Buffer2.from(`${kind}-view`),
|
|
47238
|
+
source.toBuffer(),
|
|
47239
|
+
payer.toBuffer(),
|
|
47240
|
+
nonce
|
|
47241
|
+
];
|
|
47242
|
+
const id = PublicKey10.findProgramAddressSync(seeds, DEPTH_PROGRAM_ID7)[0];
|
|
47243
|
+
if (receipt.id !== id.toBase58() || typeof receipt.signature !== "string")
|
|
47244
|
+
throw new Error("Invalid private read receipt");
|
|
47245
|
+
const mxeKey = await getMXEPublicKey(this.program.provider, DEPTH_PROGRAM_ID7);
|
|
47246
|
+
if (!mxeKey)
|
|
47247
|
+
throw new Error("MXE public key is unavailable");
|
|
47248
|
+
return new DepthView(id, receipt.signature, kind, payer, keys.secret, keys.viewKey, mxeKey, this.program, this.connection, source, async () => {
|
|
47249
|
+
this.pending.delete(name2);
|
|
47250
|
+
await this.storage?.write(name2, null);
|
|
47251
|
+
try {
|
|
47252
|
+
await this.post(request, "close");
|
|
47253
|
+
} catch {}
|
|
47254
|
+
return "";
|
|
47255
|
+
});
|
|
47256
|
+
}
|
|
47257
|
+
}
|
|
47258
|
+
|
|
46994
47259
|
// src/client/client.ts
|
|
46995
|
-
function pda(seeds, programId =
|
|
46996
|
-
return
|
|
47260
|
+
function pda(seeds, programId = DEPTH_PROGRAM_ID8) {
|
|
47261
|
+
return PublicKey11.findProgramAddressSync(seeds, programId)[0];
|
|
46997
47262
|
}
|
|
46998
47263
|
function nonce() {
|
|
46999
|
-
return new
|
|
47264
|
+
return new anchor9.BN(randomBytes3(8), "le");
|
|
47000
47265
|
}
|
|
47001
47266
|
function enumName2(value2) {
|
|
47002
47267
|
return Object.keys(value2)[0] ?? "unknown";
|
|
@@ -47006,12 +47271,13 @@ class DepthClient {
|
|
|
47006
47271
|
options;
|
|
47007
47272
|
program;
|
|
47008
47273
|
provider;
|
|
47274
|
+
viewCache;
|
|
47009
47275
|
views;
|
|
47010
47276
|
viewReads = new Map;
|
|
47011
47277
|
position;
|
|
47012
|
-
marketAddress =
|
|
47278
|
+
marketAddress = marketAddress8();
|
|
47013
47279
|
protocolAddress = protocolAddress4();
|
|
47014
|
-
mxeAddress = getMXEAccAddress(
|
|
47280
|
+
mxeAddress = getMXEAccAddress(DEPTH_PROGRAM_ID8);
|
|
47015
47281
|
get catalog() {
|
|
47016
47282
|
return new MarketCatalog(this);
|
|
47017
47283
|
}
|
|
@@ -47030,16 +47296,19 @@ class DepthClient {
|
|
|
47030
47296
|
}
|
|
47031
47297
|
constructor(options) {
|
|
47032
47298
|
this.options = options;
|
|
47033
|
-
|
|
47299
|
+
const scope = `${"manifest" in options.deployment ? options.deployment.manifest.payload.genesisHash : "localnet"}:${DEPTH_PROGRAM_ID8.toBase58()}:${options.wallet.publicKey.toBase58()}`;
|
|
47300
|
+
const storage = options.privateViews === "device" && "manifest" in options.deployment && typeof indexedDB !== "undefined" && globalThis.crypto?.subtle ? new DeviceViews : undefined;
|
|
47301
|
+
this.viewCache = new ViewCache(scope, storage);
|
|
47034
47302
|
this.provider = new DepthProvider(options.connection, options.wallet, {
|
|
47035
47303
|
commitment: "confirmed",
|
|
47036
47304
|
preflightCommitment: "confirmed"
|
|
47037
47305
|
});
|
|
47038
|
-
this.program = new
|
|
47306
|
+
this.program = new anchor9.Program(DEPTH_IDL3, this.provider);
|
|
47307
|
+
this.views = new ViewSession(this.program, options.connection, options.wallet.publicKey, options.serviceUrl, scope, storage);
|
|
47039
47308
|
this.position = this.positionActions();
|
|
47040
47309
|
}
|
|
47041
47310
|
static async create(options) {
|
|
47042
|
-
const appId = typeof options.appId === "string" ? new
|
|
47311
|
+
const appId = typeof options.appId === "string" ? new PublicKey11(options.appId) : options.appId;
|
|
47043
47312
|
const resolved = {
|
|
47044
47313
|
...options,
|
|
47045
47314
|
...await resolveConnection(options),
|
|
@@ -47052,7 +47321,7 @@ class DepthClient {
|
|
|
47052
47321
|
}
|
|
47053
47322
|
async verifyDeployment() {
|
|
47054
47323
|
const [programInfo, protocol, market, app, mxe] = await Promise.all([
|
|
47055
|
-
this.options.connection.getAccountInfo(
|
|
47324
|
+
this.options.connection.getAccountInfo(DEPTH_PROGRAM_ID8, "confirmed"),
|
|
47056
47325
|
this.read("Protocol", this.protocolAddress),
|
|
47057
47326
|
this.read("Market", this.marketAddress),
|
|
47058
47327
|
this.options.appId ? this.read("AppConfig", appAddress2(this.options.appId)) : Promise.resolve(undefined),
|
|
@@ -47060,13 +47329,13 @@ class DepthClient {
|
|
|
47060
47329
|
]);
|
|
47061
47330
|
if (!programInfo?.executable)
|
|
47062
47331
|
throw new Error("Depth program is not deployed");
|
|
47063
|
-
if (!market.settlementMint.equals(protocol.settlementMint) || !market.vault.equals(protocol.vault) || this.options.appId && !app?.app.equals(this.options.appId) || !mxe.mxeProgramId.equals(
|
|
47332
|
+
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_ID8)) {
|
|
47064
47333
|
throw new Error("Depth deployment accounts disagree");
|
|
47065
47334
|
}
|
|
47066
47335
|
}
|
|
47067
47336
|
async read(name2, address2) {
|
|
47068
47337
|
const info = await this.options.connection.getAccountInfo(address2, "confirmed");
|
|
47069
|
-
if (!info || !info.owner.equals(
|
|
47338
|
+
if (!info || !info.owner.equals(DEPTH_PROGRAM_ID8)) {
|
|
47070
47339
|
throw new Error(`${name2} account is unavailable`);
|
|
47071
47340
|
}
|
|
47072
47341
|
return this.program.coder.accounts.decode(name2[0].toLowerCase() + name2.slice(1), info.data);
|
|
@@ -47074,7 +47343,7 @@ class DepthClient {
|
|
|
47074
47343
|
async queue(name2, offset2) {
|
|
47075
47344
|
const mxe = await arciumAccount(this.provider).fetch(this.mxeAddress);
|
|
47076
47345
|
const cluster = mxe.cluster;
|
|
47077
|
-
const definition = getCompDefAccAddress(
|
|
47346
|
+
const definition = getCompDefAccAddress(DEPTH_PROGRAM_ID8, Buffer2.from(getCompDefAccOffset(computationName(name2))).readUInt32LE());
|
|
47078
47347
|
const definitionInfo = await this.options.connection.getAccountInfo(definition, "confirmed");
|
|
47079
47348
|
if (!definitionInfo)
|
|
47080
47349
|
throw new Error(`${name2} computation is not deployed`);
|
|
@@ -47096,7 +47365,7 @@ class DepthClient {
|
|
|
47096
47365
|
}
|
|
47097
47366
|
async market() {
|
|
47098
47367
|
const response = await this.options.connection.getAccountInfoAndContext(this.marketAddress, "confirmed");
|
|
47099
|
-
if (!response.value || !response.value.owner.equals(
|
|
47368
|
+
if (!response.value || !response.value.owner.equals(DEPTH_PROGRAM_ID8)) {
|
|
47100
47369
|
throw new Error("Depth market is unavailable");
|
|
47101
47370
|
}
|
|
47102
47371
|
return {
|
|
@@ -47108,6 +47377,22 @@ class DepthClient {
|
|
|
47108
47377
|
operation(id) {
|
|
47109
47378
|
return new DepthOperation(id, undefined, this.program, this.options.connection, (order) => this.requestFillView(order));
|
|
47110
47379
|
}
|
|
47380
|
+
async requestQuoteView(quote) {
|
|
47381
|
+
const record = await this.read("QuoteRecord", quote);
|
|
47382
|
+
if (!record.maker.equals(this.options.wallet.publicKey) || !record.market.equals(this.marketAddress) || !["active", "closing"].includes(enumName2(record.status)))
|
|
47383
|
+
throw new Error("Active quote does not belong to this wallet and market");
|
|
47384
|
+
const viewNonce = nonce();
|
|
47385
|
+
const view = pda([
|
|
47386
|
+
Buffer2.from("quote-view"),
|
|
47387
|
+
quote.toBuffer(),
|
|
47388
|
+
this.options.wallet.publicKey.toBuffer(),
|
|
47389
|
+
viewNonce.toArrayLike(Buffer2, "le", 8)
|
|
47390
|
+
]);
|
|
47391
|
+
return this.requestView("quote", view, viewNonce, {
|
|
47392
|
+
market: this.marketAddress,
|
|
47393
|
+
quote
|
|
47394
|
+
});
|
|
47395
|
+
}
|
|
47111
47396
|
async requestBalanceView() {
|
|
47112
47397
|
const owner = this.options.wallet.publicKey;
|
|
47113
47398
|
const balance = pda([Buffer2.from("balance"), owner.toBuffer()]);
|
|
@@ -47155,14 +47440,17 @@ class DepthClient {
|
|
|
47155
47440
|
return this.requestView("fill", view, viewNonce, { order });
|
|
47156
47441
|
}
|
|
47157
47442
|
async requestView(kind, view, viewNonce, accounts2) {
|
|
47158
|
-
const
|
|
47443
|
+
const source = accounts2.balance ?? accounts2.marketAccount ?? accounts2.order ?? accounts2.quote;
|
|
47444
|
+
if (this.options.viewAuthorization === "session" || this.options.viewAuthorization !== "wallet" && this.options.privateViews === "device" && this.options.serviceUrl)
|
|
47445
|
+
return this.views.request(kind, source);
|
|
47446
|
+
const mxePublicKey = await getMXEPublicKey(this.provider, DEPTH_PROGRAM_ID8);
|
|
47159
47447
|
if (!mxePublicKey)
|
|
47160
47448
|
throw new Error("MXE public key is unavailable");
|
|
47161
47449
|
const secret = x25519.utils.randomSecretKey();
|
|
47162
47450
|
const publicKey = x25519.getPublicKey(secret);
|
|
47163
47451
|
const offset2 = nonce();
|
|
47164
|
-
const queue = await this.queue(kind === "balance" ? "view_balance" : kind === "market" ? "view_market" : "view_fill", offset2);
|
|
47165
|
-
const builder = kind === "balance" ? this.program.methods.requestBalanceView : kind === "market" ? this.program.methods.requestMarketView : this.program.methods.requestFillView;
|
|
47452
|
+
const queue = await this.queue(kind === "balance" ? "view_balance" : kind === "market" ? "view_market" : kind === "fill" ? "view_fill" : "view_quote", offset2);
|
|
47453
|
+
const builder = kind === "balance" ? this.program.methods.requestBalanceView : kind === "market" ? this.program.methods.requestMarketView : kind === "fill" ? this.program.methods.requestFillView : this.program.methods.requestQuoteView;
|
|
47166
47454
|
const signature = await builder(offset2, viewNonce, Array.from(publicKey)).accountsPartial({
|
|
47167
47455
|
...queue,
|
|
47168
47456
|
payer: this.options.wallet.publicKey,
|
|
@@ -47170,7 +47458,7 @@ class DepthClient {
|
|
|
47170
47458
|
...kind === "balance" ? {} : { grant: null },
|
|
47171
47459
|
view
|
|
47172
47460
|
}).rpc({ commitment: "confirmed" });
|
|
47173
|
-
return new DepthView(view, signature, kind, this.options.wallet.publicKey, secret, publicKey, mxePublicKey, this.program, this.options.connection);
|
|
47461
|
+
return new DepthView(view, signature, kind, this.options.wallet.publicKey, secret, publicKey, mxePublicKey, this.program, this.options.connection, source);
|
|
47174
47462
|
}
|
|
47175
47463
|
async ensureBalanceReady() {
|
|
47176
47464
|
const address2 = this.funding.balance;
|
|
@@ -47257,7 +47545,7 @@ class DepthClient {
|
|
|
47257
47545
|
return this.funding.release(amount, clientNonce ?? BigInt(nonce().toString()));
|
|
47258
47546
|
}
|
|
47259
47547
|
async depositRequest(sourceOrAmount, amount, clientNonce) {
|
|
47260
|
-
if (sourceOrAmount instanceof
|
|
47548
|
+
if (sourceOrAmount instanceof PublicKey11) {
|
|
47261
47549
|
if (amount === undefined || clientNonce === undefined)
|
|
47262
47550
|
throw new RangeError("Source deposits require amount and client nonce");
|
|
47263
47551
|
return this.funding.deposit(sourceOrAmount, amount, clientNonce);
|
|
@@ -47268,7 +47556,7 @@ class DepthClient {
|
|
|
47268
47556
|
return this.funding.deposit(source, sourceOrAmount, amount ?? BigInt(nonce().toString()));
|
|
47269
47557
|
}
|
|
47270
47558
|
async withdrawRequest(destinationOrAmount, amount, clientNonce) {
|
|
47271
|
-
if (destinationOrAmount instanceof
|
|
47559
|
+
if (destinationOrAmount instanceof PublicKey11) {
|
|
47272
47560
|
if (amount === undefined || clientNonce === undefined)
|
|
47273
47561
|
throw new RangeError("Destination withdrawals require amount and client nonce");
|
|
47274
47562
|
return this.funding.withdraw(destinationOrAmount, amount, clientNonce);
|
|
@@ -47386,7 +47674,13 @@ class DepthClient {
|
|
|
47386
47674
|
]);
|
|
47387
47675
|
}
|
|
47388
47676
|
async deferViewClose(kind, id) {
|
|
47389
|
-
const view = new
|
|
47677
|
+
const view = new PublicKey11(id);
|
|
47678
|
+
const info = await this.options.connection.getAccountInfo(view, "confirmed");
|
|
47679
|
+
if (!info?.owner.equals(DEPTH_PROGRAM_ID8))
|
|
47680
|
+
return;
|
|
47681
|
+
const receipt = this.program.coder.accounts.decode(kind === "balance" ? "balanceView" : "marketView", info.data);
|
|
47682
|
+
if (!receipt.owner.equals(this.options.wallet.publicKey) || "pending" in receipt.status)
|
|
47683
|
+
return;
|
|
47390
47684
|
const method = kind === "balance" ? this.program.methods.closeBalanceView : this.program.methods.closeMarketView;
|
|
47391
47685
|
this.provider.deferClose(view, await method().accountsPartial({
|
|
47392
47686
|
owner: this.options.wallet.publicKey,
|
|
@@ -47396,7 +47690,7 @@ class DepthClient {
|
|
|
47396
47690
|
async viewState(kind, id) {
|
|
47397
47691
|
if (kind === "balance")
|
|
47398
47692
|
return this.account().state();
|
|
47399
|
-
const state = await this.read("MarketAccount", new
|
|
47693
|
+
const state = await this.read("MarketAccount", new PublicKey11(id));
|
|
47400
47694
|
if (!state.owner.equals(this.options.wallet.publicKey) || !state.market.equals(this.marketAddress))
|
|
47401
47695
|
throw new Error("Position does not belong to this wallet and market");
|
|
47402
47696
|
return {
|
|
@@ -47423,7 +47717,7 @@ class DepthClient {
|
|
|
47423
47717
|
for (;; ) {
|
|
47424
47718
|
const state = await this.viewState(kind, id);
|
|
47425
47719
|
if (state.status === "ready") {
|
|
47426
|
-
const cached = await this.
|
|
47720
|
+
const cached = await this.viewCache.get(kind, id, state.version);
|
|
47427
47721
|
if (cached) {
|
|
47428
47722
|
await this.deferViewClose(kind, cached.id);
|
|
47429
47723
|
return cached;
|
|
@@ -47436,11 +47730,11 @@ class DepthClient {
|
|
|
47436
47730
|
});
|
|
47437
47731
|
if (result.status === "pending")
|
|
47438
47732
|
return result;
|
|
47439
|
-
await
|
|
47733
|
+
await view.deferClose();
|
|
47440
47734
|
const latest = await this.viewState(kind, id);
|
|
47441
47735
|
if (result.status === "ready" && latest.status === "ready" && latest.version === result.version) {
|
|
47442
47736
|
const snapshot = { ...result, readAt: Date.now() };
|
|
47443
|
-
await this.
|
|
47737
|
+
await this.viewCache.set(kind, id, snapshot);
|
|
47444
47738
|
return snapshot;
|
|
47445
47739
|
}
|
|
47446
47740
|
} catch (error) {
|
|
@@ -47540,11 +47834,11 @@ class DepthClient {
|
|
|
47540
47834
|
const keys = [market.state.backstopOffer, ...quotes];
|
|
47541
47835
|
const records = await this.options.connection.getMultipleAccountsInfo(keys, "confirmed");
|
|
47542
47836
|
records.forEach((info, index) => {
|
|
47543
|
-
if (!info?.owner.equals(
|
|
47837
|
+
if (!info?.owner.equals(DEPTH_PROGRAM_ID8)) {
|
|
47544
47838
|
throw new Error(`Market quote snapshot missing account ${index}`);
|
|
47545
47839
|
}
|
|
47546
47840
|
});
|
|
47547
|
-
const mxePublicKey = await getMXEPublicKey(this.provider,
|
|
47841
|
+
const mxePublicKey = await getMXEPublicKey(this.provider, DEPTH_PROGRAM_ID8);
|
|
47548
47842
|
if (!mxePublicKey)
|
|
47549
47843
|
throw new Error("MXE public key is unavailable");
|
|
47550
47844
|
const secret = x25519.utils.randomSecretKey();
|
|
@@ -47562,7 +47856,7 @@ class DepthClient {
|
|
|
47562
47856
|
}), inputNonce);
|
|
47563
47857
|
const offset2 = nonce();
|
|
47564
47858
|
const queue = await this.queue("match_order", offset2);
|
|
47565
|
-
const signature = await this.program.methods.submitOrder(offset2, orderNonce, appId, app.feeBps, app.version, new
|
|
47859
|
+
const signature = await this.program.methods.submitOrder(offset2, orderNonce, appId, app.feeBps, app.version, new anchor9.BN(deadline), market.state.revision, market.state.oracleTimestamp, ciphertexts, Array.from(inputKey), new anchor9.BN(inputNonce, "le")).accountsPartial({
|
|
47566
47860
|
...queue,
|
|
47567
47861
|
trader: this.options.wallet.publicKey,
|
|
47568
47862
|
protocol: this.protocolAddress,
|
|
@@ -47786,6 +48080,7 @@ export {
|
|
|
47786
48080
|
captureDeployment,
|
|
47787
48081
|
authenticateManifest,
|
|
47788
48082
|
WithdrawalHandle,
|
|
48083
|
+
ViewSession,
|
|
47789
48084
|
TransferHandle,
|
|
47790
48085
|
TradeFlow,
|
|
47791
48086
|
MarketData,
|
package/dist/view/cache.d.ts
CHANGED
|
@@ -17,6 +17,15 @@ export declare class DeviceViews implements ViewStorage {
|
|
|
17
17
|
read(id: string): Promise<Envelope | undefined>;
|
|
18
18
|
write(id: string, value: Envelope): Promise<void>;
|
|
19
19
|
}
|
|
20
|
+
export declare class EncryptedViews {
|
|
21
|
+
private readonly scope;
|
|
22
|
+
private readonly storage;
|
|
23
|
+
private key?;
|
|
24
|
+
constructor(scope: string, storage: ViewStorage);
|
|
25
|
+
private encryptionKey;
|
|
26
|
+
read<T>(name: string): Promise<T | undefined>;
|
|
27
|
+
write(name: string, value: unknown): Promise<void>;
|
|
28
|
+
}
|
|
20
29
|
export declare class ViewCache {
|
|
21
30
|
private readonly scope;
|
|
22
31
|
private readonly storage?;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import * as anchor from "@anchor-lang/core";
|
|
2
|
+
import { type ViewKind } from "@depthhq/schema";
|
|
3
|
+
import { PublicKey, type Connection } from "@solana/web3.js";
|
|
4
|
+
import { type ViewStorage } from "./cache.js";
|
|
5
|
+
import { DepthView } from "./view.js";
|
|
6
|
+
export declare class ViewSession {
|
|
7
|
+
private readonly program;
|
|
8
|
+
private readonly connection;
|
|
9
|
+
private readonly owner;
|
|
10
|
+
private readonly serviceUrl;
|
|
11
|
+
private readonly scope;
|
|
12
|
+
private readonly storage?;
|
|
13
|
+
private readonly pending;
|
|
14
|
+
constructor(program: anchor.Program, connection: Connection, owner: PublicKey, serviceUrl: string | undefined, scope: string, storage?: ViewStorage);
|
|
15
|
+
private identity;
|
|
16
|
+
private keys;
|
|
17
|
+
status(): Promise<{
|
|
18
|
+
active: boolean;
|
|
19
|
+
expiresAt?: number;
|
|
20
|
+
id: string;
|
|
21
|
+
}>;
|
|
22
|
+
private capability;
|
|
23
|
+
authorize(): Promise<void>;
|
|
24
|
+
revoke(): Promise<string>;
|
|
25
|
+
private post;
|
|
26
|
+
request(kind: ViewKind, source: PublicKey): Promise<DepthView>;
|
|
27
|
+
private read;
|
|
28
|
+
}
|
package/dist/view/view.d.ts
CHANGED
|
@@ -51,7 +51,9 @@ export declare class DepthView {
|
|
|
51
51
|
private readonly mxePublicKey;
|
|
52
52
|
private readonly program;
|
|
53
53
|
private readonly connection;
|
|
54
|
-
|
|
54
|
+
private readonly source?;
|
|
55
|
+
private readonly release?;
|
|
56
|
+
constructor(id: PublicKey, signature: string, kind: "balance" | "market" | "fill" | "quote", owner: PublicKey, secret: Uint8Array, publicKey: Uint8Array, mxePublicKey: Uint8Array, program: anchor.Program, connection: Connection, source?: PublicKey | undefined, release?: (() => Promise<string>) | undefined);
|
|
55
57
|
status(): Promise<BalanceSnapshot | PositionSnapshot | FillSnapshot | QuoteBalanceSnapshot>;
|
|
56
58
|
wait(options: {
|
|
57
59
|
timeoutMs: number;
|
package/dist/view/view.js
CHANGED
|
@@ -26583,7 +26583,9 @@ class DepthView {
|
|
|
26583
26583
|
mxePublicKey;
|
|
26584
26584
|
program;
|
|
26585
26585
|
connection;
|
|
26586
|
-
|
|
26586
|
+
source;
|
|
26587
|
+
release;
|
|
26588
|
+
constructor(id, signature, kind, owner, secret, publicKey, mxePublicKey, program, connection, source, release) {
|
|
26587
26589
|
this.id = id;
|
|
26588
26590
|
this.signature = signature;
|
|
26589
26591
|
this.kind = kind;
|
|
@@ -26593,6 +26595,8 @@ class DepthView {
|
|
|
26593
26595
|
this.mxePublicKey = mxePublicKey;
|
|
26594
26596
|
this.program = program;
|
|
26595
26597
|
this.connection = connection;
|
|
26598
|
+
this.source = source;
|
|
26599
|
+
this.release = release;
|
|
26596
26600
|
}
|
|
26597
26601
|
async status() {
|
|
26598
26602
|
const response = await this.connection.getAccountInfoAndContext(this.id, "confirmed");
|
|
@@ -26603,6 +26607,9 @@ class DepthView {
|
|
|
26603
26607
|
if (!state.owner.equals(this.owner) || !Buffer.from(state.viewKey).equals(Buffer.from(this.publicKey))) {
|
|
26604
26608
|
throw new Error("Private view authorization does not match this request");
|
|
26605
26609
|
}
|
|
26610
|
+
const source = this.kind === "balance" ? state.balance : this.kind === "market" ? state.marketAccount : this.kind === "fill" ? state.order : state.quote;
|
|
26611
|
+
if (this.source && !source?.equals(this.source))
|
|
26612
|
+
throw new Error("Private view source does not match this request");
|
|
26606
26613
|
const current = Object.keys(state.status)[0];
|
|
26607
26614
|
if (current !== "pending" && current !== "ready" && current !== "stale") {
|
|
26608
26615
|
throw new Error("Private view has an unknown status");
|
|
@@ -26668,6 +26675,10 @@ class DepthView {
|
|
|
26668
26675
|
}
|
|
26669
26676
|
}
|
|
26670
26677
|
async deferClose() {
|
|
26678
|
+
if (this.release) {
|
|
26679
|
+
await this.close();
|
|
26680
|
+
return;
|
|
26681
|
+
}
|
|
26671
26682
|
const provider = this.program.provider;
|
|
26672
26683
|
if (typeof provider.deferClose !== "function") {
|
|
26673
26684
|
await this.close();
|
|
@@ -26688,6 +26699,8 @@ class DepthView {
|
|
|
26688
26699
|
if (snapshot.status === "pending") {
|
|
26689
26700
|
throw new Error("Private view computation is still pending");
|
|
26690
26701
|
}
|
|
26702
|
+
if (this.release)
|
|
26703
|
+
return this.release();
|
|
26691
26704
|
return this.closeBuilder().rpc({ commitment: "confirmed" });
|
|
26692
26705
|
}
|
|
26693
26706
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@depthhq/sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -44,8 +44,8 @@
|
|
|
44
44
|
"@noble/hashes": "1.8.0",
|
|
45
45
|
"@solana/web3.js": "1.99.0",
|
|
46
46
|
"buffer": "6.0.3",
|
|
47
|
-
"@depthhq/
|
|
48
|
-
"@depthhq/
|
|
47
|
+
"@depthhq/schema": "0.1.2",
|
|
48
|
+
"@depthhq/bindings": "0.1.2"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"fake-indexeddb": "6.2.4"
|