@interest-protocol/blast-admin-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/aborts.d.ts +10 -0
- package/dist/aborts.d.ts.map +1 -0
- package/dist/aborts.js +40 -0
- package/dist/aborts.js.map +1 -0
- package/dist/events.d.ts +352 -27
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +307 -8
- package/dist/events.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/reducer.d.ts +40 -4
- package/dist/reducer.d.ts.map +1 -1
- package/dist/reducer.js +105 -11
- package/dist/reducer.js.map +1 -1
- package/dist/state.d.ts +208 -16
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +207 -19
- package/dist/state.js.map +1 -1
- package/dist/transactions.d.ts +45 -4
- package/dist/transactions.d.ts.map +1 -1
- package/dist/transactions.js +97 -3
- package/dist/transactions.js.map +1 -1
- package/package.json +6 -2
- package/src/aborts.ts +43 -0
- package/src/events.ts +558 -11
- package/src/index.ts +1 -0
- package/src/reducer.ts +157 -15
- package/src/state.ts +347 -27
- package/src/transactions.ts +149 -4
package/src/events.ts
CHANGED
|
@@ -1,25 +1,40 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
DelayedChange,
|
|
3
|
+
DelayedMapChange,
|
|
4
|
+
DelayedSetChange,
|
|
5
|
+
} from "@interest-protocol/blast-core/bcs";
|
|
1
6
|
import {
|
|
2
7
|
addressBcs,
|
|
8
|
+
delayedChangeBcs,
|
|
9
|
+
delayedMapChangeBcs,
|
|
10
|
+
delayedSetChangeBcs,
|
|
3
11
|
moveTypeNameBcs,
|
|
4
12
|
suiObjectIdBcs,
|
|
5
13
|
u64Bcs,
|
|
14
|
+
unitKeyBcs,
|
|
6
15
|
} from "@interest-protocol/blast-core/bcs";
|
|
7
16
|
import type { SuiEventPosition } from "@interest-protocol/blast-core/events";
|
|
8
17
|
import {
|
|
9
18
|
normalizeSuiEventPosition,
|
|
10
19
|
suiEventId,
|
|
11
20
|
} from "@interest-protocol/blast-core/events";
|
|
21
|
+
import type { BcsType } from "@mysten/sui/bcs";
|
|
12
22
|
import { bcs } from "@mysten/sui/bcs";
|
|
13
23
|
import type { SuiClientTypes } from "@mysten/sui/client";
|
|
14
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
normalizeStructTag,
|
|
26
|
+
normalizeSuiAddress,
|
|
27
|
+
parseStructTag,
|
|
28
|
+
} from "@mysten/sui/utils";
|
|
29
|
+
import { upgradeActionBcs } from "./state.ts";
|
|
15
30
|
|
|
16
31
|
const roles = bcs.vector(moveTypeNameBcs);
|
|
17
|
-
const transfer = { recipient: addressBcs, execute_after_ms: u64Bcs };
|
|
18
32
|
|
|
19
33
|
/**
|
|
20
34
|
* The `blast_admin::blast_admin_events` the ACL emits, in Move field order.
|
|
21
|
-
*
|
|
22
|
-
*
|
|
35
|
+
* Package version and administration facts use packageAdministrationEventBcs;
|
|
36
|
+
* the super admin transfer's lifecycle uses the `delayed` events under
|
|
37
|
+
* `aclDelayedKeys`.
|
|
23
38
|
*/
|
|
24
39
|
export const aclEventBcs = {
|
|
25
40
|
AdminGranted: bcs.struct("AdminGranted", {
|
|
@@ -43,11 +58,6 @@ export const aclEventBcs = {
|
|
|
43
58
|
roles,
|
|
44
59
|
was_active: bcs.bool(),
|
|
45
60
|
}),
|
|
46
|
-
SuperAdminTransferStarted: bcs.struct("SuperAdminTransferStarted", transfer),
|
|
47
|
-
SuperAdminTransferCancelled: bcs.struct(
|
|
48
|
-
"SuperAdminTransferCancelled",
|
|
49
|
-
transfer,
|
|
50
|
-
),
|
|
51
61
|
SuperAdminTransferred: bcs.struct("SuperAdminTransferred", {
|
|
52
62
|
previous_super_admin_cap_id: suiObjectIdBcs,
|
|
53
63
|
new_super_admin_cap_id: suiObjectIdBcs,
|
|
@@ -74,7 +84,11 @@ export type DecodedAclEvent = {
|
|
|
74
84
|
};
|
|
75
85
|
}[AclEventKind];
|
|
76
86
|
|
|
77
|
-
/**
|
|
87
|
+
/**
|
|
88
|
+
* Decodes one `<adminPackageId>::blast_admin_events::<Kind>` ACL event. Its
|
|
89
|
+
* `role` names are `type_name::with_defining_ids` in Move; for the immutable
|
|
90
|
+
* v1 `blast_admin` and `blast_core` they equal the original-ID names.
|
|
91
|
+
*/
|
|
78
92
|
export function decodeAclEvent(
|
|
79
93
|
event: SuiClientTypes.EventEntry,
|
|
80
94
|
adminPackageId: string,
|
|
@@ -98,6 +112,539 @@ export function decodeAclEvent(
|
|
|
98
112
|
} as DecodedAclEvent;
|
|
99
113
|
}
|
|
100
114
|
|
|
101
|
-
export function aclEventId(event:
|
|
115
|
+
export function aclEventId(event: { position: SuiEventPosition }): string {
|
|
102
116
|
return suiEventId(event.position);
|
|
103
117
|
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* The eight `blast_admin_events` structs generic over a package's OTW, in
|
|
121
|
+
* Move field order. The OTW is only in the event type.
|
|
122
|
+
*/
|
|
123
|
+
export const packageAdministrationEventBcs = {
|
|
124
|
+
VersionAdvanced: bcs.struct("VersionAdvanced", {
|
|
125
|
+
container_id: suiObjectIdBcs,
|
|
126
|
+
original_package_id: addressBcs,
|
|
127
|
+
previous_version: u64Bcs,
|
|
128
|
+
new_version: u64Bcs,
|
|
129
|
+
}),
|
|
130
|
+
PackageVersionCreated: bcs.struct("PackageVersionCreated", {
|
|
131
|
+
package_version_id: suiObjectIdBcs,
|
|
132
|
+
package_admin_id: suiObjectIdBcs,
|
|
133
|
+
valid_pause_bits: bcs.u8(),
|
|
134
|
+
paused: bcs.u8(),
|
|
135
|
+
package_witness: moveTypeNameBcs,
|
|
136
|
+
version: u64Bcs,
|
|
137
|
+
}),
|
|
138
|
+
PackageAdminCreated: bcs.struct("PackageAdminCreated", {
|
|
139
|
+
package_admin_id: suiObjectIdBcs,
|
|
140
|
+
publisher_id: suiObjectIdBcs,
|
|
141
|
+
upgrade_cap_id: suiObjectIdBcs,
|
|
142
|
+
original_package_id: suiObjectIdBcs,
|
|
143
|
+
upgrade_cap_version: u64Bcs,
|
|
144
|
+
policy: bcs.u8(),
|
|
145
|
+
}),
|
|
146
|
+
UpgradeAuthorized: bcs.struct("UpgradeAuthorized", {
|
|
147
|
+
package_admin_id: suiObjectIdBcs,
|
|
148
|
+
upgrade_cap_id: suiObjectIdBcs,
|
|
149
|
+
current_package_id: suiObjectIdBcs,
|
|
150
|
+
upgrade_cap_version: u64Bcs,
|
|
151
|
+
policy: bcs.u8(),
|
|
152
|
+
digest: bcs.vector(bcs.u8()),
|
|
153
|
+
}),
|
|
154
|
+
UpgradeCommitted: bcs.struct("UpgradeCommitted", {
|
|
155
|
+
package_admin_id: suiObjectIdBcs,
|
|
156
|
+
upgrade_cap_id: suiObjectIdBcs,
|
|
157
|
+
original_package_id: addressBcs,
|
|
158
|
+
new_package_id: suiObjectIdBcs,
|
|
159
|
+
previous_upgrade_cap_version: u64Bcs,
|
|
160
|
+
new_upgrade_cap_version: u64Bcs,
|
|
161
|
+
}),
|
|
162
|
+
UpgradeCapDestroyed: bcs.struct("UpgradeCapDestroyed", {
|
|
163
|
+
package_admin_id: suiObjectIdBcs,
|
|
164
|
+
upgrade_cap_id: suiObjectIdBcs,
|
|
165
|
+
original_package_id: addressBcs,
|
|
166
|
+
final_upgrade_cap_version: u64Bcs,
|
|
167
|
+
final_policy: bcs.u8(),
|
|
168
|
+
}),
|
|
169
|
+
Paused: bcs.struct("Paused", {
|
|
170
|
+
package_version_id: suiObjectIdBcs,
|
|
171
|
+
bits: bcs.u8(),
|
|
172
|
+
paused: bcs.u8(),
|
|
173
|
+
}),
|
|
174
|
+
Unpaused: bcs.struct("Unpaused", {
|
|
175
|
+
package_version_id: suiObjectIdBcs,
|
|
176
|
+
bits: bcs.u8(),
|
|
177
|
+
paused: bcs.u8(),
|
|
178
|
+
}),
|
|
179
|
+
};
|
|
180
|
+
export type PackageAdministrationEventKind =
|
|
181
|
+
keyof typeof packageAdministrationEventBcs;
|
|
182
|
+
export type DecodedPackageAdministrationEvent = {
|
|
183
|
+
[Kind in PackageAdministrationEventKind]: {
|
|
184
|
+
source: "package-administration";
|
|
185
|
+
kind: Kind;
|
|
186
|
+
/** The package's OTW type, from the event type. */
|
|
187
|
+
otw: string;
|
|
188
|
+
payload: ReturnType<(typeof packageAdministrationEventBcs)[Kind]["parse"]>;
|
|
189
|
+
sender: string;
|
|
190
|
+
position: SuiEventPosition;
|
|
191
|
+
};
|
|
192
|
+
}[PackageAdministrationEventKind];
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Decodes one `<adminPackageId>::blast_admin_events::<Kind><OTW>` of any package.
|
|
196
|
+
* Move records `package_witness` with `type_name::with_defining_ids`; each
|
|
197
|
+
* product defines its `PackageWitness` in its first version, so the defining
|
|
198
|
+
* ID is the original ID the SDK compares against. The event type names the
|
|
199
|
+
* original v1 `blast_admin`.
|
|
200
|
+
*/
|
|
201
|
+
export function decodePackageAdministrationEvent(
|
|
202
|
+
event: SuiClientTypes.EventEntry,
|
|
203
|
+
adminPackageId: string,
|
|
204
|
+
): DecodedPackageAdministrationEvent {
|
|
205
|
+
const tag = parseStructTag(event.eventType);
|
|
206
|
+
const otw = tag.typeParams[0];
|
|
207
|
+
if (
|
|
208
|
+
tag.address !== normalizeSuiAddress(adminPackageId) ||
|
|
209
|
+
tag.module !== "blast_admin_events" ||
|
|
210
|
+
tag.typeParams.length !== 1 ||
|
|
211
|
+
otw === undefined ||
|
|
212
|
+
typeof otw === "string" ||
|
|
213
|
+
!Object.hasOwn(packageAdministrationEventBcs, tag.name)
|
|
214
|
+
)
|
|
215
|
+
throw new TypeError(
|
|
216
|
+
`unexpected package administration event ${event.eventType}`,
|
|
217
|
+
);
|
|
218
|
+
const kind = tag.name as PackageAdministrationEventKind;
|
|
219
|
+
return {
|
|
220
|
+
source: "package-administration",
|
|
221
|
+
kind,
|
|
222
|
+
otw: normalizeStructTag(otw),
|
|
223
|
+
payload: packageAdministrationEventBcs[kind].parse(event.bcs),
|
|
224
|
+
sender: normalizeSuiAddress(event.sender),
|
|
225
|
+
position: normalizeSuiEventPosition(event),
|
|
226
|
+
} as DecodedPackageAdministrationEvent;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Every lifecycle event the `blast_admin` delayed modules emit, generic in the
|
|
231
|
+
* parent's key `K` and the value types: `delayed` (`Delayed*`),
|
|
232
|
+
* `delayed_action` (`Action*`), `delayed_set` (`Set*`, `MemberRemoved`) and
|
|
233
|
+
* `delayed_map` (`Map*`): 21 kinds.
|
|
234
|
+
*/
|
|
235
|
+
export const DELAYED_EVENT_KINDS = [
|
|
236
|
+
"DelayedCreated",
|
|
237
|
+
"DelayedScheduled",
|
|
238
|
+
"DelayedCancelled",
|
|
239
|
+
"DelayedApplied",
|
|
240
|
+
"DelayedDestroyed",
|
|
241
|
+
"ActionCreated",
|
|
242
|
+
"ActionScheduled",
|
|
243
|
+
"ActionCancelled",
|
|
244
|
+
"ActionApplied",
|
|
245
|
+
"ActionDestroyed",
|
|
246
|
+
"SetCreated",
|
|
247
|
+
"SetScheduled",
|
|
248
|
+
"SetCancelled",
|
|
249
|
+
"SetApplied",
|
|
250
|
+
"SetDestroyed",
|
|
251
|
+
"MemberRemoved",
|
|
252
|
+
"MapCreated",
|
|
253
|
+
"MapScheduled",
|
|
254
|
+
"MapCancelled",
|
|
255
|
+
"MapApplied",
|
|
256
|
+
"MapDestroyed",
|
|
257
|
+
] as const;
|
|
258
|
+
export type DelayedEventKind = (typeof DELAYED_EVENT_KINDS)[number];
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Which primitive a key names: a `Delayed<K, T>` setting, a
|
|
262
|
+
* `DelayedAction<K, A>` slot, a `DelayedSet<K, E>` allowlist or a
|
|
263
|
+
* `DelayedMap<K, E, V>` of entries.
|
|
264
|
+
*/
|
|
265
|
+
export type DelayedFamily = "setting" | "action" | "set" | "map";
|
|
266
|
+
|
|
267
|
+
type FamilyKinds = {
|
|
268
|
+
setting: Extract<DelayedEventKind, `Delayed${string}`>;
|
|
269
|
+
action: Extract<DelayedEventKind, `Action${string}`>;
|
|
270
|
+
set: Extract<DelayedEventKind, `Set${string}`> | "MemberRemoved";
|
|
271
|
+
map: Extract<DelayedEventKind, `Map${string}`>;
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
const FAMILY_MODULES: Record<DelayedFamily, string> = {
|
|
275
|
+
setting: "delayed",
|
|
276
|
+
action: "delayed_action",
|
|
277
|
+
set: "delayed_set",
|
|
278
|
+
map: "delayed_map",
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
const FAMILY_KINDS: {
|
|
282
|
+
[Family in DelayedFamily]: readonly FamilyKinds[Family][];
|
|
283
|
+
} = {
|
|
284
|
+
setting: [
|
|
285
|
+
"DelayedCreated",
|
|
286
|
+
"DelayedScheduled",
|
|
287
|
+
"DelayedCancelled",
|
|
288
|
+
"DelayedApplied",
|
|
289
|
+
"DelayedDestroyed",
|
|
290
|
+
],
|
|
291
|
+
action: [
|
|
292
|
+
"ActionCreated",
|
|
293
|
+
"ActionScheduled",
|
|
294
|
+
"ActionCancelled",
|
|
295
|
+
"ActionApplied",
|
|
296
|
+
"ActionDestroyed",
|
|
297
|
+
],
|
|
298
|
+
set: [
|
|
299
|
+
"SetCreated",
|
|
300
|
+
"SetScheduled",
|
|
301
|
+
"SetCancelled",
|
|
302
|
+
"SetApplied",
|
|
303
|
+
"SetDestroyed",
|
|
304
|
+
"MemberRemoved",
|
|
305
|
+
],
|
|
306
|
+
map: [
|
|
307
|
+
"MapCreated",
|
|
308
|
+
"MapScheduled",
|
|
309
|
+
"MapCancelled",
|
|
310
|
+
"MapApplied",
|
|
311
|
+
"MapDestroyed",
|
|
312
|
+
],
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
/** Any `BcsType` decoding `T`, whatever it serializes from. */
|
|
316
|
+
type BcsDecoder<T> = Pick<BcsType<T, never>, "parse">;
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* One consumer key `K`. Owners never expose `K`'s constructor, so its type
|
|
320
|
+
* authenticates every event emitted under it; the value types are checked
|
|
321
|
+
* too. A map key also names its entry type `E`.
|
|
322
|
+
*/
|
|
323
|
+
export type DelayedKeySpec<Key = unknown, Value = unknown, Entry = unknown> = {
|
|
324
|
+
/** `<module>::<Struct>` of `K` in the consumer's original package. */
|
|
325
|
+
key: string;
|
|
326
|
+
family: DelayedFamily;
|
|
327
|
+
keyBcs: BcsDecoder<Key>;
|
|
328
|
+
/** BCS of the last type argument: `T`, `A`, `E` of a set, or `V` of a map. */
|
|
329
|
+
valueBcs: BcsDecoder<Value>;
|
|
330
|
+
/** The last type argument; `{package}` stands for the consumer's original package. */
|
|
331
|
+
valueType: string;
|
|
332
|
+
/** A map's entry type `E`, its BCS and its type tag. */
|
|
333
|
+
entryBcs?: BcsDecoder<Entry>;
|
|
334
|
+
entryType?: string;
|
|
335
|
+
};
|
|
336
|
+
export type DelayedKeySpecs = Readonly<Record<string, DelayedKeySpec>>;
|
|
337
|
+
|
|
338
|
+
/** Move field order of each event; `Value` is `T`, `A`, `E` or `V`. */
|
|
339
|
+
export type DelayedEventPayloads<Key, Value, Entry> = {
|
|
340
|
+
DelayedCreated: { parent: string; key: Key; value: Value; delay_ms: bigint };
|
|
341
|
+
DelayedScheduled: {
|
|
342
|
+
parent: string;
|
|
343
|
+
key: Key;
|
|
344
|
+
value: Value;
|
|
345
|
+
delay_ms: bigint;
|
|
346
|
+
ready_at_ms: bigint;
|
|
347
|
+
};
|
|
348
|
+
DelayedCancelled: {
|
|
349
|
+
parent: string;
|
|
350
|
+
key: Key;
|
|
351
|
+
value: Value;
|
|
352
|
+
delay_ms: bigint;
|
|
353
|
+
ready_at_ms: bigint;
|
|
354
|
+
};
|
|
355
|
+
DelayedApplied: {
|
|
356
|
+
parent: string;
|
|
357
|
+
key: Key;
|
|
358
|
+
previous_value: Value;
|
|
359
|
+
value: Value;
|
|
360
|
+
delay_ms: bigint;
|
|
361
|
+
};
|
|
362
|
+
DelayedDestroyed: { parent: string; key: Key };
|
|
363
|
+
ActionCreated: { parent: string; key: Key; delay_ms: bigint };
|
|
364
|
+
ActionScheduled: {
|
|
365
|
+
parent: string;
|
|
366
|
+
key: Key;
|
|
367
|
+
change: DelayedChange<Value>;
|
|
368
|
+
delay_ms: bigint;
|
|
369
|
+
ready_at_ms: bigint;
|
|
370
|
+
};
|
|
371
|
+
ActionCancelled: {
|
|
372
|
+
parent: string;
|
|
373
|
+
key: Key;
|
|
374
|
+
change: DelayedChange<Value>;
|
|
375
|
+
delay_ms: bigint;
|
|
376
|
+
ready_at_ms: bigint;
|
|
377
|
+
};
|
|
378
|
+
ActionApplied: {
|
|
379
|
+
parent: string;
|
|
380
|
+
key: Key;
|
|
381
|
+
change: DelayedChange<Value>;
|
|
382
|
+
delay_ms: bigint;
|
|
383
|
+
};
|
|
384
|
+
ActionDestroyed: { parent: string; key: Key };
|
|
385
|
+
SetCreated: { parent: string; key: Key; delay_ms: bigint };
|
|
386
|
+
SetScheduled: {
|
|
387
|
+
parent: string;
|
|
388
|
+
key: Key;
|
|
389
|
+
change: DelayedSetChange<Value>;
|
|
390
|
+
delay_ms: bigint;
|
|
391
|
+
ready_at_ms: bigint;
|
|
392
|
+
};
|
|
393
|
+
SetCancelled: {
|
|
394
|
+
parent: string;
|
|
395
|
+
key: Key;
|
|
396
|
+
change: DelayedSetChange<Value>;
|
|
397
|
+
delay_ms: bigint;
|
|
398
|
+
ready_at_ms: bigint;
|
|
399
|
+
};
|
|
400
|
+
SetApplied: {
|
|
401
|
+
parent: string;
|
|
402
|
+
key: Key;
|
|
403
|
+
change: DelayedSetChange<Value>;
|
|
404
|
+
delay_ms: bigint;
|
|
405
|
+
};
|
|
406
|
+
SetDestroyed: { parent: string; key: Key };
|
|
407
|
+
MemberRemoved: { parent: string; key: Key; member: Value };
|
|
408
|
+
MapCreated: { parent: string; key: Key; delay_ms: bigint };
|
|
409
|
+
MapScheduled: {
|
|
410
|
+
parent: string;
|
|
411
|
+
key: Key;
|
|
412
|
+
change: DelayedMapChange<Entry, Value>;
|
|
413
|
+
delay_ms: bigint;
|
|
414
|
+
ready_at_ms: bigint;
|
|
415
|
+
};
|
|
416
|
+
MapCancelled: {
|
|
417
|
+
parent: string;
|
|
418
|
+
key: Key;
|
|
419
|
+
change: DelayedMapChange<Entry, Value>;
|
|
420
|
+
delay_ms: bigint;
|
|
421
|
+
ready_at_ms: bigint;
|
|
422
|
+
};
|
|
423
|
+
MapApplied: {
|
|
424
|
+
parent: string;
|
|
425
|
+
key: Key;
|
|
426
|
+
change: DelayedMapChange<Entry, Value>;
|
|
427
|
+
delay_ms: bigint;
|
|
428
|
+
};
|
|
429
|
+
MapDestroyed: { parent: string; key: Key };
|
|
430
|
+
};
|
|
431
|
+
|
|
432
|
+
type SpecKey<Spec> =
|
|
433
|
+
Spec extends DelayedKeySpec<infer Key, unknown, unknown> ? Key : never;
|
|
434
|
+
type SpecValue<Spec> =
|
|
435
|
+
Spec extends DelayedKeySpec<unknown, infer Value, unknown> ? Value : never;
|
|
436
|
+
type SpecEntry<Spec> = Spec extends { entryBcs: BcsDecoder<infer Entry> }
|
|
437
|
+
? Entry
|
|
438
|
+
: never;
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* A decoded delayed event. `name` is the consumer's registry name for `K`;
|
|
442
|
+
* `parent` is the ID of the object storing the value.
|
|
443
|
+
*/
|
|
444
|
+
export type DecodedDelayedEvent<Specs extends DelayedKeySpecs> = {
|
|
445
|
+
[Name in keyof Specs & string]: {
|
|
446
|
+
[Kind in FamilyKinds[Specs[Name]["family"]]]: {
|
|
447
|
+
source: "delayed";
|
|
448
|
+
kind: Kind;
|
|
449
|
+
name: Name;
|
|
450
|
+
payload: DelayedEventPayloads<
|
|
451
|
+
SpecKey<Specs[Name]>,
|
|
452
|
+
SpecValue<Specs[Name]>,
|
|
453
|
+
SpecEntry<Specs[Name]>
|
|
454
|
+
>[Kind];
|
|
455
|
+
sender: string;
|
|
456
|
+
position: SuiEventPosition;
|
|
457
|
+
};
|
|
458
|
+
}[FamilyKinds[Specs[Name]["family"]]];
|
|
459
|
+
}[keyof Specs & string];
|
|
460
|
+
|
|
461
|
+
/** The `blast_admin` module that emits `kind`. */
|
|
462
|
+
export function delayedEventModule(kind: DelayedEventKind): string {
|
|
463
|
+
const family = (Object.keys(FAMILY_KINDS) as DelayedFamily[]).find(
|
|
464
|
+
(candidate) =>
|
|
465
|
+
(FAMILY_KINDS[candidate] as readonly string[]).includes(kind),
|
|
466
|
+
);
|
|
467
|
+
if (family === undefined)
|
|
468
|
+
throw new TypeError(`unknown delayed event ${kind}`);
|
|
469
|
+
return FAMILY_MODULES[family];
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/** Whether `eventType` is a lifecycle event of `adminPackageId`'s delayed modules. */
|
|
473
|
+
export function isDelayedEventType(
|
|
474
|
+
eventType: string,
|
|
475
|
+
adminPackageId: string,
|
|
476
|
+
): boolean {
|
|
477
|
+
const tag = parseStructTag(eventType);
|
|
478
|
+
return (
|
|
479
|
+
tag.address === normalizeSuiAddress(adminPackageId) &&
|
|
480
|
+
Object.values(FAMILY_MODULES).includes(tag.module)
|
|
481
|
+
);
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/**
|
|
485
|
+
* Decodes one `blast_admin` delayed event whose key belongs to `packageId`
|
|
486
|
+
* (the consumer's original package) and is listed in `keys`.
|
|
487
|
+
*/
|
|
488
|
+
export function decodeDelayedEvent<const Specs extends DelayedKeySpecs>(
|
|
489
|
+
event: SuiClientTypes.EventEntry,
|
|
490
|
+
identity: { adminPackageId: string; packageId: string; keys: Specs },
|
|
491
|
+
): DecodedDelayedEvent<Specs> {
|
|
492
|
+
const tag = parseStructTag(event.eventType);
|
|
493
|
+
const kind = tag.name as DelayedEventKind;
|
|
494
|
+
const keyTag = tag.typeParams[0];
|
|
495
|
+
if (
|
|
496
|
+
tag.address !== normalizeSuiAddress(identity.adminPackageId) ||
|
|
497
|
+
!DELAYED_EVENT_KINDS.includes(kind) ||
|
|
498
|
+
keyTag === undefined ||
|
|
499
|
+
typeof keyTag === "string"
|
|
500
|
+
)
|
|
501
|
+
throw new TypeError(`unexpected delayed event type ${event.eventType}`);
|
|
502
|
+
const packageId = normalizeSuiAddress(identity.packageId);
|
|
503
|
+
const keyType = normalizeStructTag(keyTag);
|
|
504
|
+
const entry = Object.entries(identity.keys).find(
|
|
505
|
+
([, spec]) => normalizeStructTag(`${packageId}::${spec.key}`) === keyType,
|
|
506
|
+
);
|
|
507
|
+
if (entry === undefined)
|
|
508
|
+
throw new TypeError(`unexpected delayed event key ${event.eventType}`);
|
|
509
|
+
const [name, spec] = entry;
|
|
510
|
+
const local = (type: string) => type.replaceAll("{package}", packageId);
|
|
511
|
+
const valueTypes =
|
|
512
|
+
spec.family === "map"
|
|
513
|
+
? [local(spec.entryType ?? ""), local(spec.valueType)]
|
|
514
|
+
: [local(spec.valueType)];
|
|
515
|
+
if (
|
|
516
|
+
!(FAMILY_KINDS[spec.family] as readonly string[]).includes(kind) ||
|
|
517
|
+
normalizeStructTag(event.eventType) !==
|
|
518
|
+
normalizeStructTag(
|
|
519
|
+
`${tag.address}::${FAMILY_MODULES[spec.family]}::${kind}<${[keyType, ...valueTypes].join(", ")}>`,
|
|
520
|
+
)
|
|
521
|
+
)
|
|
522
|
+
throw new TypeError(`unexpected delayed event key ${event.eventType}`);
|
|
523
|
+
return {
|
|
524
|
+
source: "delayed",
|
|
525
|
+
kind,
|
|
526
|
+
name,
|
|
527
|
+
payload: delayedEventBcs(kind, spec).parse(event.bcs),
|
|
528
|
+
sender: normalizeSuiAddress(event.sender),
|
|
529
|
+
position: normalizeSuiEventPosition(event),
|
|
530
|
+
} as DecodedDelayedEvent<Specs>;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
/** BCS of one delayed event under `spec`, in Move field order. */
|
|
534
|
+
export function delayedEventBcs(
|
|
535
|
+
kind: DelayedEventKind,
|
|
536
|
+
spec: Pick<DelayedKeySpec, "keyBcs" | "valueBcs" | "entryBcs">,
|
|
537
|
+
): BcsType<Record<string, unknown>, Record<string, unknown>> {
|
|
538
|
+
// Every decoder in a spec is a full BcsType; the spec only promises `parse`.
|
|
539
|
+
const value = spec.valueBcs as BcsType<unknown, unknown>;
|
|
540
|
+
const head = {
|
|
541
|
+
parent: suiObjectIdBcs,
|
|
542
|
+
key: spec.keyBcs as BcsType<unknown, unknown>,
|
|
543
|
+
};
|
|
544
|
+
const timing = { delay_ms: u64Bcs, ready_at_ms: u64Bcs };
|
|
545
|
+
const change = delayedChangeBcs(value);
|
|
546
|
+
const setChange = delayedSetChangeBcs(value);
|
|
547
|
+
const mapChange = spec.entryBcs
|
|
548
|
+
? delayedMapChangeBcs(spec.entryBcs as BcsType<unknown, unknown>, value)
|
|
549
|
+
: change;
|
|
550
|
+
const fields = {
|
|
551
|
+
DelayedCreated: { value, delay_ms: u64Bcs },
|
|
552
|
+
DelayedScheduled: { value, ...timing },
|
|
553
|
+
DelayedCancelled: { value, ...timing },
|
|
554
|
+
DelayedApplied: { previous_value: value, value, delay_ms: u64Bcs },
|
|
555
|
+
DelayedDestroyed: {},
|
|
556
|
+
ActionCreated: { delay_ms: u64Bcs },
|
|
557
|
+
ActionScheduled: { change, ...timing },
|
|
558
|
+
ActionCancelled: { change, ...timing },
|
|
559
|
+
ActionApplied: { change, delay_ms: u64Bcs },
|
|
560
|
+
ActionDestroyed: {},
|
|
561
|
+
SetCreated: { delay_ms: u64Bcs },
|
|
562
|
+
SetScheduled: { change: setChange, ...timing },
|
|
563
|
+
SetCancelled: { change: setChange, ...timing },
|
|
564
|
+
SetApplied: { change: setChange, delay_ms: u64Bcs },
|
|
565
|
+
SetDestroyed: {},
|
|
566
|
+
MemberRemoved: { member: value },
|
|
567
|
+
MapCreated: { delay_ms: u64Bcs },
|
|
568
|
+
MapScheduled: { change: mapChange, ...timing },
|
|
569
|
+
MapCancelled: { change: mapChange, ...timing },
|
|
570
|
+
MapApplied: { change: mapChange, delay_ms: u64Bcs },
|
|
571
|
+
MapDestroyed: {},
|
|
572
|
+
}[kind];
|
|
573
|
+
return bcs.struct(kind, { ...head, ...fields }) as unknown as BcsType<
|
|
574
|
+
Record<string, unknown>,
|
|
575
|
+
Record<string, unknown>
|
|
576
|
+
>;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
/**
|
|
580
|
+
* `package_admin::UpgradeKey<otw>`: one package's upgrade and immutability
|
|
581
|
+
* slot, `DelayedAction<UpgradeKey<OTW>, UpgradeAction>`. The key lives in the
|
|
582
|
+
* admin package, so decode with `packageId` = the admin package ID.
|
|
583
|
+
*/
|
|
584
|
+
export function upgradeDelayedKey(otw: string) {
|
|
585
|
+
return {
|
|
586
|
+
key: `package_admin::UpgradeKey<${normalizeStructTag(otw)}>`,
|
|
587
|
+
family: "action",
|
|
588
|
+
keyBcs: unitKeyBcs,
|
|
589
|
+
valueBcs: upgradeActionBcs,
|
|
590
|
+
valueType: "{package}::package_admin::UpgradeAction",
|
|
591
|
+
} as const satisfies DelayedKeySpec;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
export type DecodedUpgradeDelayedEvent = DecodedDelayedEvent<{
|
|
595
|
+
Upgrade: ReturnType<typeof upgradeDelayedKey>;
|
|
596
|
+
}> & { otw: string };
|
|
597
|
+
|
|
598
|
+
/** Decodes a `delayed_action` event keyed by any package's `UpgradeKey<OTW>`. */
|
|
599
|
+
export function decodeUpgradeDelayedEvent(
|
|
600
|
+
event: SuiClientTypes.EventEntry,
|
|
601
|
+
adminPackageId: string,
|
|
602
|
+
): DecodedUpgradeDelayedEvent {
|
|
603
|
+
const keyTag = parseStructTag(event.eventType).typeParams[0];
|
|
604
|
+
const otw =
|
|
605
|
+
keyTag !== undefined && typeof keyTag !== "string"
|
|
606
|
+
? keyTag.typeParams[0]
|
|
607
|
+
: undefined;
|
|
608
|
+
if (
|
|
609
|
+
keyTag === undefined ||
|
|
610
|
+
typeof keyTag === "string" ||
|
|
611
|
+
keyTag.address !== normalizeSuiAddress(adminPackageId) ||
|
|
612
|
+
keyTag.module !== "package_admin" ||
|
|
613
|
+
keyTag.name !== "UpgradeKey" ||
|
|
614
|
+
otw === undefined ||
|
|
615
|
+
typeof otw === "string"
|
|
616
|
+
)
|
|
617
|
+
throw new TypeError(`unexpected upgrade delayed event ${event.eventType}`);
|
|
618
|
+
const type = normalizeStructTag(otw);
|
|
619
|
+
const decoded = decodeDelayedEvent(event, {
|
|
620
|
+
adminPackageId,
|
|
621
|
+
packageId: adminPackageId,
|
|
622
|
+
keys: { Upgrade: upgradeDelayedKey(type) },
|
|
623
|
+
});
|
|
624
|
+
return { ...decoded, otw: type };
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
/** The ACL's one key: the super admin transfer slot, `DelayedAction<SuperAdminTransfer, address>`. */
|
|
628
|
+
export const aclDelayedKeys = {
|
|
629
|
+
SuperAdminTransfer: {
|
|
630
|
+
key: "blast_acl::SuperAdminTransfer",
|
|
631
|
+
family: "action",
|
|
632
|
+
keyBcs: unitKeyBcs,
|
|
633
|
+
valueBcs: addressBcs,
|
|
634
|
+
valueType: "address",
|
|
635
|
+
},
|
|
636
|
+
} as const satisfies DelayedKeySpecs;
|
|
637
|
+
|
|
638
|
+
export type DecodedAclDelayedEvent = DecodedDelayedEvent<typeof aclDelayedKeys>;
|
|
639
|
+
|
|
640
|
+
/** Decodes the ACL's super admin transfer lifecycle. */
|
|
641
|
+
export function decodeAclDelayedEvent(
|
|
642
|
+
event: SuiClientTypes.EventEntry,
|
|
643
|
+
adminPackageId: string,
|
|
644
|
+
): DecodedAclDelayedEvent {
|
|
645
|
+
return decodeDelayedEvent(event, {
|
|
646
|
+
adminPackageId,
|
|
647
|
+
packageId: adminPackageId,
|
|
648
|
+
keys: aclDelayedKeys,
|
|
649
|
+
});
|
|
650
|
+
}
|
package/src/index.ts
CHANGED