@candledottv/agent-sdk 0.5.0 → 0.6.1
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 +78 -8
- package/dist/client.d.ts +294 -20
- package/dist/client.d.ts.map +1 -1
- package/dist/errors.d.ts +137 -5
- package/dist/errors.d.ts.map +1 -1
- package/dist/hyperliquid.d.ts +43 -1
- package/dist/hyperliquid.d.ts.map +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +372 -41
- package/dist/plans.d.ts +1 -1
- package/dist/plans.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@ var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
|
3
3
|
|
|
4
4
|
// src/client.ts
|
|
5
5
|
import { keccak_256 as keccak_2562 } from "@noble/hashes/sha3";
|
|
6
|
+
import { base58 as base582 } from "@scure/base";
|
|
6
7
|
|
|
7
8
|
// src/authorization-signature.ts
|
|
8
9
|
import canonicalize from "canonicalize";
|
|
@@ -78,6 +79,7 @@ async function buildPrivyAuthorizationSignature(params) {
|
|
|
78
79
|
var BRIDGE_ERROR_CODES = ["BRIDGE_DESTINATION_MISSING", "RELAY_STEP_REFUSED", "BRIDGE_IN_FLIGHT"];
|
|
79
80
|
|
|
80
81
|
class CandleApiError extends Error {
|
|
82
|
+
legs;
|
|
81
83
|
code;
|
|
82
84
|
status;
|
|
83
85
|
retryable;
|
|
@@ -94,9 +96,12 @@ class CandleApiError extends Error {
|
|
|
94
96
|
feeRaw;
|
|
95
97
|
quoteAsset;
|
|
96
98
|
treasury;
|
|
99
|
+
reason;
|
|
100
|
+
retryAfter;
|
|
97
101
|
constructor(args) {
|
|
98
102
|
super(args.message);
|
|
99
103
|
this.name = "CandleApiError";
|
|
104
|
+
this.legs = args.legs;
|
|
100
105
|
this.code = args.code;
|
|
101
106
|
this.status = args.status;
|
|
102
107
|
this.retryable = args.retryable;
|
|
@@ -121,6 +126,45 @@ class CandleApiError extends Error {
|
|
|
121
126
|
this.quoteAsset = args.quoteAsset;
|
|
122
127
|
if (args.treasury !== undefined)
|
|
123
128
|
this.treasury = args.treasury;
|
|
129
|
+
if (args.reason !== undefined)
|
|
130
|
+
this.reason = args.reason;
|
|
131
|
+
if (args.retryAfter !== undefined)
|
|
132
|
+
this.retryAfter = args.retryAfter;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
class TradeLegOutcomeError extends Error {
|
|
137
|
+
clientTradeId;
|
|
138
|
+
leg;
|
|
139
|
+
outcome;
|
|
140
|
+
txHash;
|
|
141
|
+
landedLegs;
|
|
142
|
+
cause;
|
|
143
|
+
constructor(args) {
|
|
144
|
+
super((args.cause instanceof Error ? args.cause.message + ". " : "") + "A Hood trade leg failed. Inspect txHash and landedLegs on chain; read getTradeJob(clientTradeId) or call trade with the same id and body for Candle's view. Never retry a retryable:false answer.", { cause: args.cause });
|
|
145
|
+
this.name = "TradeLegOutcomeError";
|
|
146
|
+
this.clientTradeId = args.clientTradeId;
|
|
147
|
+
this.leg = args.leg;
|
|
148
|
+
this.outcome = args.outcome;
|
|
149
|
+
this.txHash = args.txHash;
|
|
150
|
+
this.landedLegs = args.landedLegs;
|
|
151
|
+
this.cause = args.cause;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
class TradeLandedUnconfirmedError extends Error {
|
|
156
|
+
clientTradeId;
|
|
157
|
+
tradeTxHash;
|
|
158
|
+
feeTxHash;
|
|
159
|
+
stage = "executed";
|
|
160
|
+
cause;
|
|
161
|
+
constructor(args) {
|
|
162
|
+
super("The trade is on chain and not booked. Read getTradeJob(clientTradeId) before calling confirmTrade again with these hashes. If the row is failed, this id cannot be recorded with /confirm; retain the hashes and do not retry or rebuild.", { cause: args.cause });
|
|
163
|
+
this.name = "TradeLandedUnconfirmedError";
|
|
164
|
+
this.clientTradeId = args.clientTradeId;
|
|
165
|
+
this.tradeTxHash = args.tradeTxHash;
|
|
166
|
+
this.feeTxHash = args.feeTxHash;
|
|
167
|
+
this.cause = args.cause;
|
|
124
168
|
}
|
|
125
169
|
}
|
|
126
170
|
|
|
@@ -142,6 +186,42 @@ class TradeLandedFeeLegError extends Error {
|
|
|
142
186
|
this.feeTxHash = args.feeTxHash;
|
|
143
187
|
}
|
|
144
188
|
}
|
|
189
|
+
function selfLaunchOutcomeMessage(args) {
|
|
190
|
+
const reason = args.cause instanceof Error ? args.cause.message : String(args.cause);
|
|
191
|
+
const feeTxHash = "feeTxHash" in args ? args.feeTxHash : undefined;
|
|
192
|
+
const head = `launch executed; ${args.step === "confirm" ? "confirmation" : "fee"} incomplete: the Hood curve is on chain ` + `(createCurveTxHash ${args.createCurveTxHash}, clientLaunchId ${args.clientLaunchId}), and a later step ` + `failed (${reason}). Do NOT call selfLaunch() or buildSelfLaunch() again for this attempt, under this id ` + `or a new one: a rebuild can create a second curve. Keep the id and every hash on this error.`;
|
|
193
|
+
const confirmWith = (fee) => `confirmSelfLaunch({ clientLaunchId, signature: createCurveTxHash${fee} }) for clientLaunchId ${args.clientLaunchId}`;
|
|
194
|
+
if (args.step === "confirm") {
|
|
195
|
+
const fee = args.feeOutcome === "landed" ? `The fee transfer landed (feeTxHash ${feeTxHash}).` : "This build had no fee transfer, so none is owed.";
|
|
196
|
+
return `${head} ${fee} The confirm call was refused or its answer was lost, so Candle may or may not have ` + `recorded the launch: read getLaunchJob(clientLaunchId). If the job is not confirmed and this error's ` + `cause allows it, call ${confirmWith(args.feeOutcome === "landed" ? ", feeTxHash" : "")} with these same ` + `hashes. Nothing needs signing or sending.`;
|
|
197
|
+
}
|
|
198
|
+
if (args.feeOutcome === "unknown") {
|
|
199
|
+
return `${head} The fee transfer MAY have paid: its outcome is unknown. Do NOT pay it again. ` + (feeTxHash ? `Check feeTxHash ${feeTxHash} and the payer wallet's history; a hash alone does not prove payment. ` : "Its hash is not known: reconcile the payer wallet's transactions before any payment decision. ") + `Once that exact fee is verified successful, call ${confirmWith(", feeTxHash")}.`;
|
|
200
|
+
}
|
|
201
|
+
const proof = args.feeOutcome === "reverted" ? `its receipt reverted${feeTxHash ? ` (feeTxHash ${feeTxHash})` : ""}` : `it was not broadcast${feeTxHash ? ` (feeTxHash ${feeTxHash} names the refused transaction, not a payment)` : ""}`;
|
|
202
|
+
return `${head} The fee transfer did NOT pay: ${proof}. The launch is not recorded without it. Pay only the ` + `missing fee, to the original build's treasury in its quote asset and raw amount, then call ` + `${confirmWith(", feeTxHash")} with the successful fee hash.`;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
class SelfLaunchOutcomeError extends Error {
|
|
206
|
+
name = "SelfLaunchOutcomeError";
|
|
207
|
+
chain = "hood";
|
|
208
|
+
clientLaunchId;
|
|
209
|
+
createCurveTxHash;
|
|
210
|
+
stage = "executed";
|
|
211
|
+
step;
|
|
212
|
+
feeOutcome;
|
|
213
|
+
cause;
|
|
214
|
+
constructor(args) {
|
|
215
|
+
super(selfLaunchOutcomeMessage(args), { cause: args.cause });
|
|
216
|
+
this.clientLaunchId = args.clientLaunchId;
|
|
217
|
+
this.createCurveTxHash = args.createCurveTxHash;
|
|
218
|
+
this.step = args.step;
|
|
219
|
+
this.feeOutcome = args.feeOutcome;
|
|
220
|
+
if ("feeTxHash" in args && args.feeTxHash !== undefined)
|
|
221
|
+
this.feeTxHash = args.feeTxHash;
|
|
222
|
+
this.cause = args.cause;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
145
225
|
function isSolanaRpcErrorData(data) {
|
|
146
226
|
if (typeof data !== "object" || data === null)
|
|
147
227
|
return false;
|
|
@@ -191,7 +271,7 @@ function definedIds(ids) {
|
|
|
191
271
|
};
|
|
192
272
|
}
|
|
193
273
|
function operationIds(error) {
|
|
194
|
-
if (error instanceof CandleApiError || error instanceof JsonRpcError || error instanceof TradeLandedFeeLegError || error instanceof CandleOperationError) {
|
|
274
|
+
if (error instanceof CandleApiError || error instanceof JsonRpcError || error instanceof TradeLandedFeeLegError || error instanceof TradeLegOutcomeError || error instanceof TradeLandedUnconfirmedError || error instanceof SelfLaunchOutcomeError || error instanceof CandleOperationError) {
|
|
195
275
|
return definedIds(error);
|
|
196
276
|
}
|
|
197
277
|
return {};
|
|
@@ -199,7 +279,7 @@ function operationIds(error) {
|
|
|
199
279
|
function withOperationIds(error, ids, flow) {
|
|
200
280
|
if (error instanceof CandleApiError || error instanceof JsonRpcError)
|
|
201
281
|
return Object.assign(error, definedIds(ids));
|
|
202
|
-
if (error instanceof TradeLandedFeeLegError)
|
|
282
|
+
if (error instanceof TradeLandedFeeLegError || error instanceof TradeLegOutcomeError || error instanceof TradeLandedUnconfirmedError || error instanceof SelfLaunchOutcomeError)
|
|
203
283
|
return error;
|
|
204
284
|
if (error instanceof CandleOperationError) {
|
|
205
285
|
return new CandleOperationError({ cause: error.cause, ids: { ...operationIds(error), ...definedIds(ids) }, flow });
|
|
@@ -227,13 +307,16 @@ function envelopeError(body) {
|
|
|
227
307
|
message: error.message,
|
|
228
308
|
...typeof error.field === "string" ? { field: error.field } : {},
|
|
229
309
|
...typeof error.retryable === "boolean" ? { retryable: error.retryable } : {},
|
|
310
|
+
...Array.isArray(error.legs) ? { legs: error.legs } : {},
|
|
230
311
|
...typeof error.stage === "string" ? { stage: error.stage } : {},
|
|
231
312
|
...typeof error.signature === "string" ? { signature: error.signature } : {},
|
|
232
313
|
...typeof error.mint === "string" ? { mint: error.mint } : {},
|
|
233
314
|
...typeof error.recorded === "boolean" ? { recorded: error.recorded } : {},
|
|
234
315
|
...typeof error.feeRaw === "string" ? { feeRaw: error.feeRaw } : {},
|
|
235
316
|
...typeof error.quoteAsset === "string" ? { quoteAsset: error.quoteAsset } : {},
|
|
236
|
-
...typeof error.treasury === "string" ? { treasury: error.treasury } : {}
|
|
317
|
+
...typeof error.treasury === "string" ? { treasury: error.treasury } : {},
|
|
318
|
+
...typeof error.reason === "string" ? { reason: error.reason } : {},
|
|
319
|
+
...typeof error.retryAfter === "number" ? { retryAfter: error.retryAfter } : {}
|
|
237
320
|
};
|
|
238
321
|
}
|
|
239
322
|
function candleApiErrorFromResponse(status, bodyText) {
|
|
@@ -368,6 +451,10 @@ var HYPERLIQUID_EXCHANGE_URLS = {
|
|
|
368
451
|
mainnet: "https://api.hyperliquid.xyz/exchange",
|
|
369
452
|
testnet: "https://api.hyperliquid-testnet.xyz/exchange"
|
|
370
453
|
};
|
|
454
|
+
var HYPERLIQUID_INFO_URLS = {
|
|
455
|
+
mainnet: "https://api.hyperliquid.xyz/info",
|
|
456
|
+
testnet: "https://api.hyperliquid-testnet.xyz/info"
|
|
457
|
+
};
|
|
371
458
|
var CANDLE_HYPERLIQUID_BUILDER_ADDRESS = null;
|
|
372
459
|
var HYPERLIQUID_MAX_BUILDER_FEE_TENTHS_BPS = 100;
|
|
373
460
|
var HYPERLIQUID_MAX_BUILDER_FEE_RATE = "0.1%";
|
|
@@ -670,6 +757,67 @@ async function hyperliquidCloseOrder(fetcher, network, address, params) {
|
|
|
670
757
|
const size = asked < held ? String(params.size) : String(szi).replace(/^-/, "");
|
|
671
758
|
return { asset, isBuy: signed < 0n, size };
|
|
672
759
|
}
|
|
760
|
+
var HYPERLIQUID_DEFAULT_SLIPPAGE_BPS = 100;
|
|
761
|
+
var HYPERLIQUID_MID_DRIFT_BPS = 100;
|
|
762
|
+
async function hyperliquidOrderMarket(fetcher, network, address, method, params) {
|
|
763
|
+
const read = async (body) => {
|
|
764
|
+
const res = await fetcher(HYPERLIQUID_INFO_URLS[network], {
|
|
765
|
+
method: "POST",
|
|
766
|
+
headers: { "content-type": "application/json" },
|
|
767
|
+
body: JSON.stringify(body)
|
|
768
|
+
});
|
|
769
|
+
if (!res.ok)
|
|
770
|
+
throw new Error("Cannot read the market from Hyperliquid");
|
|
771
|
+
return JSON.parse(await res.text());
|
|
772
|
+
};
|
|
773
|
+
let coin = String(params.coin ?? "").toUpperCase();
|
|
774
|
+
let order;
|
|
775
|
+
if (method === "modify") {
|
|
776
|
+
const status = await read({ type: "orderStatus", user: address, oid: params.cloid });
|
|
777
|
+
const resting = status?.order?.order ?? null;
|
|
778
|
+
if (!resting || typeof resting.coin !== "string" || decimal(resting.limitPx) === null)
|
|
779
|
+
throw new Error("No resting order with this cloid on Hyperliquid");
|
|
780
|
+
coin = resting.coin.toUpperCase();
|
|
781
|
+
order = { isBuy: resting.side === "B", limitPx: String(resting.limitPx) };
|
|
782
|
+
}
|
|
783
|
+
const [meta, contexts] = await read({ type: "metaAndAssetCtxs" });
|
|
784
|
+
const asset = meta.universe.findIndex((m) => m.name.toUpperCase() === coin);
|
|
785
|
+
if (asset < 0 || asset >= 1e4)
|
|
786
|
+
throw new Error("No main-universe market for this coin on Hyperliquid");
|
|
787
|
+
const context = contexts[asset];
|
|
788
|
+
const midPx = context?.midPx ?? context?.markPx;
|
|
789
|
+
if ((decimal(midPx) ?? 0n) <= 0n)
|
|
790
|
+
throw new Error("No Hyperliquid price for this coin");
|
|
791
|
+
return { asset, midPx: String(midPx), ...order ? { order } : {} };
|
|
792
|
+
}
|
|
793
|
+
function checkOrderMarket(action, intent, market) {
|
|
794
|
+
const list = action.type === "modify" ? [action.order] : action.orders;
|
|
795
|
+
if (!Array.isArray(list) || list.length === 0)
|
|
796
|
+
return "missing requested order";
|
|
797
|
+
if (list.some((o) => !o || o.a !== market.asset))
|
|
798
|
+
return "order asset is not the requested coin's on Hyperliquid";
|
|
799
|
+
const first = list[0];
|
|
800
|
+
const p = intent.params;
|
|
801
|
+
if (intent.method === "open" && p.price == null) {
|
|
802
|
+
const requested = p.slippageBps;
|
|
803
|
+
const slippage = typeof requested === "number" && Number.isInteger(requested) && requested > 0 ? requested : HYPERLIQUID_DEFAULT_SLIPPAGE_BPS;
|
|
804
|
+
const bound = BigInt(slippage + HYPERLIQUID_MID_DRIFT_BPS);
|
|
805
|
+
const px = decimal(first.p) ?? 0n;
|
|
806
|
+
const mid = decimal(market.midPx) ?? 0n;
|
|
807
|
+
const within = first.b === true ? px * 10000n <= mid * (10000n + bound) : px * 10000n >= mid * (10000n - bound);
|
|
808
|
+
if (mid <= 0n || !within)
|
|
809
|
+
return "market order price is outside its slippage of Hyperliquid's mid";
|
|
810
|
+
}
|
|
811
|
+
if (intent.method === "modify") {
|
|
812
|
+
if (!market.order)
|
|
813
|
+
return "no resting order on Hyperliquid to check the modify against";
|
|
814
|
+
if (first.b !== market.order.isBuy)
|
|
815
|
+
return "modify changes the resting order's side";
|
|
816
|
+
if (p.price == null && decimal(first.p) !== decimal(market.order.limitPx))
|
|
817
|
+
return "modify changes the resting order's price";
|
|
818
|
+
}
|
|
819
|
+
return null;
|
|
820
|
+
}
|
|
673
821
|
function verifyPerpsBuild(build, opts) {
|
|
674
822
|
try {
|
|
675
823
|
const network = opts.network ?? "mainnet";
|
|
@@ -697,6 +845,13 @@ function verifyPerpsBuild(build, opts) {
|
|
|
697
845
|
if (!order || order.a !== opts.closeOrder.asset || order.b !== opts.closeOrder.isBuy || decimal(order.s) !== decimal(opts.closeOrder.size) || order.r !== true)
|
|
698
846
|
return { ok: false, reason: "close side, asset or size does not match the requested position" };
|
|
699
847
|
}
|
|
848
|
+
if (opts.market) {
|
|
849
|
+
if (opts.intent?.method !== "open" && opts.intent?.method !== "modify")
|
|
850
|
+
return { ok: false, reason: "a market check needs an open or modify intent" };
|
|
851
|
+
const marketRefusal = checkOrderMarket(action, opts.intent, opts.market);
|
|
852
|
+
if (marketRefusal)
|
|
853
|
+
return { ok: false, reason: marketRefusal };
|
|
854
|
+
}
|
|
700
855
|
if (typed.primary_type === "Agent") {
|
|
701
856
|
const type = action.type;
|
|
702
857
|
if (typeof type !== "string" || !HYPERLIQUID_ALLOWED_ACTION_TYPES.includes(type)) {
|
|
@@ -989,6 +1144,47 @@ function assertTransportSecurity(apiUrl, allowInsecureHttp) {
|
|
|
989
1144
|
return;
|
|
990
1145
|
throw new Error(`CandleClient: refusing to send credentials in the clear to ${parsed.origin}. Use https://.` + (isPrivateHost(parsed.hostname) ? " Pass allowInsecureHttp: true if this really is a trusted local endpoint." : " allowInsecureHttp does not apply here: it covers private networks only, and this is a" + " public address."));
|
|
991
1146
|
}
|
|
1147
|
+
var REDIRECT_STATUSES = new Set([301, 302, 303, 307, 308]);
|
|
1148
|
+
var MAX_REDIRECTS = 5;
|
|
1149
|
+
|
|
1150
|
+
class CrossOriginRedirectError extends Error {
|
|
1151
|
+
from;
|
|
1152
|
+
to;
|
|
1153
|
+
constructor(from, to) {
|
|
1154
|
+
super(`The API at ${from} redirected to ${to}, another origin. Not followed, so the API key was not sent there.`);
|
|
1155
|
+
this.from = from;
|
|
1156
|
+
this.to = to;
|
|
1157
|
+
this.name = "CrossOriginRedirectError";
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
function keyedRedirectGuard(doFetch) {
|
|
1161
|
+
const guarded = async (input, init) => {
|
|
1162
|
+
if (input instanceof Request || !init?.headers || !new Headers(init.headers).has("x-api-key")) {
|
|
1163
|
+
return doFetch(input, init);
|
|
1164
|
+
}
|
|
1165
|
+
const url = input.toString();
|
|
1166
|
+
let current = url;
|
|
1167
|
+
let next = { ...init, redirect: "manual" };
|
|
1168
|
+
for (let hops = 0;; hops++) {
|
|
1169
|
+
const response = await doFetch(current, next);
|
|
1170
|
+
const location = REDIRECT_STATUSES.has(response.status) ? response.headers?.get?.("location") : null;
|
|
1171
|
+
if (!location)
|
|
1172
|
+
return response;
|
|
1173
|
+
const from = new URL(current);
|
|
1174
|
+
const target = new URL(location, from);
|
|
1175
|
+
if (target.origin !== from.origin)
|
|
1176
|
+
throw new CrossOriginRedirectError(from.origin, target.origin);
|
|
1177
|
+
if (hops >= MAX_REDIRECTS)
|
|
1178
|
+
throw new Error(`More than ${MAX_REDIRECTS} redirects from ${url}`);
|
|
1179
|
+
const method = (next.method ?? "GET").toUpperCase();
|
|
1180
|
+
if (response.status === 303 && method !== "GET" && method !== "HEAD" || (response.status === 301 || response.status === 302) && method === "POST") {
|
|
1181
|
+
next = { ...next, method: "GET", body: undefined };
|
|
1182
|
+
}
|
|
1183
|
+
current = target.href;
|
|
1184
|
+
}
|
|
1185
|
+
};
|
|
1186
|
+
return guarded;
|
|
1187
|
+
}
|
|
992
1188
|
|
|
993
1189
|
class CandleClient {
|
|
994
1190
|
apiUrl;
|
|
@@ -1060,7 +1256,7 @@ class CandleClient {
|
|
|
1060
1256
|
this.apiUrl = opts.apiUrl.replace(/\/+$/, "");
|
|
1061
1257
|
if (opts.apiKey !== undefined)
|
|
1062
1258
|
this.apiKey = opts.apiKey;
|
|
1063
|
-
this.fetchImpl = opts.fetch ?? fetch;
|
|
1259
|
+
this.fetchImpl = keyedRedirectGuard(opts.fetch ?? fetch);
|
|
1064
1260
|
if (opts.maxRetries !== undefined && (!Number.isInteger(opts.maxRetries) || opts.maxRetries < 0)) {
|
|
1065
1261
|
throw new Error(`CandleClient: maxRetries must be a non-negative integer, got ${opts.maxRetries}`);
|
|
1066
1262
|
}
|
|
@@ -1119,6 +1315,45 @@ class CandleClient {
|
|
|
1119
1315
|
async verify(chain, mint) {
|
|
1120
1316
|
return this.requestJson("GET", `/api/v1/verify/${chain}/${encodeURIComponent(mint)}`);
|
|
1121
1317
|
}
|
|
1318
|
+
async getOwnProfile() {
|
|
1319
|
+
this.requireKey("getOwnProfile()");
|
|
1320
|
+
return this.requestJson("GET", "/api/v1/agent/keys/self/public-profile");
|
|
1321
|
+
}
|
|
1322
|
+
async updateOwnProfile(patch) {
|
|
1323
|
+
this.requireKey("updateOwnProfile()");
|
|
1324
|
+
return this.requestJson("PATCH", "/api/v1/agent/keys/self/public-profile", patch);
|
|
1325
|
+
}
|
|
1326
|
+
async uploadProfileImage(kind, bytes, contentType) {
|
|
1327
|
+
this.requireKey("uploadProfileImage()");
|
|
1328
|
+
const form = new FormData;
|
|
1329
|
+
form.set("kind", kind);
|
|
1330
|
+
form.set("image", new Blob([bytes], { type: contentType }), "profile.image");
|
|
1331
|
+
const headers = this.headers();
|
|
1332
|
+
delete headers["Content-Type"];
|
|
1333
|
+
const res = await this.fetchImpl(`${this.apiUrl}/api/v1/uploads/agent-profile-image`, {
|
|
1334
|
+
method: "POST",
|
|
1335
|
+
headers,
|
|
1336
|
+
body: form
|
|
1337
|
+
});
|
|
1338
|
+
return this.parseResponse(res);
|
|
1339
|
+
}
|
|
1340
|
+
async createPost(req) {
|
|
1341
|
+
this.requireKey("createPost()");
|
|
1342
|
+
return this.requestJson("POST", "/api/v1/agent/posts", req);
|
|
1343
|
+
}
|
|
1344
|
+
async deletePost(postId) {
|
|
1345
|
+
this.requireKey("deletePost()");
|
|
1346
|
+
return this.requestJson("DELETE", `/api/v1/agent/posts/${encodeURIComponent(postId)}`);
|
|
1347
|
+
}
|
|
1348
|
+
async listAgentPosts(profileId, options = {}) {
|
|
1349
|
+
const params = new URLSearchParams;
|
|
1350
|
+
if (options.limit !== undefined)
|
|
1351
|
+
params.set("limit", String(options.limit));
|
|
1352
|
+
if (options.cursor !== undefined)
|
|
1353
|
+
params.set("cursor", options.cursor);
|
|
1354
|
+
const body = await this.requestJson("GET", `/api/v1/agent/records/${encodeURIComponent(profileId)}/posts${params.size ? `?${params}` : ""}`);
|
|
1355
|
+
return { posts: body.posts, cursor: body.cursor ?? null };
|
|
1356
|
+
}
|
|
1122
1357
|
async getAgentProfile(idOrWallet) {
|
|
1123
1358
|
const body = await this.requestJson("GET", `/api/v1/users/${encodeURIComponent(idOrWallet)}/agent`);
|
|
1124
1359
|
return body.agent;
|
|
@@ -1456,6 +1691,7 @@ class CandleClient {
|
|
|
1456
1691
|
if (built.artifacts.feeTransfer) {
|
|
1457
1692
|
legs.push({ kind: "feeTransfer", ...built.artifacts.feeTransfer });
|
|
1458
1693
|
}
|
|
1694
|
+
const landedLegs = [];
|
|
1459
1695
|
let tradeTxHash;
|
|
1460
1696
|
let feeTxHash;
|
|
1461
1697
|
for (let i = 0;i < legs.length; i++) {
|
|
@@ -1475,13 +1711,24 @@ class CandleClient {
|
|
|
1475
1711
|
feeData,
|
|
1476
1712
|
linkedWalletId,
|
|
1477
1713
|
privyWalletId
|
|
1478
|
-
}, { surfaceLegOutcome:
|
|
1714
|
+
}, { surfaceLegOutcome: true });
|
|
1479
1715
|
} catch (err) {
|
|
1480
1716
|
if (leg.kind === "feeTransfer" && tradeTxHash) {
|
|
1481
1717
|
throw tradeLandedFeeLegError({ clientTradeId: built.clientTradeId, tradeTxHash, err });
|
|
1482
1718
|
}
|
|
1483
|
-
|
|
1719
|
+
if (err instanceof EvmLegOutcome && err.txHash !== undefined || landedLegs.length > 0) {
|
|
1720
|
+
throw new TradeLegOutcomeError({
|
|
1721
|
+
clientTradeId: built.clientTradeId,
|
|
1722
|
+
leg: leg.kind,
|
|
1723
|
+
outcome: err instanceof EvmLegOutcome ? err.kind : "not-broadcast",
|
|
1724
|
+
txHash: err instanceof EvmLegOutcome ? err.txHash : undefined,
|
|
1725
|
+
landedLegs: [...landedLegs],
|
|
1726
|
+
cause: err instanceof EvmLegOutcome ? err.cause : err
|
|
1727
|
+
});
|
|
1728
|
+
}
|
|
1729
|
+
throw err instanceof EvmLegOutcome ? err.cause : err;
|
|
1484
1730
|
}
|
|
1731
|
+
landedLegs.push({ leg: leg.kind, txHash });
|
|
1485
1732
|
if (leg.kind === "trade")
|
|
1486
1733
|
tradeTxHash = txHash;
|
|
1487
1734
|
if (leg.kind === "feeTransfer")
|
|
@@ -1490,11 +1737,15 @@ class CandleClient {
|
|
|
1490
1737
|
if (!tradeTxHash) {
|
|
1491
1738
|
throw new Error("trade(): Hood leg sequence completed without a trade leg");
|
|
1492
1739
|
}
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1740
|
+
try {
|
|
1741
|
+
return await this.confirmTrade({
|
|
1742
|
+
clientTradeId: built.clientTradeId,
|
|
1743
|
+
tradeTxHash,
|
|
1744
|
+
...feeTxHash ? { feeTxHash } : {}
|
|
1745
|
+
});
|
|
1746
|
+
} catch (cause) {
|
|
1747
|
+
throw new TradeLandedUnconfirmedError({ clientTradeId: built.clientTradeId, tradeTxHash, feeTxHash, cause });
|
|
1748
|
+
}
|
|
1498
1749
|
}
|
|
1499
1750
|
async selfLaunch(req) {
|
|
1500
1751
|
const { privyWalletId, ...launchReq } = req;
|
|
@@ -1506,27 +1757,44 @@ class CandleClient {
|
|
|
1506
1757
|
const built = await this.postSelfLaunchBuild(body, op);
|
|
1507
1758
|
if (typeof built.transaction === "string") {
|
|
1508
1759
|
let unsignedTransactionBase64 = built.transaction;
|
|
1509
|
-
let
|
|
1760
|
+
let clientLaunchId2 = built.clientLaunchId;
|
|
1761
|
+
let signed;
|
|
1510
1762
|
for (let attempt = 0;attempt <= MAX_BLOCKHASH_REBUILDS; attempt++) {
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1763
|
+
if (signed?.forTransaction !== unsignedTransactionBase64) {
|
|
1764
|
+
const result = await this.signLinkedTransaction({
|
|
1765
|
+
linkedWalletId: body.linkedWalletId,
|
|
1766
|
+
privyWalletId,
|
|
1767
|
+
chain: "solana",
|
|
1768
|
+
unsignedTransactionBase64
|
|
1769
|
+
});
|
|
1770
|
+
signed = { forTransaction: unsignedTransactionBase64, ...result };
|
|
1771
|
+
}
|
|
1517
1772
|
try {
|
|
1518
1773
|
const signature = await this.broadcastSignedTransaction("solana", signed.signedTransaction, signed.encoding);
|
|
1519
|
-
return this.confirmSelfLaunch({ clientLaunchId, signature });
|
|
1774
|
+
return this.confirmSelfLaunch({ clientLaunchId: clientLaunchId2, signature });
|
|
1520
1775
|
} catch (error) {
|
|
1521
1776
|
if (!isBlockhashExpiry(error))
|
|
1522
1777
|
throw error;
|
|
1523
1778
|
if (attempt === MAX_BLOCKHASH_REBUILDS)
|
|
1524
1779
|
throw withRpcLagHint(error);
|
|
1525
|
-
|
|
1780
|
+
let rebuilt;
|
|
1781
|
+
try {
|
|
1782
|
+
rebuilt = await this.postSelfLaunchBuild(body, op);
|
|
1783
|
+
} catch (buildError) {
|
|
1784
|
+
const reason = buildError instanceof CandleApiError ? buildError.reason : undefined;
|
|
1785
|
+
if (reason === "prior_attempt_in_flight")
|
|
1786
|
+
continue;
|
|
1787
|
+
if (reason === "prior_attempt_on_chain") {
|
|
1788
|
+
const signature = solanaSignedTxSignature(signed.signedTransaction, signed.encoding);
|
|
1789
|
+
if (signature)
|
|
1790
|
+
return this.confirmSelfLaunch({ clientLaunchId: clientLaunchId2, signature });
|
|
1791
|
+
}
|
|
1792
|
+
throw buildError;
|
|
1793
|
+
}
|
|
1526
1794
|
if (typeof rebuilt.transaction !== "string")
|
|
1527
1795
|
throw error;
|
|
1528
1796
|
unsignedTransactionBase64 = rebuilt.transaction;
|
|
1529
|
-
|
|
1797
|
+
clientLaunchId2 = rebuilt.clientLaunchId;
|
|
1530
1798
|
}
|
|
1531
1799
|
}
|
|
1532
1800
|
throw new Error("selfLaunch(): blockhash-rebuild loop exited without returning or throwing");
|
|
@@ -1552,26 +1820,41 @@ class CandleClient {
|
|
|
1552
1820
|
linkedWalletId: body.linkedWalletId,
|
|
1553
1821
|
privyWalletId
|
|
1554
1822
|
});
|
|
1823
|
+
const clientLaunchId = built.clientLaunchId;
|
|
1555
1824
|
let feeTxHash;
|
|
1556
1825
|
if (hoodBuilt.feeTransfer) {
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1826
|
+
try {
|
|
1827
|
+
feeTxHash = await this.signBroadcastAndWaitEvmLeg({
|
|
1828
|
+
rpc,
|
|
1829
|
+
from,
|
|
1830
|
+
to: hoodBuilt.feeTransfer.to,
|
|
1831
|
+
data: hoodBuilt.feeTransfer.data,
|
|
1832
|
+
valueDecimal: hoodBuilt.feeTransfer.value,
|
|
1833
|
+
nonce: baseNonce + 1,
|
|
1834
|
+
chainId,
|
|
1835
|
+
feeData,
|
|
1836
|
+
linkedWalletId: body.linkedWalletId,
|
|
1837
|
+
privyWalletId
|
|
1838
|
+
}, { surfaceLegOutcome: true });
|
|
1839
|
+
} catch (err) {
|
|
1840
|
+
throw selfLaunchFeeLegError({ clientLaunchId, createCurveTxHash, err });
|
|
1841
|
+
}
|
|
1842
|
+
}
|
|
1843
|
+
try {
|
|
1844
|
+
return await this.confirmSelfLaunch({
|
|
1845
|
+
clientLaunchId,
|
|
1846
|
+
signature: createCurveTxHash,
|
|
1847
|
+
...feeTxHash ? { feeTxHash } : {}
|
|
1848
|
+
});
|
|
1849
|
+
} catch (cause) {
|
|
1850
|
+
throw new SelfLaunchOutcomeError({
|
|
1851
|
+
clientLaunchId,
|
|
1852
|
+
createCurveTxHash,
|
|
1853
|
+
step: "confirm",
|
|
1854
|
+
...feeTxHash ? { feeOutcome: "landed", feeTxHash } : { feeOutcome: "not-required" },
|
|
1855
|
+
cause
|
|
1568
1856
|
});
|
|
1569
1857
|
}
|
|
1570
|
-
return this.confirmSelfLaunch({
|
|
1571
|
-
clientLaunchId: built.clientLaunchId,
|
|
1572
|
-
signature: createCurveTxHash,
|
|
1573
|
-
...feeTxHash ? { feeTxHash } : {}
|
|
1574
|
-
});
|
|
1575
1858
|
}
|
|
1576
1859
|
async buildAtomicLaunch(req) {
|
|
1577
1860
|
this.requireKey("buildAtomicLaunch()");
|
|
@@ -1693,7 +1976,7 @@ class CandleClient {
|
|
|
1693
1976
|
if (!isDefiniteBroadcastRejection(err)) {
|
|
1694
1977
|
throw new EvmLegOutcome({ kind: "unknown", txHash: predicted, cause: err });
|
|
1695
1978
|
}
|
|
1696
|
-
throw err;
|
|
1979
|
+
throw new EvmLegOutcome({ kind: "not-broadcast", txHash: predicted, cause: err });
|
|
1697
1980
|
}
|
|
1698
1981
|
try {
|
|
1699
1982
|
await waitForReceipt(params.rpc, txHash, evmReceiptWaitForTest ?? {});
|
|
@@ -1891,6 +2174,17 @@ class CandleClient {
|
|
|
1891
2174
|
if (!closeCheck.ok)
|
|
1892
2175
|
throw new Error(`perps: refused to sign this build: ${closeCheck.reason}`);
|
|
1893
2176
|
}
|
|
2177
|
+
if (method === "open" || method === "modify") {
|
|
2178
|
+
const market = await hyperliquidOrderMarket(this.fetchImpl, this.hyperliquidNetwork, build.address, method, ref);
|
|
2179
|
+
const marketCheck = verifyPerpsBuild(build, {
|
|
2180
|
+
builder: await this.perpsBuilder(),
|
|
2181
|
+
network: this.hyperliquidNetwork,
|
|
2182
|
+
intent: { method, params: ref },
|
|
2183
|
+
market
|
|
2184
|
+
});
|
|
2185
|
+
if (!marketCheck.ok)
|
|
2186
|
+
throw new Error(`perps: refused to sign this build: ${marketCheck.reason}`);
|
|
2187
|
+
}
|
|
1894
2188
|
if (ref.submit === false)
|
|
1895
2189
|
return { build, signature: null, submitted: false, exchange: null };
|
|
1896
2190
|
const signature = await this.signLinkedTypedData({
|
|
@@ -2050,7 +2344,7 @@ function tradeLandedFeeLegError(args) {
|
|
|
2050
2344
|
tradeTxHash: args.tradeTxHash,
|
|
2051
2345
|
cause: args.err.cause,
|
|
2052
2346
|
feeOutcome: args.err.kind,
|
|
2053
|
-
...args.err.txHash !== undefined ? { feeTxHash: args.err.txHash } : {}
|
|
2347
|
+
...args.err.kind !== "not-broadcast" && args.err.txHash !== undefined ? { feeTxHash: args.err.txHash } : {}
|
|
2054
2348
|
});
|
|
2055
2349
|
}
|
|
2056
2350
|
return new TradeLandedFeeLegError({
|
|
@@ -2060,6 +2354,38 @@ function tradeLandedFeeLegError(args) {
|
|
|
2060
2354
|
feeOutcome: "not-broadcast"
|
|
2061
2355
|
});
|
|
2062
2356
|
}
|
|
2357
|
+
function selfLaunchFeeLegError(args) {
|
|
2358
|
+
const outcome = args.err instanceof EvmLegOutcome ? args.err : undefined;
|
|
2359
|
+
return new SelfLaunchOutcomeError({
|
|
2360
|
+
clientLaunchId: args.clientLaunchId,
|
|
2361
|
+
createCurveTxHash: args.createCurveTxHash,
|
|
2362
|
+
step: "feeTransfer",
|
|
2363
|
+
feeOutcome: outcome?.kind ?? "not-broadcast",
|
|
2364
|
+
...outcome?.txHash !== undefined ? { feeTxHash: outcome.txHash } : {},
|
|
2365
|
+
cause: outcome ? outcome.cause : args.err
|
|
2366
|
+
});
|
|
2367
|
+
}
|
|
2368
|
+
function solanaSignedTxSignature(signedTransaction, encoding) {
|
|
2369
|
+
const enc = encoding.toLowerCase();
|
|
2370
|
+
let bytes;
|
|
2371
|
+
try {
|
|
2372
|
+
if (enc === "base64")
|
|
2373
|
+
bytes = fromBase64(signedTransaction);
|
|
2374
|
+
else if (enc === "base58")
|
|
2375
|
+
bytes = base582.decode(signedTransaction);
|
|
2376
|
+
else
|
|
2377
|
+
return;
|
|
2378
|
+
} catch {
|
|
2379
|
+
return;
|
|
2380
|
+
}
|
|
2381
|
+
const count = bytes[0];
|
|
2382
|
+
if (count === undefined || count === 0 || count >= 128 || bytes.length < 1 + count * 64)
|
|
2383
|
+
return;
|
|
2384
|
+
const first = bytes.subarray(1, 65);
|
|
2385
|
+
if (first.every((byte) => byte === 0))
|
|
2386
|
+
return;
|
|
2387
|
+
return base582.encode(first);
|
|
2388
|
+
}
|
|
2063
2389
|
function evmSignedTxHash(signedTransaction, encoding) {
|
|
2064
2390
|
const enc = encoding.toLowerCase();
|
|
2065
2391
|
let bytes;
|
|
@@ -2098,7 +2424,7 @@ function generateClientLaunchId() {
|
|
|
2098
2424
|
function generateClientTradeId() {
|
|
2099
2425
|
return generateSdkId();
|
|
2100
2426
|
}
|
|
2101
|
-
var SDK_VERSION = "0.
|
|
2427
|
+
var SDK_VERSION = "0.6.1";
|
|
2102
2428
|
var sdkUpdateWarned = false;
|
|
2103
2429
|
function noteLatestSdkVersion(value) {
|
|
2104
2430
|
if (sdkUpdateWarned || !value || !/^\d+\.\d+\.\d+$/.test(value))
|
|
@@ -2237,7 +2563,7 @@ var PLAN_CAPABILITY_LABELS = {
|
|
|
2237
2563
|
createLinkedWallets: "Create linked wallets",
|
|
2238
2564
|
importLinkedWallets: "Import linked wallets",
|
|
2239
2565
|
limitOrders: "Limit orders",
|
|
2240
|
-
quant: "Quant
|
|
2566
|
+
quant: "Quant deep analyses (Max)"
|
|
2241
2567
|
};
|
|
2242
2568
|
var PLAN_LABELS = { free: "Free", believer: "Believer", pro: "Pro", max: "Max" };
|
|
2243
2569
|
function planLabel(plan) {
|
|
@@ -2464,11 +2790,15 @@ export {
|
|
|
2464
2790
|
perpsDepositProblem,
|
|
2465
2791
|
operationIds,
|
|
2466
2792
|
isSolanaRpcErrorData,
|
|
2793
|
+
hyperliquidOrderMarket,
|
|
2467
2794
|
hyperliquidActionHash,
|
|
2468
2795
|
generateSignerKeypair,
|
|
2469
2796
|
formatPlanBps,
|
|
2470
2797
|
encryptWalletKeyForImport,
|
|
2798
|
+
TradeLegOutcomeError,
|
|
2799
|
+
TradeLandedUnconfirmedError,
|
|
2471
2800
|
TradeLandedFeeLegError,
|
|
2801
|
+
SelfLaunchOutcomeError,
|
|
2472
2802
|
PLAN_CAPABILITY_NOTE,
|
|
2473
2803
|
PLAN_CAPABILITY_LABELS,
|
|
2474
2804
|
KeychainSecretStore,
|
|
@@ -2477,6 +2807,7 @@ export {
|
|
|
2477
2807
|
HYPERLIQUID_EXCHANGE_URLS,
|
|
2478
2808
|
HYPERLIQUID_ALLOWED_ACTION_TYPES,
|
|
2479
2809
|
EncryptedFileSecretStore,
|
|
2810
|
+
CrossOriginRedirectError,
|
|
2480
2811
|
CandleOperationError,
|
|
2481
2812
|
CandleClient,
|
|
2482
2813
|
CandleApiError,
|
package/dist/plans.d.ts
CHANGED
|
@@ -46,7 +46,7 @@ export interface PlanCapabilities {
|
|
|
46
46
|
/** Plan eligibility only: whether perps are open on the deployment is its own switch, and trading needs the wallet and scopes. */
|
|
47
47
|
hyperliquidPerps: boolean;
|
|
48
48
|
limitOrders: boolean;
|
|
49
|
-
/**
|
|
49
|
+
/** Max-level Quant: the deep `run_analysis` studies. Pro also has Quant, on Telegram and in Candle, but by its plan name, not this flag. */
|
|
50
50
|
quant: boolean;
|
|
51
51
|
/** Base-pair swaps and base-asset bridges between the key's own wallets carry no Candle fee. A bridge also needs its own deployment switch. */
|
|
52
52
|
freeBaseTransfers: boolean;
|
package/dist/plans.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plans.d.ts","sourceRoot":"","sources":["../src/plans.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,UAAU,CAAA;AAE1D,yFAAyF;AACzF,MAAM,WAAW,SAAS;IACxB,gBAAgB,EAAE,MAAM,CAAA;IACxB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,qGAAqG;AACrG,MAAM,WAAW,UAAU;IACzB,eAAe,EAAE,MAAM,CAAA;IACvB,cAAc,EAAE,MAAM,CAAA;IACtB,aAAa,EAAE,MAAM,CAAA;IACrB,0DAA0D;IAC1D,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,yEAAyE;AACzE,MAAM,WAAW,gBAAgB;IAC/B,2EAA2E;IAC3E,iBAAiB,EAAE,OAAO,CAAA;IAC1B,sFAAsF;IACtF,kBAAkB,EAAE,OAAO,CAAA;IAC3B,eAAe,EAAE,OAAO,CAAA;IACxB,iBAAiB,EAAE,OAAO,CAAA;IAC1B,UAAU,EAAE,OAAO,CAAA;IACnB,YAAY,EAAE,OAAO,CAAA;IACrB,mBAAmB,EAAE,OAAO,CAAA;IAC5B,mBAAmB,EAAE,OAAO,CAAA;IAC5B,kIAAkI;IAClI,gBAAgB,EAAE,OAAO,CAAA;IACzB,WAAW,EAAE,OAAO,CAAA;IACpB,
|
|
1
|
+
{"version":3,"file":"plans.d.ts","sourceRoot":"","sources":["../src/plans.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,UAAU,CAAA;AAE1D,yFAAyF;AACzF,MAAM,WAAW,SAAS;IACxB,gBAAgB,EAAE,MAAM,CAAA;IACxB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,qGAAqG;AACrG,MAAM,WAAW,UAAU;IACzB,eAAe,EAAE,MAAM,CAAA;IACvB,cAAc,EAAE,MAAM,CAAA;IACtB,aAAa,EAAE,MAAM,CAAA;IACrB,0DAA0D;IAC1D,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,yEAAyE;AACzE,MAAM,WAAW,gBAAgB;IAC/B,2EAA2E;IAC3E,iBAAiB,EAAE,OAAO,CAAA;IAC1B,sFAAsF;IACtF,kBAAkB,EAAE,OAAO,CAAA;IAC3B,eAAe,EAAE,OAAO,CAAA;IACxB,iBAAiB,EAAE,OAAO,CAAA;IAC1B,UAAU,EAAE,OAAO,CAAA;IACnB,YAAY,EAAE,OAAO,CAAA;IACrB,mBAAmB,EAAE,OAAO,CAAA;IAC5B,mBAAmB,EAAE,OAAO,CAAA;IAC5B,kIAAkI;IAClI,gBAAgB,EAAE,OAAO,CAAA;IACzB,WAAW,EAAE,OAAO,CAAA;IACpB,4IAA4I;IAC5I,KAAK,EAAE,OAAO,CAAA;IACd,+IAA+I;IAC/I,iBAAiB,EAAE,OAAO,CAAA;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,QAAQ,CAAA;IACd;;;OAGG;IACH,YAAY,CAAC,EAAE,gBAAgB,CAAA;IAC/B,2FAA2F;IAC3F,MAAM,EAAE,MAAM,CAAA;IACd,0DAA0D;IAC1D,UAAU,EAAE,MAAM,CAAA;IAClB,4FAA4F;IAC5F,KAAK,EAAE,SAAS,GAAG,IAAI,CAAA;IACvB,MAAM,EAAE,UAAU,CAAA;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,cAAc,EAAE,CAAA;IACvB,6EAA6E;IAC7E,YAAY,EAAE,MAAM,CAAA;CACrB;AAED,iCAAiC;AACjC,MAAM,WAAW,gBAAiB,SAAQ,SAAS;IACjD,OAAO,EAAE,IAAI,CAAA;CACd;AAED;;;GAGG;AACH,eAAO,MAAM,oBAAoB,ibAC+Y,CAAA;AAEhb,0EAA0E;AAC1E,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,MAAM,gBAAgB,EAAE,MAAM,CAazE,CAAA;AAID,mEAAmE;AACnE,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED,6EAA6E;AAC7E,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEjD;AAWD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,GAAG;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAA;CAAE,CA+BvF;AAED,+DAA+D;AAC/D,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI,CAIjE;AAED,iGAAiG;AACjG,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAI1D"}
|
package/package.json
CHANGED