@interest-protocol/blast-partners-sdk 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/events.d.ts +59 -6
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +68 -6
- package/dist/events.js.map +1 -1
- package/dist/reducer.d.ts +27 -5
- package/dist/reducer.d.ts.map +1 -1
- package/dist/reducer.js +63 -10
- package/dist/reducer.js.map +1 -1
- package/dist/state.d.ts +97 -13
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +50 -11
- package/dist/state.js.map +1 -1
- package/dist/transactions.d.ts +43 -4
- package/dist/transactions.d.ts.map +1 -1
- package/dist/transactions.js +68 -4
- package/dist/transactions.js.map +1 -1
- package/package.json +3 -3
- package/src/events.ts +88 -7
- package/src/reducer.ts +102 -15
- package/src/state.ts +67 -21
- package/src/transactions.ts +93 -5
package/src/state.ts
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
|
+
import type { Delayed } from "@interest-protocol/blast-core/bcs";
|
|
1
2
|
import {
|
|
2
3
|
addressBcs,
|
|
4
|
+
delayedBcs,
|
|
3
5
|
suiObjectIdBcs,
|
|
4
6
|
suiUidBcs,
|
|
7
|
+
tableBcs,
|
|
5
8
|
u64Bcs,
|
|
9
|
+
unitKeyBcs,
|
|
6
10
|
} from "@interest-protocol/blast-core/bcs";
|
|
7
11
|
import {
|
|
8
12
|
BASIS_POINTS_DENOMINATOR,
|
|
@@ -10,31 +14,33 @@ import {
|
|
|
10
14
|
normalizePositiveU64,
|
|
11
15
|
} from "@interest-protocol/blast-core/integers";
|
|
12
16
|
import type { SharedObjectIdentity } from "@interest-protocol/blast-core/sui";
|
|
13
|
-
import type { Timelocked } from "@interest-protocol/blast-core/timelock";
|
|
14
|
-
import {
|
|
15
|
-
timelockedBcs,
|
|
16
|
-
timelockedValue,
|
|
17
|
-
} from "@interest-protocol/blast-core/timelock";
|
|
18
17
|
import { bcs } from "@mysten/sui/bcs";
|
|
19
18
|
import type { ClientWithCoreApi } from "@mysten/sui/client";
|
|
19
|
+
import { ObjectError } from "@mysten/sui/client";
|
|
20
20
|
import { normalizeSuiObjectId, parseStructTag } from "@mysten/sui/utils";
|
|
21
21
|
|
|
22
|
-
/**
|
|
22
|
+
/**
|
|
23
|
+
* `blast_partners::delay_ms`: the fixed notice before a share or cap Blast
|
|
24
|
+
* proposes can be applied.
|
|
25
|
+
*/
|
|
23
26
|
export const PARTNER_DELAY_MS = 604_800_000n;
|
|
24
27
|
|
|
25
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* The partner's recipient, share and managing cap, as Move stores them. A
|
|
30
|
+
* share or cap proposal changes nothing until someone applies it.
|
|
31
|
+
*/
|
|
26
32
|
export type PartnerTerms = {
|
|
27
33
|
recipient: string;
|
|
28
34
|
/** Basis points of Blast's fee on each trade naming the partner. */
|
|
29
|
-
shareBps:
|
|
35
|
+
shareBps: Delayed<null, bigint>;
|
|
30
36
|
/** The only `PartnerCap` that may set `recipient`. */
|
|
31
|
-
capId:
|
|
37
|
+
capId: Delayed<null, string>;
|
|
32
38
|
};
|
|
33
39
|
|
|
34
40
|
export const partnerTermsBcs = {
|
|
35
41
|
recipient: addressBcs,
|
|
36
|
-
share_bps:
|
|
37
|
-
cap_id:
|
|
42
|
+
share_bps: delayedBcs(unitKeyBcs, u64Bcs),
|
|
43
|
+
cap_id: delayedBcs(unitKeyBcs, suiObjectIdBcs),
|
|
38
44
|
};
|
|
39
45
|
|
|
40
46
|
/** BCS layout of `blast_partners::blast_partners::Partner`. */
|
|
@@ -64,7 +70,11 @@ export function decodePartnerObject(
|
|
|
64
70
|
}
|
|
65
71
|
const parsed = partnerBcs.parse(object.content);
|
|
66
72
|
const objectId = normalizeSuiObjectId(object.objectId);
|
|
67
|
-
if (
|
|
73
|
+
if (
|
|
74
|
+
normalizeSuiObjectId(parsed.id.id.bytes) !== objectId ||
|
|
75
|
+
parsed.share_bps.parent !== objectId ||
|
|
76
|
+
parsed.cap_id.parent !== objectId
|
|
77
|
+
) {
|
|
68
78
|
throw new TypeError(`partner ${object.objectId} has a mismatched UID`);
|
|
69
79
|
}
|
|
70
80
|
return {
|
|
@@ -103,18 +113,54 @@ export async function getPartner(
|
|
|
103
113
|
}
|
|
104
114
|
|
|
105
115
|
/**
|
|
106
|
-
* Mirrors `blast_partners::pay`: the partner's share of `fee`
|
|
107
|
-
* one trade, in that coin's atoms)
|
|
108
|
-
* remainder.
|
|
116
|
+
* Mirrors `blast_partners::pay`: the partner's applied share of `fee`
|
|
117
|
+
* (Blast's fee on one trade, in that coin's atoms), rounded down; Blast keeps
|
|
118
|
+
* the remainder.
|
|
109
119
|
*/
|
|
110
120
|
export function partnerPayment(
|
|
111
121
|
partner: Pick<PartnerTerms, "shareBps">,
|
|
112
122
|
fee: bigint,
|
|
113
|
-
nowMs: bigint,
|
|
114
123
|
): bigint {
|
|
115
|
-
return mulDivDown(
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
124
|
+
return mulDivDown(fee, partner.shareBps.value, BASIS_POINTS_DENOMINATOR);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* BCS layout of `blast_partners::partner_list::PartnerList`, embedded in a
|
|
129
|
+
* product's configuration (`LaunchConfig.partners`,
|
|
130
|
+
* `CreationPolicy.partners`). `parent` is that configuration's ID; each
|
|
131
|
+
* accepted partner is an entry of the `acceptance_ends_at_ms` table.
|
|
132
|
+
*/
|
|
133
|
+
export const partnerListBcs = bcs.struct("PartnerList", {
|
|
134
|
+
parent: suiObjectIdBcs,
|
|
135
|
+
acceptance_ends_at_ms: tableBcs,
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
export type PartnerList = ReturnType<typeof partnerListBcs.parse>;
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Reads one entry of a `PartnerList`'s `acceptance_ends_at_ms` table (its
|
|
142
|
+
* `id`): the millisecond from which new sales stop naming `partnerId`, or
|
|
143
|
+
* `U64_MAX` while it is accepted without end. Null when the list never
|
|
144
|
+
* accepted the partner. A partner is accepted at `now` when `now` is before
|
|
145
|
+
* the returned time (`partner_list::is_accepted`).
|
|
146
|
+
*/
|
|
147
|
+
export async function getPartnerAcceptance(
|
|
148
|
+
client: ClientWithCoreApi,
|
|
149
|
+
listTableId: string,
|
|
150
|
+
partnerId: string,
|
|
151
|
+
): Promise<bigint | null> {
|
|
152
|
+
try {
|
|
153
|
+
const { dynamicField } = await client.core.getDynamicField({
|
|
154
|
+
parentId: normalizeSuiObjectId(listTableId),
|
|
155
|
+
name: {
|
|
156
|
+
type: "0x2::object::ID",
|
|
157
|
+
bcs: suiObjectIdBcs.serialize(partnerId).toBytes(),
|
|
158
|
+
},
|
|
159
|
+
});
|
|
160
|
+
return u64Bcs.parse(dynamicField.value.bcs);
|
|
161
|
+
} catch (error) {
|
|
162
|
+
if (error instanceof ObjectError && error.reason === "notFound")
|
|
163
|
+
return null;
|
|
164
|
+
throw error;
|
|
165
|
+
}
|
|
120
166
|
}
|
package/src/transactions.ts
CHANGED
|
@@ -14,7 +14,7 @@ import type {
|
|
|
14
14
|
import { Transaction } from "@mysten/sui/transactions";
|
|
15
15
|
import { normalizeSuiAddress, normalizeSuiObjectId } from "@mysten/sui/utils";
|
|
16
16
|
|
|
17
|
-
/** The
|
|
17
|
+
/** The canonical `blast_partners` package (immutability deferred) and the ACL its `PartnerAdmin` signs in to. */
|
|
18
18
|
export type PartnersDeployment = {
|
|
19
19
|
packageId: string;
|
|
20
20
|
admin: AdminDeployment;
|
|
@@ -78,7 +78,11 @@ export class PartnersCalls {
|
|
|
78
78
|
};
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
/**
|
|
81
|
+
/**
|
|
82
|
+
* `schedule_share` (`PartnerAdmin`): proposes the share, which `applyShare`
|
|
83
|
+
* applies once `PARTNER_DELAY_MS` has passed. A new proposal replaces a
|
|
84
|
+
* pending one and restarts the notice.
|
|
85
|
+
*/
|
|
82
86
|
scheduleShare(options: {
|
|
83
87
|
partner: SharedObjectReference<true>;
|
|
84
88
|
adminWitness: TransactionObjectInput;
|
|
@@ -98,7 +102,10 @@ export class PartnersCalls {
|
|
|
98
102
|
};
|
|
99
103
|
}
|
|
100
104
|
|
|
101
|
-
/**
|
|
105
|
+
/**
|
|
106
|
+
* `schedule_cap` (`PartnerAdmin`): proposes moving the partner to the cap
|
|
107
|
+
* `capId`, which `applyCap` applies once `PARTNER_DELAY_MS` has passed.
|
|
108
|
+
*/
|
|
102
109
|
scheduleCap(options: {
|
|
103
110
|
partner: SharedObjectReference<true>;
|
|
104
111
|
adminWitness: TransactionObjectInput;
|
|
@@ -118,7 +125,59 @@ export class PartnersCalls {
|
|
|
118
125
|
};
|
|
119
126
|
}
|
|
120
127
|
|
|
121
|
-
/** `
|
|
128
|
+
/** `apply_share`: anyone applies the proposed share once its notice has passed. */
|
|
129
|
+
applyShare(options: { partner: SharedObjectReference<true> }) {
|
|
130
|
+
return (tx: Transaction): void => {
|
|
131
|
+
tx.moveCall({
|
|
132
|
+
target: this.#target("apply_share"),
|
|
133
|
+
arguments: [partner(tx, options.partner), tx.object.clock()],
|
|
134
|
+
});
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/** `apply_cap`: anyone applies the proposed managing cap once its notice has passed. */
|
|
139
|
+
applyCap(options: { partner: SharedObjectReference<true> }) {
|
|
140
|
+
return (tx: Transaction): void => {
|
|
141
|
+
tx.moveCall({
|
|
142
|
+
target: this.#target("apply_cap"),
|
|
143
|
+
arguments: [partner(tx, options.partner), tx.object.clock()],
|
|
144
|
+
});
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/** `cancel_share` (`PartnerAdmin`): discards the proposed share, even a ready one. */
|
|
149
|
+
cancelShare(options: {
|
|
150
|
+
partner: SharedObjectReference<true>;
|
|
151
|
+
adminWitness: TransactionObjectInput;
|
|
152
|
+
}) {
|
|
153
|
+
return (tx: Transaction): void => {
|
|
154
|
+
tx.moveCall({
|
|
155
|
+
target: this.#target("cancel_share"),
|
|
156
|
+
arguments: [
|
|
157
|
+
partner(tx, options.partner),
|
|
158
|
+
tx.object(options.adminWitness),
|
|
159
|
+
],
|
|
160
|
+
});
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/** `cancel_cap` (`PartnerAdmin`): discards the proposed managing cap, even a ready one. */
|
|
165
|
+
cancelCap(options: {
|
|
166
|
+
partner: SharedObjectReference<true>;
|
|
167
|
+
adminWitness: TransactionObjectInput;
|
|
168
|
+
}) {
|
|
169
|
+
return (tx: Transaction): void => {
|
|
170
|
+
tx.moveCall({
|
|
171
|
+
target: this.#target("cancel_cap"),
|
|
172
|
+
arguments: [
|
|
173
|
+
partner(tx, options.partner),
|
|
174
|
+
tx.object(options.adminWitness),
|
|
175
|
+
],
|
|
176
|
+
});
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/** `set_recipient`: the partner's applied cap sets where it is paid, at once. */
|
|
122
181
|
setRecipient(options: {
|
|
123
182
|
partner: SharedObjectReference<true>;
|
|
124
183
|
partnerCap: TransactionObjectInput;
|
|
@@ -132,7 +191,6 @@ export class PartnersCalls {
|
|
|
132
191
|
partner(tx, options.partner),
|
|
133
192
|
tx.object(options.partnerCap),
|
|
134
193
|
tx.pure.address(recipient),
|
|
135
|
-
tx.object.clock(),
|
|
136
194
|
],
|
|
137
195
|
});
|
|
138
196
|
};
|
|
@@ -198,6 +256,36 @@ export class PartnersTransactions {
|
|
|
198
256
|
);
|
|
199
257
|
}
|
|
200
258
|
|
|
259
|
+
applyShare(options: { partner: SharedObjectReference<true> }): Transaction {
|
|
260
|
+
const tx = new Transaction();
|
|
261
|
+
tx.add(this.call.applyShare(options));
|
|
262
|
+
return tx;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
applyCap(options: { partner: SharedObjectReference<true> }): Transaction {
|
|
266
|
+
const tx = new Transaction();
|
|
267
|
+
tx.add(this.call.applyCap(options));
|
|
268
|
+
return tx;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
cancelShare(options: {
|
|
272
|
+
adminCapId: string;
|
|
273
|
+
partner: SharedObjectReference<true>;
|
|
274
|
+
}): Transaction {
|
|
275
|
+
return this.#asPartnerAdmin(options.adminCapId, (adminWitness) =>
|
|
276
|
+
this.call.cancelShare({ ...options, adminWitness }),
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
cancelCap(options: {
|
|
281
|
+
adminCapId: string;
|
|
282
|
+
partner: SharedObjectReference<true>;
|
|
283
|
+
}): Transaction {
|
|
284
|
+
return this.#asPartnerAdmin(options.adminCapId, (adminWitness) =>
|
|
285
|
+
this.call.cancelCap({ ...options, adminWitness }),
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
|
|
201
289
|
setRecipient(options: {
|
|
202
290
|
partner: SharedObjectReference<true>;
|
|
203
291
|
partnerCapId: string;
|