@parchment-trade/sdk 0.0.0-stage → 1.0.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/LICENSE +202 -0
- package/README.md +193 -2
- package/REFERENCE.md +338 -0
- package/SECURITY.md +25 -0
- package/dist/general/providers/index.d.ts +2 -0
- package/dist/general/providers/index.js +2 -0
- package/dist/general/providers/parchment.d.ts +1 -0
- package/dist/general/providers/parchment.js +1 -0
- package/dist/general/providers/parchmentSdk.d.ts +23 -0
- package/dist/general/providers/parchmentSdk.js +11 -0
- package/dist/general/types/configTypes.d.ts +62 -0
- package/dist/general/types/configTypes.js +1 -0
- package/dist/general/types/index.d.ts +1 -0
- package/dist/general/types/index.js +1 -0
- package/dist/general/utils/address.d.ts +49 -0
- package/dist/general/utils/address.js +110 -0
- package/dist/general/utils/caller.d.ts +58 -0
- package/dist/general/utils/caller.js +182 -0
- package/dist/general/utils/errors.d.ts +16 -0
- package/dist/general/utils/errors.js +26 -0
- package/dist/general/utils/index.d.ts +4 -0
- package/dist/general/utils/index.js +4 -0
- package/dist/general/utils/jsBigInt.d.ts +26 -0
- package/dist/general/utils/jsBigInt.js +74 -0
- package/dist/general/utils/txShape.d.ts +8 -0
- package/dist/general/utils/txShape.js +39 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/packages/index.d.ts +11 -0
- package/dist/packages/index.js +5 -0
- package/dist/packages/parchment/abortCodes.d.ts +196 -0
- package/dist/packages/parchment/abortCodes.js +522 -0
- package/dist/packages/parchment/batchClose.d.ts +268 -0
- package/dist/packages/parchment/batchClose.js +524 -0
- package/dist/packages/parchment/eventGuard.d.ts +106 -0
- package/dist/packages/parchment/eventGuard.js +119 -0
- package/dist/packages/parchment/gameCounterEvents.d.ts +59 -0
- package/dist/packages/parchment/gameCounterEvents.js +56 -0
- package/dist/packages/parchment/index.d.ts +52 -0
- package/dist/packages/parchment/index.js +30 -0
- package/dist/packages/parchment/liquidationCredit.d.ts +28 -0
- package/dist/packages/parchment/liquidationCredit.js +25 -0
- package/dist/packages/parchment/lockedMintEvents.d.ts +42 -0
- package/dist/packages/parchment/lockedMintEvents.js +46 -0
- package/dist/packages/parchment/monitoring.d.ts +369 -0
- package/dist/packages/parchment/monitoring.js +259 -0
- package/dist/packages/parchment/notes.d.ts +6 -0
- package/dist/packages/parchment/notes.js +1 -0
- package/dist/packages/parchment/onboarding.d.ts +50 -0
- package/dist/packages/parchment/onboarding.js +48 -0
- package/dist/packages/parchment/orderEffects.d.ts +207 -0
- package/dist/packages/parchment/orderEffects.js +268 -0
- package/dist/packages/parchment/orderParams.d.ts +72 -0
- package/dist/packages/parchment/orderParams.js +71 -0
- package/dist/packages/parchment/packageIds.d.ts +53 -0
- package/dist/packages/parchment/packageIds.js +149 -0
- package/dist/packages/parchment/parchment.d.ts +442 -0
- package/dist/packages/parchment/parchment.js +975 -0
- package/dist/packages/parchment/parchmentAccount.d.ts +189 -0
- package/dist/packages/parchment/parchmentAccount.js +273 -0
- package/dist/packages/parchment/parchmentMarket.d.ts +58 -0
- package/dist/packages/parchment/parchmentMarket.js +86 -0
- package/dist/packages/parchment/parchmentTypes.d.ts +2031 -0
- package/dist/packages/parchment/parchmentTypes.js +65 -0
- package/dist/packages/parchment/publicInts.d.ts +45 -0
- package/dist/packages/parchment/publicInts.js +383 -0
- package/dist/packages/parchment/reconcileEvents.d.ts +24 -0
- package/dist/packages/parchment/reconcileEvents.js +30 -0
- package/dist/packages/parchment/retainedFee.d.ts +43 -0
- package/dist/packages/parchment/retainedFee.js +68 -0
- package/dist/packages/parchment/sessionClose.d.ts +68 -0
- package/dist/packages/parchment/sessionClose.js +50 -0
- package/dist/packages/parchment/sessionKey.d.ts +78 -0
- package/dist/packages/parchment/sessionKey.js +154 -0
- package/dist/packages/parchment/slippage.d.ts +23 -0
- package/dist/packages/parchment/slippage.js +27 -0
- package/dist/packages/parchment/sponsor.d.ts +39 -0
- package/dist/packages/parchment/sponsor.js +48 -0
- package/dist/packages/parchment/stakingCalls.d.ts +33 -0
- package/dist/packages/parchment/stakingCalls.js +21 -0
- package/dist/packages/parchment/stakingEvents.d.ts +53 -0
- package/dist/packages/parchment/stakingEvents.js +71 -0
- package/dist/packages/parchment/triggerCalls.d.ts +46 -0
- package/dist/packages/parchment/triggerCalls.js +36 -0
- package/dist/packages/parchment/triggerEvents.d.ts +22 -0
- package/dist/packages/parchment/triggerEvents.js +33 -0
- package/dist/packages/parchment/triggers.d.ts +113 -0
- package/dist/packages/parchment/triggers.js +183 -0
- package/dist/packages/parchment/txBodies.d.ts +111 -0
- package/dist/packages/parchment/txBodies.js +683 -0
- package/dist/packages/parchment/txIntent.d.ts +99 -0
- package/dist/packages/parchment/txIntent.js +611 -0
- package/dist/types.d.ts +2 -0
- package/dist/types.js +1 -0
- package/package.json +58 -4
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { Transaction, TransactionArgument, TransactionObjectArgument } from "@mysten/sui/transactions";
|
|
2
|
+
/** Max position ids per `trade::force_close_session` call (`trade::EBatchTooLarge` 34 above it). */
|
|
3
|
+
export declare const FORCE_CLOSE_SESSION_MAX_IDS = 128;
|
|
4
|
+
type ObjectInput = string | TransactionObjectArgument;
|
|
5
|
+
export interface ArmSessionCloseCall {
|
|
6
|
+
/** Latest `parchment_trade` package id (call target). */
|
|
7
|
+
tradePackageId: string;
|
|
8
|
+
/** Collateral coin type `C`. */
|
|
9
|
+
coinType: string;
|
|
10
|
+
market: ObjectInput;
|
|
11
|
+
exchange: ObjectInput;
|
|
12
|
+
config: ObjectInput;
|
|
13
|
+
/** `oracle::PriceReceipt` from an earlier command in the same PTB; must be a closed receipt for this market. */
|
|
14
|
+
receipt: TransactionArgument;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Keeper-only `oracle::arm_session_close<C>(market, exchange, config, receipt, clock)`: the tx sender must be an
|
|
18
|
+
* order keeper (`oracle::ENotKeeper` 16 otherwise). Arms from a receipt whose signed Lazer market session is
|
|
19
|
+
* closed (the storage may still be fresh: the crank keeps writing through a closed session), snapshots the
|
|
20
|
+
* storage price at the signed last-trade time and starts the drain. The gap is measured from the signed last
|
|
21
|
+
* trade (`oracle::EGapTooShort` 13 until it is older than the force-close minimum gap). Consumes the receipt.
|
|
22
|
+
* Aborts oracle 10-16 (see `ORACLE_ABORT_NAMES`); runs during every pause and the oracle kill switch.
|
|
23
|
+
*/
|
|
24
|
+
export declare function addArmSessionCloseCall(tx: Transaction, input: ArmSessionCloseCall): void;
|
|
25
|
+
export interface ArmSessionCloseAdminCall extends ArmSessionCloseCall {
|
|
26
|
+
/** `parchment::authority::AuthorityCap<PACKAGE, ADMIN>`. */
|
|
27
|
+
adminCap: ObjectInput;
|
|
28
|
+
}
|
|
29
|
+
/** Admin `oracle::arm_session_close_admin<C>(market, exchange, config, cap, receipt, clock)`: same as {@link addArmSessionCloseCall}, authorized by the admin cap. */
|
|
30
|
+
export declare function addArmSessionCloseAdminCall(tx: Transaction, input: ArmSessionCloseAdminCall): void;
|
|
31
|
+
export interface SessionRefundCall {
|
|
32
|
+
tradePackageId: string;
|
|
33
|
+
coinType: string;
|
|
34
|
+
exchange: ObjectInput;
|
|
35
|
+
market: ObjectInput;
|
|
36
|
+
account: ObjectInput;
|
|
37
|
+
config: ObjectInput;
|
|
38
|
+
/** The pending `order::OrderRequest<C>` object. */
|
|
39
|
+
order: ObjectInput;
|
|
40
|
+
/** Closed `oracle::PriceReceipt` frozen at the market's session snapshot tick. */
|
|
41
|
+
receipt: TransactionArgument;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Keeper-only `order::session_refund<C>(exchange, market, account, config, order, receipt, clock)`: refunds an order
|
|
45
|
+
* left pending across an equity session close with outcome 13, without the fill window. Aborts order 0, 2, 3, 21, 22.
|
|
46
|
+
*/
|
|
47
|
+
export declare function addSessionRefundCall(tx: Transaction, input: SessionRefundCall): void;
|
|
48
|
+
export interface ForceCloseSessionCall {
|
|
49
|
+
tradePackageId: string;
|
|
50
|
+
coinType: string;
|
|
51
|
+
exchange: ObjectInput;
|
|
52
|
+
market: ObjectInput;
|
|
53
|
+
account: ObjectInput;
|
|
54
|
+
config: ObjectInput;
|
|
55
|
+
/** Position ids on `account` (at most {@link FORCE_CLOSE_SESSION_MAX_IDS}); ids not eligible are skipped. */
|
|
56
|
+
positionIds: ReadonlyArray<string | number | bigint>;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Permissionless `trade::force_close_session<C>(exchange, market, account, config, position_ids, clock)`: settles the
|
|
60
|
+
* listed positions at the armed snapshot price. Returns `[lossTicket, coin]`: settle the `LossTicket` with
|
|
61
|
+
* `fee_mint::mint_on_loss` or `fees::discard_zero_loss` as for a close; `coin` carries any liquidation bounty
|
|
62
|
+
* (zero otherwise) and must be transferred or merged. Runs during every pause and the oracle kill switch.
|
|
63
|
+
*/
|
|
64
|
+
export declare function addForceCloseSessionCall(tx: Transaction, input: ForceCloseSessionCall): {
|
|
65
|
+
lossTicket: TransactionArgument;
|
|
66
|
+
coin: TransactionArgument;
|
|
67
|
+
};
|
|
68
|
+
export {};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export const FORCE_CLOSE_SESSION_MAX_IDS = 128;
|
|
2
|
+
function obj(tx, o) {
|
|
3
|
+
return typeof o === "string" ? tx.object(o) : o;
|
|
4
|
+
}
|
|
5
|
+
export function addArmSessionCloseCall(tx, input) {
|
|
6
|
+
tx.moveCall({
|
|
7
|
+
target: `${input.tradePackageId}::oracle::arm_session_close`,
|
|
8
|
+
typeArguments: [input.coinType],
|
|
9
|
+
arguments: [obj(tx, input.market), obj(tx, input.exchange), obj(tx, input.config), input.receipt, tx.object.clock()],
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
export function addArmSessionCloseAdminCall(tx, input) {
|
|
13
|
+
tx.moveCall({
|
|
14
|
+
target: `${input.tradePackageId}::oracle::arm_session_close_admin`,
|
|
15
|
+
typeArguments: [input.coinType],
|
|
16
|
+
arguments: [
|
|
17
|
+
obj(tx, input.market), obj(tx, input.exchange), obj(tx, input.config), obj(tx, input.adminCap), input.receipt, tx.object.clock(),
|
|
18
|
+
],
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
export function addSessionRefundCall(tx, input) {
|
|
22
|
+
tx.moveCall({
|
|
23
|
+
target: `${input.tradePackageId}::order::session_refund`,
|
|
24
|
+
typeArguments: [input.coinType],
|
|
25
|
+
arguments: [
|
|
26
|
+
obj(tx, input.exchange), obj(tx, input.market), obj(tx, input.account), obj(tx, input.config), obj(tx, input.order),
|
|
27
|
+
input.receipt, tx.object.clock(),
|
|
28
|
+
],
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
export function addForceCloseSessionCall(tx, input) {
|
|
32
|
+
if (input.positionIds.length === 0)
|
|
33
|
+
throw new Error("force_close_session: no position ids");
|
|
34
|
+
if (input.positionIds.length > FORCE_CLOSE_SESSION_MAX_IDS) {
|
|
35
|
+
throw new Error(`force_close_session: at most ${FORCE_CLOSE_SESSION_MAX_IDS} position ids`);
|
|
36
|
+
}
|
|
37
|
+
const [lossTicket, coin] = tx.moveCall({
|
|
38
|
+
target: `${input.tradePackageId}::trade::force_close_session`,
|
|
39
|
+
typeArguments: [input.coinType],
|
|
40
|
+
arguments: [
|
|
41
|
+
obj(tx, input.exchange),
|
|
42
|
+
obj(tx, input.market),
|
|
43
|
+
obj(tx, input.account),
|
|
44
|
+
obj(tx, input.config),
|
|
45
|
+
tx.pure.vector("u64", input.positionIds.map((id) => BigInt(id))),
|
|
46
|
+
tx.object.clock(),
|
|
47
|
+
],
|
|
48
|
+
});
|
|
49
|
+
return { lossTicket: lossTicket, coin: coin };
|
|
50
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { Signer } from "@mysten/sui/cryptography";
|
|
2
|
+
import type { ParchmentDelegate, ParchmentSponsoredTx } from "./parchmentTypes.js";
|
|
3
|
+
/**
|
|
4
|
+
* Trading session keys. An app keeps an Ed25519 key in the browser, the owner grants it as a delegate on
|
|
5
|
+
* their Parchment account once (`grant-delegate`, wallet-signed, AccountCap), and afterwards the key signs
|
|
6
|
+
* the `*-as-delegate` trade transactions itself with the gas sponsored. On chain a delegate can only
|
|
7
|
+
* request opens / closes, cancel and emergency-close on the account (`order::*_as_delegate`,
|
|
8
|
+
* `trade::close_retired_as_delegate`); withdraw, deposit and delegate changes all need the AccountCap, so a
|
|
9
|
+
* leaked session key can trade the account but never move funds out of it. The owner removes it with
|
|
10
|
+
* `revoke-delegate` (runs under every pause).
|
|
11
|
+
*/
|
|
12
|
+
/** Default session length; callers may choose a longer duration. */
|
|
13
|
+
export declare const SESSION_KEY_TTL_MS: number;
|
|
14
|
+
/** A session is treated as ended this long before its on-chain expiry (a trade then still lands while live). */
|
|
15
|
+
export declare const SESSION_KEY_EXPIRY_MARGIN_MS = 600000;
|
|
16
|
+
/**
|
|
17
|
+
* A session key. `keypair` is an Ed25519 signer: an in-memory `Ed25519Keypair`, or one whose private key
|
|
18
|
+
* cannot be read out (e.g. a non-extractable WebCrypto key) that only signs.
|
|
19
|
+
*/
|
|
20
|
+
export interface ParchmentSessionKey {
|
|
21
|
+
readonly address: string;
|
|
22
|
+
readonly keypair: Signer;
|
|
23
|
+
}
|
|
24
|
+
/** A fresh random Ed25519 session key. */
|
|
25
|
+
export declare function createSessionKey(): ParchmentSessionKey;
|
|
26
|
+
/** The bech32 `suiprivkey…` secret to persist for {@link sessionKeyFromSecret}; `bad_session_key` for a signer that can't export it. */
|
|
27
|
+
export declare function sessionKeySecret(key: ParchmentSessionKey): string;
|
|
28
|
+
/** A stored session key back from its `suiprivkey…` secret; `bad_session_key` when it is not an Ed25519 secret. */
|
|
29
|
+
export declare function sessionKeyFromSecret(secret: string): ParchmentSessionKey;
|
|
30
|
+
/** The `expiryMs` to grant: `now + ttlMs`. */
|
|
31
|
+
export declare function sessionKeyExpiryMs(nowMs?: number, ttlMs?: number): bigint;
|
|
32
|
+
/**
|
|
33
|
+
* The account's delegate entry for `address` when it is still live at `nowMs` with `marginMs` to spare, else
|
|
34
|
+
* null (revoked elsewhere, never granted, or about to expire: `assert_delegate` wants `expiry > now`).
|
|
35
|
+
*/
|
|
36
|
+
export declare function liveSessionDelegate(delegates: readonly ParchmentDelegate[] | undefined, address: string, nowMs?: number, marginMs?: number): ParchmentDelegate | null;
|
|
37
|
+
/**
|
|
38
|
+
* Throws `bad_session_tx` unless the BCS `TransactionKind` is a programmable transaction that calls a
|
|
39
|
+
* `*_as_delegate` trade entry and nothing that moves funds or delegates: every command is a Move call or a
|
|
40
|
+
* `TransferObjects` back to `sender` itself (the service hands the zero coin `mint_on_loss` returns to the
|
|
41
|
+
* sender), so no `Publish` / `Upgrade`, `SplitCoins`, `MergeCoins` or `MakeMoveVec`; every Move call is one
|
|
42
|
+
* of the delegate trade entries, `adapter::quote`, `oracle::begin_price` or `tokenomics::mint_on_loss` in one
|
|
43
|
+
* of `packages` (the Parchment package ids: core, trade, oracle and token, any version), or
|
|
44
|
+
* `price_feed_storage::update_price_feed` on `lazerIntegrationPackage` only (the configured
|
|
45
|
+
* integration, not a Parchment package). Run it on every kind before the session key signs.
|
|
46
|
+
*/
|
|
47
|
+
export declare function assertSessionTradeKind(kind: Uint8Array | string, sender: string, packages: Iterable<string>, lazerIntegrationPackage?: string | null): void;
|
|
48
|
+
/**
|
|
49
|
+
* True when the sponsor's `txBytesBase64` is exactly `kind`, sent by `sender`, with another address paying gas
|
|
50
|
+
* (and that address is `sponsored.sponsor` when served): `TransactionData::V1` = tag 0, the kind bytes, the sender.
|
|
51
|
+
*/
|
|
52
|
+
export declare function isSponsoredCopyOf(sponsored: Pick<ParchmentSponsoredTx, "txBytesBase64" | "sponsor">, kind: Uint8Array, sender: string): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* The session key's signature over the sponsor's transaction, after checking it is the sponsored copy of
|
|
55
|
+
* `kind` from the session address and a trade-only kind calling only `packages` ({@link assertSessionTradeKind}).
|
|
56
|
+
* Execute with `[signature, sponsored.sponsorSignature]`.
|
|
57
|
+
*/
|
|
58
|
+
export declare function signSessionSponsoredTx(key: ParchmentSessionKey, sponsored: Pick<ParchmentSponsoredTx, "txBytesBase64" | "sponsor">, kind: Uint8Array, packages: Iterable<string>, lazerIntegrationPackage?: string | null): Promise<string>;
|
|
59
|
+
/** The sponsor's `MAX_PROOF_LIFETIME_MS`: a session proof's `expiresAtMs` is at most this far ahead of its clock. */
|
|
60
|
+
export declare const MAX_SPONSOR_PROOF_LIFETIME_MS = 120000;
|
|
61
|
+
/** The lifetime {@link signSponsorProof} gives a proof: half the maximum, so a browser clock up to 60 s off still passes. */
|
|
62
|
+
export declare const SPONSOR_PROOF_LIFETIME_MS = 60000;
|
|
63
|
+
/** The session proof a sponsor request carries: the session key's personal-message signature and its expiry. */
|
|
64
|
+
export interface ParchmentSponsorProof {
|
|
65
|
+
senderSignature: string;
|
|
66
|
+
expiresAtMs: bigint;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* The personal message the session key signs for one sponsorship (service `sponsor::proof_message`): five
|
|
70
|
+
* `\n`-joined lines, no trailing newline. Addresses are `0x` + 64 lowercase hex digits, `txKindSha256` the
|
|
71
|
+
* lowercase hex SHA-256 of the kind bytes, `expiresAtMs` plain decimal.
|
|
72
|
+
*/
|
|
73
|
+
export declare function sponsorProofMessage(sender: string, accountId: string, kind: Uint8Array, expiresAtMs: bigint): Promise<string>;
|
|
74
|
+
/**
|
|
75
|
+
* The session key's proof for sponsoring `kind` on `accountId` (the account the kind trades on), valid for
|
|
76
|
+
* {@link SPONSOR_PROOF_LIFETIME_MS} from `nowMs`. Signed by the session key alone, never the wallet.
|
|
77
|
+
*/
|
|
78
|
+
export declare function signSponsorProof(key: ParchmentSessionKey, accountId: string, kind: Uint8Array, nowMs?: number): Promise<ParchmentSponsorProof>;
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { bcs } from "@mysten/sui/bcs";
|
|
2
|
+
import { Ed25519Keypair } from "@mysten/sui/keypairs/ed25519";
|
|
3
|
+
import { fromBase64, normalizeSuiAddress, toHex } from "@mysten/sui/utils";
|
|
4
|
+
import { ParchmentApiError } from "../../general/utils/errors.js";
|
|
5
|
+
export const SESSION_KEY_TTL_MS = 2_592_000_000 - 3_600_000;
|
|
6
|
+
export const SESSION_KEY_EXPIRY_MARGIN_MS = 600_000;
|
|
7
|
+
export function createSessionKey() {
|
|
8
|
+
const keypair = Ed25519Keypair.generate();
|
|
9
|
+
return { address: normalizeSuiAddress(keypair.toSuiAddress()), keypair };
|
|
10
|
+
}
|
|
11
|
+
export function sessionKeySecret(key) {
|
|
12
|
+
if (!(key.keypair instanceof Ed25519Keypair))
|
|
13
|
+
throw new ParchmentApiError(0, "bad_session_key", "Session key can't be exported");
|
|
14
|
+
return key.keypair.getSecretKey();
|
|
15
|
+
}
|
|
16
|
+
export function sessionKeyFromSecret(secret) {
|
|
17
|
+
let keypair;
|
|
18
|
+
try {
|
|
19
|
+
keypair = Ed25519Keypair.fromSecretKey(secret);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
throw new ParchmentApiError(0, "bad_session_key", "Stored session key is not an Ed25519 secret");
|
|
23
|
+
}
|
|
24
|
+
return { address: normalizeSuiAddress(keypair.toSuiAddress()), keypair };
|
|
25
|
+
}
|
|
26
|
+
export function sessionKeyExpiryMs(nowMs = Date.now(), ttlMs = SESSION_KEY_TTL_MS) {
|
|
27
|
+
const ttl = Math.max(0, Math.floor(ttlMs));
|
|
28
|
+
if (ttl <= 0)
|
|
29
|
+
throw new ParchmentApiError(0, "bad_amount", "Session length must be positive");
|
|
30
|
+
return BigInt(Math.floor(nowMs)) + BigInt(ttl);
|
|
31
|
+
}
|
|
32
|
+
export function liveSessionDelegate(delegates, address, nowMs = Date.now(), marginMs = SESSION_KEY_EXPIRY_MARGIN_MS) {
|
|
33
|
+
const who = normalizeSuiAddress(address);
|
|
34
|
+
const entry = delegates?.find((d) => normalizeSuiAddress(d.delegate) === who);
|
|
35
|
+
if (!entry)
|
|
36
|
+
return null;
|
|
37
|
+
return entry.expiryMs > BigInt(Math.floor(nowMs + marginMs)) ? entry : null;
|
|
38
|
+
}
|
|
39
|
+
const SESSION_TRADE_CALLS = new Set([
|
|
40
|
+
"order::request_open_as_delegate",
|
|
41
|
+
"order::request_close_as_delegate",
|
|
42
|
+
"order::cancel_as_delegate",
|
|
43
|
+
"order::emergency_close_as_delegate",
|
|
44
|
+
"trade::close_retired_as_delegate",
|
|
45
|
+
]);
|
|
46
|
+
const SESSION_CALLS = new Set([...SESSION_TRADE_CALLS, "adapter::quote", "oracle::begin_price", "tokenomics::mint_on_loss"]);
|
|
47
|
+
const UPDATE_PRICE_FEED = "price_feed_storage::update_price_feed";
|
|
48
|
+
function pureAddress(inputs, arg) {
|
|
49
|
+
const index = arg?.Input;
|
|
50
|
+
if (typeof index !== "number")
|
|
51
|
+
return null;
|
|
52
|
+
const pure = inputs[index]?.Pure;
|
|
53
|
+
if (!pure)
|
|
54
|
+
return null;
|
|
55
|
+
try {
|
|
56
|
+
return normalizeSuiAddress(bcs.Address.parse(fromBase64(pure.bytes)));
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
export function assertSessionTradeKind(kind, sender, packages, lazerIntegrationPackage) {
|
|
63
|
+
const bytes = typeof kind === "string" ? fromBase64(kind.trim()) : kind;
|
|
64
|
+
let parsed;
|
|
65
|
+
try {
|
|
66
|
+
parsed = bcs.TransactionKind.parse(bytes);
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
throw new ParchmentApiError(0, "bad_session_tx", "Session transaction is not a transaction kind");
|
|
70
|
+
}
|
|
71
|
+
const ptb = parsed.ProgrammableTransaction;
|
|
72
|
+
if (!ptb)
|
|
73
|
+
throw new ParchmentApiError(0, "bad_session_tx", "Session transaction is not a programmable transaction");
|
|
74
|
+
const self = normalizeSuiAddress(sender);
|
|
75
|
+
const allowed = new Set([...packages].map((id) => normalizeSuiAddress(id)));
|
|
76
|
+
const lazer = lazerIntegrationPackage ? normalizeSuiAddress(lazerIntegrationPackage) : null;
|
|
77
|
+
let trades = 0;
|
|
78
|
+
for (const command of ptb.commands) {
|
|
79
|
+
if (command.TransferObjects) {
|
|
80
|
+
if (pureAddress(ptb.inputs, command.TransferObjects.address) !== self) {
|
|
81
|
+
throw new ParchmentApiError(0, "bad_session_tx", "Session transaction transfers to another address");
|
|
82
|
+
}
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
const call = command.MoveCall;
|
|
86
|
+
if (!call)
|
|
87
|
+
throw new ParchmentApiError(0, "bad_session_tx", `Session key never signs ${command.$kind}`);
|
|
88
|
+
const target = `${call.module}::${call.function}`;
|
|
89
|
+
if (target === UPDATE_PRICE_FEED) {
|
|
90
|
+
const typeArguments = call.typeArguments ?? [];
|
|
91
|
+
if (!lazer || normalizeSuiAddress(call.package) !== lazer || typeArguments.length !== 0) {
|
|
92
|
+
throw new ParchmentApiError(0, "bad_session_tx", `Session key never signs ${target} on package ${call.package}`);
|
|
93
|
+
}
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
if (!SESSION_CALLS.has(target)) {
|
|
97
|
+
throw new ParchmentApiError(0, "bad_session_tx", `Session key never signs ${target}`);
|
|
98
|
+
}
|
|
99
|
+
if (!allowed.has(normalizeSuiAddress(call.package))) {
|
|
100
|
+
throw new ParchmentApiError(0, "bad_session_tx", `Session key never signs a call to package ${call.package}`);
|
|
101
|
+
}
|
|
102
|
+
if (SESSION_TRADE_CALLS.has(target))
|
|
103
|
+
trades++;
|
|
104
|
+
}
|
|
105
|
+
if (trades === 0)
|
|
106
|
+
throw new ParchmentApiError(0, "bad_session_tx", "Session transaction has no delegate trade call");
|
|
107
|
+
}
|
|
108
|
+
function sameBytes(a, b) {
|
|
109
|
+
return a.length === b.length && a.every((x, i) => x === b[i]);
|
|
110
|
+
}
|
|
111
|
+
export function isSponsoredCopyOf(sponsored, kind, sender) {
|
|
112
|
+
try {
|
|
113
|
+
const bytes = fromBase64(sponsored.txBytesBase64);
|
|
114
|
+
if (bytes[0] !== 0 || !sameBytes(bytes.subarray(1, 1 + kind.length), kind))
|
|
115
|
+
return false;
|
|
116
|
+
const v1 = bcs.TransactionData.parse(bytes).V1;
|
|
117
|
+
if (!v1)
|
|
118
|
+
return false;
|
|
119
|
+
const owner = normalizeSuiAddress(v1.gasData.owner);
|
|
120
|
+
const from = normalizeSuiAddress(sender);
|
|
121
|
+
if (normalizeSuiAddress(v1.sender) !== from || owner === from)
|
|
122
|
+
return false;
|
|
123
|
+
return typeof sponsored.sponsor !== "string" || !sponsored.sponsor || owner === normalizeSuiAddress(sponsored.sponsor);
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
export async function signSessionSponsoredTx(key, sponsored, kind, packages, lazerIntegrationPackage) {
|
|
130
|
+
assertSessionTradeKind(kind, key.address, packages, lazerIntegrationPackage);
|
|
131
|
+
if (!isSponsoredCopyOf(sponsored, kind, key.address)) {
|
|
132
|
+
throw new ParchmentApiError(0, "bad_tx", "Sponsored transaction is not the session's trade");
|
|
133
|
+
}
|
|
134
|
+
const { signature } = await key.keypair.signTransaction(fromBase64(sponsored.txBytesBase64));
|
|
135
|
+
return signature;
|
|
136
|
+
}
|
|
137
|
+
export const MAX_SPONSOR_PROOF_LIFETIME_MS = 120_000;
|
|
138
|
+
export const SPONSOR_PROOF_LIFETIME_MS = 60_000;
|
|
139
|
+
export async function sponsorProofMessage(sender, accountId, kind, expiresAtMs) {
|
|
140
|
+
const kindSha256 = toHex(new Uint8Array(await crypto.subtle.digest("SHA-256", new Uint8Array(kind))));
|
|
141
|
+
return [
|
|
142
|
+
"Parchment session-key sponsorship v1",
|
|
143
|
+
`sender: ${normalizeSuiAddress(sender)}`,
|
|
144
|
+
`accountId: ${normalizeSuiAddress(accountId)}`,
|
|
145
|
+
`txKindSha256: ${kindSha256}`,
|
|
146
|
+
`expiresAtMs: ${expiresAtMs}`,
|
|
147
|
+
].join("\n");
|
|
148
|
+
}
|
|
149
|
+
export async function signSponsorProof(key, accountId, kind, nowMs = Date.now()) {
|
|
150
|
+
const expiresAtMs = BigInt(Math.floor(nowMs) + SPONSOR_PROOF_LIFETIME_MS);
|
|
151
|
+
const message = await sponsorProofMessage(key.address, accountId, kind, expiresAtMs);
|
|
152
|
+
const { signature } = await key.keypair.signPersonalMessage(new TextEncoder().encode(message));
|
|
153
|
+
return { senderSignature: signature, expiresAtMs };
|
|
154
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type SlippageSide = "long" | "short";
|
|
2
|
+
export type SlippageAction = "open" | "close";
|
|
3
|
+
/**
|
|
4
|
+
* Worst acceptable fill price (WAD) for a given side, action, mid/quote price and slippage.
|
|
5
|
+
*
|
|
6
|
+
* - long open / short close: upper bound `price * (1 + slip)`, rounded down (fill must be <= bound)
|
|
7
|
+
* - short open / long close: lower bound `price * (1 - slip)`, rounded up (fill must be >= bound);
|
|
8
|
+
* an open's bound is at least 1 (the deployed service still refuses a 0 open bound; 0 means "no bound")
|
|
9
|
+
*
|
|
10
|
+
* Both round to the tight side, so a bound never allows more than `slippageBps`.
|
|
11
|
+
*
|
|
12
|
+
* Pass the result as `acceptablePriceWad` on order requests. On chain it is stored and emitted only;
|
|
13
|
+
* two-step fills and emergency close take no price bound, so it is a record of intent, not protection.
|
|
14
|
+
* Throws `invalid_amount` for a negative `priceWad` or a `slippageBps` that is not a non-negative integer
|
|
15
|
+
* (a negative slip would give a bound on the wrong side of the price, or a negative bound), and
|
|
16
|
+
* `bad_request` for a `slippageBps` above 10000 (100%), like the service preview's `slippageBps` (0..=10000).
|
|
17
|
+
*/
|
|
18
|
+
export declare function boundFromSlippage(input: {
|
|
19
|
+
side: SlippageSide;
|
|
20
|
+
action: SlippageAction;
|
|
21
|
+
priceWad: bigint;
|
|
22
|
+
slippageBps: bigint | number;
|
|
23
|
+
}): bigint;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ParchmentApiError } from "../../general/utils/errors.js";
|
|
2
|
+
const BPS = 10000n;
|
|
3
|
+
export function boundFromSlippage(input) {
|
|
4
|
+
const price = input.priceWad;
|
|
5
|
+
const raw = input.slippageBps;
|
|
6
|
+
if (typeof price !== "bigint" || price < 0n) {
|
|
7
|
+
throw new ParchmentApiError(0, "invalid_amount", "priceWad must be a non-negative bigint");
|
|
8
|
+
}
|
|
9
|
+
if (!(typeof raw === "bigint" || (typeof raw === "number" && Number.isSafeInteger(raw))) || raw < 0) {
|
|
10
|
+
throw new ParchmentApiError(0, "invalid_amount", "slippageBps must be a non-negative integer");
|
|
11
|
+
}
|
|
12
|
+
if ((input.side !== "long" && input.side !== "short") || (input.action !== "open" && input.action !== "close")) {
|
|
13
|
+
throw new ParchmentApiError(0, "invalid_amount", "side must be long or short and action must be open or close");
|
|
14
|
+
}
|
|
15
|
+
const slip = BigInt(raw);
|
|
16
|
+
if (slip > BPS) {
|
|
17
|
+
throw new ParchmentApiError(0, "bad_request", "slippageBps must be at most 10000 (100%)");
|
|
18
|
+
}
|
|
19
|
+
const ceiling = (input.side === "long" && input.action === "open")
|
|
20
|
+
|| (input.side === "short" && input.action === "close");
|
|
21
|
+
if (ceiling) {
|
|
22
|
+
const upper = (price * (BPS + slip)) / BPS;
|
|
23
|
+
return input.action === "open" && upper === 0n ? 1n : upper;
|
|
24
|
+
}
|
|
25
|
+
const floor = slip === BPS ? 0n : (price * (BPS - slip) + (BPS - 1n)) / BPS;
|
|
26
|
+
return input.action === "open" && floor === 0n ? 1n : floor;
|
|
27
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { ApiParchmentSponsorBody } from "./parchmentTypes.js";
|
|
2
|
+
/**
|
|
3
|
+
* Gas sponsorship for trading session keys. The sponsor pays only for
|
|
4
|
+
* `*-as-delegate` trade kinds whose sender is a live delegate of the target account (see `sessionKey.ts`); owner
|
|
5
|
+
* (`AccountCap`) transactions are never sponsored. Limits are per account, shared by all of its session keys.
|
|
6
|
+
*/
|
|
7
|
+
/** 403: the sender is not a live delegate of the account (never granted, expired or revoked). Drop the session key. */
|
|
8
|
+
export declare const SPONSOR_NOT_DELEGATE = "not_delegate";
|
|
9
|
+
/** 429: the account already holds its unresolved sponsorship(s) until the sponsor sees that tx land (or 120 s). */
|
|
10
|
+
export declare const SPONSOR_IN_FLIGHT_LIMIT = "in_flight_limit";
|
|
11
|
+
/** True when a sponsor refusal means the session key is no longer a delegate: forget it and offer to enable again. */
|
|
12
|
+
export declare function isSessionKeyRevoked(error: unknown): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Whether a failed {@link Parchment.sponsorTransaction} should fall back to the wallet path (the owner's
|
|
15
|
+
* `AccountCap` transaction, user-paid gas): true when nothing is wrong with the kind itself.
|
|
16
|
+
*
|
|
17
|
+
* - true: 403 `not_delegate` (the session is gone), 401 `session_proof_expired` and 400 `bad_session_proof_expiry`
|
|
18
|
+
* (the browser clock is too far off the service's), every 429 (the account's in-flight, rate or failure limits,
|
|
19
|
+
* or an edge rate limit), 400 `gas_budget_exceeded`, 502 / 503 / 504 (`sponsor_unavailable`: disabled, out
|
|
20
|
+
* of budget, node or signer down) and the SDK's own `network` / `timeout`.
|
|
21
|
+
* - false: every other 400 (`paused`, `simulation_failed`: the trade would fail anyway; `disallowed_*`,
|
|
22
|
+
* `mixed_*`, `bad_account`, ...: a kind the sponsor never pays for), 413, any other status, the SDK's local
|
|
23
|
+
* refusals (`bad_request`, `bad_tx`, `bad_tx_kind`) and anything that is not a `ParchmentApiError`.
|
|
24
|
+
*
|
|
25
|
+
* Safe to fall back after any of these: the session key signs only the sponsor's bytes, so a refused sponsorship
|
|
26
|
+
* left nothing signed, and the wallet path is a different (owner) transaction.
|
|
27
|
+
*/
|
|
28
|
+
export declare function shouldPayOwnGas(error: unknown): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* the legacy API's check: a missing or non-string kind is `bad_request`; the kind is trimmed (as the service does)
|
|
31
|
+
* and an empty or non-base64 one is the service's `bad_tx_kind`. The service decodes and validates it.
|
|
32
|
+
*/
|
|
33
|
+
export declare function sponsorKind(value: unknown): string;
|
|
34
|
+
/**
|
|
35
|
+
* The `POST /api/parchment/sponsor` wire body: `{ sender, txKindBase64, senderSignature, expiresAtMs }`,
|
|
36
|
+
* `expiresAtMs` as a js_bigint literal. A missing sender, signature or expiry is `bad_request`, a bad kind
|
|
37
|
+
* `bad_tx_kind` ({@link sponsorKind}).
|
|
38
|
+
*/
|
|
39
|
+
export declare function sponsorBody(input: ApiParchmentSponsorBody): Record<string, string>;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { normalizeAddress } from "../../general/utils/address.js";
|
|
2
|
+
import { ParchmentApiError } from "../../general/utils/errors.js";
|
|
3
|
+
import { toJsBigInt } from "../../general/utils/jsBigInt.js";
|
|
4
|
+
export const SPONSOR_NOT_DELEGATE = "not_delegate";
|
|
5
|
+
export const SPONSOR_IN_FLIGHT_LIMIT = "in_flight_limit";
|
|
6
|
+
export function isSessionKeyRevoked(error) {
|
|
7
|
+
return error instanceof ParchmentApiError && error.status === 403 && error.code === SPONSOR_NOT_DELEGATE;
|
|
8
|
+
}
|
|
9
|
+
export function shouldPayOwnGas(error) {
|
|
10
|
+
if (!(error instanceof ParchmentApiError))
|
|
11
|
+
return false;
|
|
12
|
+
if (error.status === 0)
|
|
13
|
+
return error.code === "network" || error.code === "timeout";
|
|
14
|
+
if (error.status === 400)
|
|
15
|
+
return error.code === "gas_budget_exceeded" || error.code === "bad_session_proof_expiry";
|
|
16
|
+
if (error.status === 401)
|
|
17
|
+
return error.code === "session_proof_expired";
|
|
18
|
+
if (error.status === 403)
|
|
19
|
+
return error.code === SPONSOR_NOT_DELEGATE;
|
|
20
|
+
return error.status === 429 || error.status === 502 || error.status === 503 || error.status === 504;
|
|
21
|
+
}
|
|
22
|
+
export function sponsorKind(value) {
|
|
23
|
+
if (typeof value !== "string") {
|
|
24
|
+
throw new ParchmentApiError(0, "bad_request", "txKindBase64 is required");
|
|
25
|
+
}
|
|
26
|
+
const kind = value.trim();
|
|
27
|
+
if (kind.length === 0 || !/^[A-Za-z0-9+/=]+$/.test(kind)) {
|
|
28
|
+
throw new ParchmentApiError(0, "bad_tx_kind", "txKindBase64 must be base64 transaction-kind bytes");
|
|
29
|
+
}
|
|
30
|
+
return kind;
|
|
31
|
+
}
|
|
32
|
+
export function sponsorBody(input) {
|
|
33
|
+
if (typeof input?.walletAddress !== "string") {
|
|
34
|
+
throw new ParchmentApiError(0, "bad_request", "walletAddress is required");
|
|
35
|
+
}
|
|
36
|
+
if (typeof input.senderSignature !== "string" || input.senderSignature.length === 0) {
|
|
37
|
+
throw new ParchmentApiError(0, "bad_request", "senderSignature is required");
|
|
38
|
+
}
|
|
39
|
+
if (typeof input.expiresAtMs !== "bigint" || input.expiresAtMs <= 0n) {
|
|
40
|
+
throw new ParchmentApiError(0, "bad_request", "expiresAtMs is required");
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
sender: normalizeAddress(input.walletAddress),
|
|
44
|
+
txKindBase64: sponsorKind(input.txKindBase64),
|
|
45
|
+
senderSignature: input.senderSignature,
|
|
46
|
+
expiresAtMs: toJsBigInt(input.expiresAtMs),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Transaction, TransactionObjectArgument } from "@mysten/sui/transactions";
|
|
2
|
+
type ObjectInput = string | TransactionObjectArgument;
|
|
3
|
+
/**
|
|
4
|
+
* Direct `parchment_token::staking` locked-yield calls. `packageId` is the token package of
|
|
5
|
+
* that has `sync_locked`. `clock` defaults to `0x6`.
|
|
6
|
+
*/
|
|
7
|
+
export interface SyncLockedCall {
|
|
8
|
+
packageId: string;
|
|
9
|
+
coinType: string;
|
|
10
|
+
pool: ObjectInput;
|
|
11
|
+
exchange: ObjectInput;
|
|
12
|
+
owner: string;
|
|
13
|
+
clock?: ObjectInput;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* `staking::sync_locked(pool, exchange, owner, clock)`: banks the yield `owner`'s locked weight
|
|
17
|
+
* earned and reweighs it from their mint ledger. Permissionless; pays nobody. Append it after any
|
|
18
|
+
* call that changes the owner's ledger (release, exit, credit, void).
|
|
19
|
+
*/
|
|
20
|
+
export declare function addSyncLockedCall(tx: Transaction, input: SyncLockedCall): void;
|
|
21
|
+
/** {@link addSyncLockedCall} for each distinct owner, in first-seen order. Returns the owners synced. */
|
|
22
|
+
export declare function addSyncLockedCalls(tx: Transaction, input: Omit<SyncLockedCall, "owner"> & {
|
|
23
|
+
owners: readonly string[];
|
|
24
|
+
}): string[];
|
|
25
|
+
/**
|
|
26
|
+
* ADMIN `staking::forfeit_locked_yield(pool, exchange, config, cap, owner, clock)`: syncs `owner`, then
|
|
27
|
+
* returns all their unpaid locked yield to the reward stream. Append it after `locked_mint::admin_void`.
|
|
28
|
+
*/
|
|
29
|
+
export declare function addForfeitLockedYieldCall(tx: Transaction, input: SyncLockedCall & {
|
|
30
|
+
config: ObjectInput;
|
|
31
|
+
cap: ObjectInput;
|
|
32
|
+
}): void;
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { normalizeSuiAddress } from "@mysten/sui/utils";
|
|
2
|
+
const object = (tx, value) => typeof value === "string" ? tx.object(value) : value;
|
|
3
|
+
export function addSyncLockedCall(tx, input) {
|
|
4
|
+
tx.moveCall({
|
|
5
|
+
target: `${input.packageId}::staking::sync_locked`, typeArguments: [input.coinType],
|
|
6
|
+
arguments: [object(tx, input.pool), object(tx, input.exchange), tx.pure.address(input.owner), object(tx, input.clock ?? "0x6")],
|
|
7
|
+
});
|
|
8
|
+
}
|
|
9
|
+
export function addSyncLockedCalls(tx, input) {
|
|
10
|
+
const owners = [...new Set(input.owners.map((o) => normalizeSuiAddress(o)))];
|
|
11
|
+
for (const owner of owners)
|
|
12
|
+
addSyncLockedCall(tx, { ...input, owner });
|
|
13
|
+
return owners;
|
|
14
|
+
}
|
|
15
|
+
export function addForfeitLockedYieldCall(tx, input) {
|
|
16
|
+
tx.moveCall({
|
|
17
|
+
target: `${input.packageId}::staking::forfeit_locked_yield`, typeArguments: [input.coinType],
|
|
18
|
+
arguments: [object(tx, input.pool), object(tx, input.exchange), object(tx, input.config), object(tx, input.cap),
|
|
19
|
+
tx.pure.address(input.owner), object(tx, input.clock ?? "0x6")],
|
|
20
|
+
});
|
|
21
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/** BCS for `events::Event<StakingDurationCapsUpdatedEventV1>`. */
|
|
2
|
+
export declare const STAKING_DURATION_CAPS_UPDATED_EVENT_BCS: import("@mysten/sui/bcs").BcsStruct<{
|
|
3
|
+
pool_id: import("@mysten/sui/bcs").BcsType<string, string | Uint8Array<ArrayBufferLike>, "bytes[32]">;
|
|
4
|
+
max_reward_stream_ms: import("@mysten/sui/bcs").BcsType<string, string | number | bigint, "u64">;
|
|
5
|
+
max_min_stake_lock_ms: import("@mysten/sui/bcs").BcsType<string, string | number | bigint, "u64">;
|
|
6
|
+
}, string>;
|
|
7
|
+
export type StakingDurationCapsUpdatedEventV1 = ReturnType<typeof STAKING_DURATION_CAPS_UPDATED_EVENT_BCS.parse>;
|
|
8
|
+
/** Decode event bytes supplied by the API. */
|
|
9
|
+
export declare function decodeStakingDurationCapsUpdatedEvent(bytes: Uint8Array): StakingDurationCapsUpdatedEventV1 | null;
|
|
10
|
+
/**
|
|
11
|
+
* BCS for `events::Event<LockedWeightSyncedEventV1>`: `staking::sync_locked` set `owner`'s
|
|
12
|
+
* locked weight from `balance` (finalized locked and vesting PARCHMENT). `moved` is the yield the
|
|
13
|
+
* old weight earned, banked into `owed`; `total_weight` is stake plus locked weight after it.
|
|
14
|
+
*/
|
|
15
|
+
export declare const LOCKED_WEIGHT_SYNCED_EVENT_BCS: import("@mysten/sui/bcs").BcsStruct<{
|
|
16
|
+
pool_id: import("@mysten/sui/bcs").BcsType<string, string | Uint8Array<ArrayBufferLike>, "bytes[32]">;
|
|
17
|
+
owner: import("@mysten/sui/bcs").BcsType<string, string | Uint8Array<ArrayBufferLike>, "bytes[32]">;
|
|
18
|
+
balance: import("@mysten/sui/bcs").BcsType<string, string | number | bigint, "u64">;
|
|
19
|
+
weight: import("@mysten/sui/bcs").BcsType<string, string | number | bigint, "u64">;
|
|
20
|
+
total_weight: import("@mysten/sui/bcs").BcsType<string, string | number | bigint, "u64">;
|
|
21
|
+
moved: import("@mysten/sui/bcs").BcsType<string, string | number | bigint, "u64">;
|
|
22
|
+
owed: import("@mysten/sui/bcs").BcsType<string, string | number | bigint, "u64">;
|
|
23
|
+
}, string>;
|
|
24
|
+
/**
|
|
25
|
+
* `Event<LockedYieldClaimedEventV1>`: on a claim, stake or unstake whenever the owner's owed balance
|
|
26
|
+
* changed. `amount` paid (0 when the reward balance paid none), `owed` still unpaid after it.
|
|
27
|
+
*/
|
|
28
|
+
export declare const LOCKED_YIELD_CLAIMED_EVENT_BCS: import("@mysten/sui/bcs").BcsStruct<{
|
|
29
|
+
pool_id: import("@mysten/sui/bcs").BcsType<string, string | Uint8Array<ArrayBufferLike>, "bytes[32]">;
|
|
30
|
+
owner: import("@mysten/sui/bcs").BcsType<string, string | Uint8Array<ArrayBufferLike>, "bytes[32]">;
|
|
31
|
+
amount: import("@mysten/sui/bcs").BcsType<string, string | number | bigint, "u64">;
|
|
32
|
+
owed: import("@mysten/sui/bcs").BcsType<string, string | number | bigint, "u64">;
|
|
33
|
+
}, string>;
|
|
34
|
+
/** `Event<LockedYieldForfeitedEventV1>`: ADMIN returned `owner`'s unpaid locked yield to the stream. */
|
|
35
|
+
export declare const LOCKED_YIELD_FORFEITED_EVENT_BCS: import("@mysten/sui/bcs").BcsStruct<{
|
|
36
|
+
pool_id: import("@mysten/sui/bcs").BcsType<string, string | Uint8Array<ArrayBufferLike>, "bytes[32]">;
|
|
37
|
+
owner: import("@mysten/sui/bcs").BcsType<string, string | Uint8Array<ArrayBufferLike>, "bytes[32]">;
|
|
38
|
+
amount: import("@mysten/sui/bcs").BcsType<string, string | number | bigint, "u64">;
|
|
39
|
+
stream_end_ms: import("@mysten/sui/bcs").BcsType<string, string | number | bigint, "u64">;
|
|
40
|
+
}, string>;
|
|
41
|
+
/** `Event<LockedWeightBpsUpdatedEventV1>`: the multiplier later syncs use (bps). */
|
|
42
|
+
export declare const LOCKED_WEIGHT_BPS_UPDATED_EVENT_BCS: import("@mysten/sui/bcs").BcsStruct<{
|
|
43
|
+
pool_id: import("@mysten/sui/bcs").BcsType<string, string | Uint8Array<ArrayBufferLike>, "bytes[32]">;
|
|
44
|
+
bps: import("@mysten/sui/bcs").BcsType<string, string | number | bigint, "u64">;
|
|
45
|
+
}, string>;
|
|
46
|
+
export type LockedWeightSyncedEventV1 = ReturnType<typeof LOCKED_WEIGHT_SYNCED_EVENT_BCS.parse>;
|
|
47
|
+
export type LockedYieldClaimedEventV1 = ReturnType<typeof LOCKED_YIELD_CLAIMED_EVENT_BCS.parse>;
|
|
48
|
+
export type LockedYieldForfeitedEventV1 = ReturnType<typeof LOCKED_YIELD_FORFEITED_EVENT_BCS.parse>;
|
|
49
|
+
export type LockedWeightBpsUpdatedEventV1 = ReturnType<typeof LOCKED_WEIGHT_BPS_UPDATED_EVENT_BCS.parse>;
|
|
50
|
+
export declare function decodeLockedWeightSyncedEvent(bytes: Uint8Array): LockedWeightSyncedEventV1 | null;
|
|
51
|
+
export declare function decodeLockedYieldClaimedEvent(bytes: Uint8Array): LockedYieldClaimedEventV1 | null;
|
|
52
|
+
export declare function decodeLockedYieldForfeitedEvent(bytes: Uint8Array): LockedYieldForfeitedEventV1 | null;
|
|
53
|
+
export declare function decodeLockedWeightBpsUpdatedEvent(bytes: Uint8Array): LockedWeightBpsUpdatedEventV1 | null;
|