@misofm/partyos 0.1.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/LICENSE +201 -0
- package/README.md +50 -0
- package/dist/client.d.ts +84 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +109 -0
- package/dist/client.js.map +1 -0
- package/dist/contracts/partyos/deps/sui/vec_set.d.ts +21 -0
- package/dist/contracts/partyos/deps/sui/vec_set.d.ts.map +1 -0
- package/dist/contracts/partyos/deps/sui/vec_set.js +20 -0
- package/dist/contracts/partyos/deps/sui/vec_set.js.map +1 -0
- package/dist/contracts/partyos/party.d.ts +481 -0
- package/dist/contracts/partyos/party.d.ts.map +1 -0
- package/dist/contracts/partyos/party.js +527 -0
- package/dist/contracts/partyos/party.js.map +1 -0
- package/dist/contracts/utils/index.d.ts +104 -0
- package/dist/contracts/utils/index.d.ts.map +1 -0
- package/dist/contracts/utils/index.js +272 -0
- package/dist/contracts/utils/index.js.map +1 -0
- package/dist/contracts.d.ts +12 -0
- package/dist/contracts.d.ts.map +1 -0
- package/dist/contracts.js +21 -0
- package/dist/contracts.js.map +1 -0
- package/dist/deployments.d.ts +33 -0
- package/dist/deployments.d.ts.map +1 -0
- package/dist/deployments.js +63 -0
- package/dist/deployments.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/internal.d.ts +5 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +24 -0
- package/dist/internal.js.map +1 -0
- package/dist/queries.d.ts +37 -0
- package/dist/queries.d.ts.map +1 -0
- package/dist/queries.js +123 -0
- package/dist/queries.js.map +1 -0
- package/dist/transactions.d.ts +74 -0
- package/dist/transactions.d.ts.map +1 -0
- package/dist/transactions.js +85 -0
- package/dist/transactions.js.map +1 -0
- package/dist/types.d.ts +12 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +4 -0
- package/dist/types.js.map +1 -0
- package/package.json +97 -0
- package/src/client.ts +165 -0
- package/src/contracts/partyos/deps/sui/vec_set.ts +22 -0
- package/src/contracts/partyos/party.ts +798 -0
- package/src/contracts/utils/index.ts +428 -0
- package/src/contracts.ts +31 -0
- package/src/deployments.ts +90 -0
- package/src/index.ts +15 -0
- package/src/internal.ts +30 -0
- package/src/queries.ts +167 -0
- package/src/transactions.ts +167 -0
- package/src/types.ts +18 -0
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
|
|
2
|
+
import {
|
|
3
|
+
bcs,
|
|
4
|
+
type BcsType,
|
|
5
|
+
type TypeTag,
|
|
6
|
+
TypeTagSerializer,
|
|
7
|
+
BcsStruct,
|
|
8
|
+
BcsEnum,
|
|
9
|
+
BcsTuple,
|
|
10
|
+
} from '@mysten/sui/bcs';
|
|
11
|
+
import { normalizeStructTag, normalizeSuiAddress } from '@mysten/sui/utils';
|
|
12
|
+
import {
|
|
13
|
+
type TransactionArgument,
|
|
14
|
+
type TransactionObjectArgument,
|
|
15
|
+
isArgument,
|
|
16
|
+
} from '@mysten/sui/transactions';
|
|
17
|
+
import { type ClientWithCoreApi, type SuiClientTypes } from '@mysten/sui/client';
|
|
18
|
+
|
|
19
|
+
const MOVE_STDLIB_ADDRESS = normalizeSuiAddress('0x1');
|
|
20
|
+
const SUI_FRAMEWORK_ADDRESS = normalizeSuiAddress('0x2');
|
|
21
|
+
|
|
22
|
+
export type RawTransactionArgument<T> = T | TransactionArgument;
|
|
23
|
+
|
|
24
|
+
export type GetOptions<Include extends Omit<SuiClientTypes.ObjectInclude, 'content'> = {}> =
|
|
25
|
+
SuiClientTypes.GetObjectOptions<Include> & { client: ClientWithCoreApi };
|
|
26
|
+
|
|
27
|
+
export type GetManyOptions<Include extends Omit<SuiClientTypes.ObjectInclude, 'content'> = {}> =
|
|
28
|
+
SuiClientTypes.GetObjectsOptions<Include> & { client: ClientWithCoreApi };
|
|
29
|
+
|
|
30
|
+
export function getPureBcsSchema(typeTag: string | TypeTag): BcsType<any> | null {
|
|
31
|
+
const parsedTag = typeof typeTag === 'string' ? TypeTagSerializer.parseFromStr(typeTag) : typeTag;
|
|
32
|
+
|
|
33
|
+
if ('u8' in parsedTag) {
|
|
34
|
+
return bcs.U8;
|
|
35
|
+
} else if ('u16' in parsedTag) {
|
|
36
|
+
return bcs.U16;
|
|
37
|
+
} else if ('u32' in parsedTag) {
|
|
38
|
+
return bcs.U32;
|
|
39
|
+
} else if ('u64' in parsedTag) {
|
|
40
|
+
return bcs.U64;
|
|
41
|
+
} else if ('u128' in parsedTag) {
|
|
42
|
+
return bcs.U128;
|
|
43
|
+
} else if ('u256' in parsedTag) {
|
|
44
|
+
return bcs.U256;
|
|
45
|
+
} else if ('address' in parsedTag) {
|
|
46
|
+
return bcs.Address;
|
|
47
|
+
} else if ('bool' in parsedTag) {
|
|
48
|
+
return bcs.Bool;
|
|
49
|
+
} else if ('vector' in parsedTag) {
|
|
50
|
+
const type = getPureBcsSchema(parsedTag.vector);
|
|
51
|
+
return type ? bcs.vector(type) : null;
|
|
52
|
+
} else if ('struct' in parsedTag) {
|
|
53
|
+
const structTag = parsedTag.struct;
|
|
54
|
+
const pkg = normalizeSuiAddress(structTag.address);
|
|
55
|
+
|
|
56
|
+
if (pkg === MOVE_STDLIB_ADDRESS) {
|
|
57
|
+
if (
|
|
58
|
+
(structTag.module === 'ascii' || structTag.module === 'string') &&
|
|
59
|
+
structTag.name === 'String'
|
|
60
|
+
) {
|
|
61
|
+
return bcs.String;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (structTag.module === 'option' && structTag.name === 'Option') {
|
|
65
|
+
const inner = structTag.typeParams[0];
|
|
66
|
+
const type = inner ? getPureBcsSchema(inner) : null;
|
|
67
|
+
return type ? bcs.option(type) : null;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (
|
|
72
|
+
pkg === SUI_FRAMEWORK_ADDRESS &&
|
|
73
|
+
structTag.module === 'object' &&
|
|
74
|
+
(structTag.name === 'ID' || structTag.name === 'UID')
|
|
75
|
+
) {
|
|
76
|
+
return bcs.Address;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export function normalizeMoveArguments(
|
|
84
|
+
args: unknown[] | object,
|
|
85
|
+
argTypes: readonly (string | null)[],
|
|
86
|
+
parameterNames?: string[],
|
|
87
|
+
) {
|
|
88
|
+
const argLen = Array.isArray(args) ? args.length : Object.keys(args).length;
|
|
89
|
+
if (parameterNames && argLen !== parameterNames.length) {
|
|
90
|
+
throw new Error(
|
|
91
|
+
`Invalid number of arguments, expected ${parameterNames.length}, got ${argLen}`,
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const normalizedArgs: TransactionArgument[] = [];
|
|
96
|
+
|
|
97
|
+
let index = 0;
|
|
98
|
+
for (const argType of argTypes) {
|
|
99
|
+
if (argType === '0x2::clock::Clock') {
|
|
100
|
+
normalizedArgs.push((tx) => tx.object.clock());
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (argType === '0x2::random::Random') {
|
|
105
|
+
normalizedArgs.push((tx) => tx.object.random());
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (argType === '0x2::deny_list::DenyList') {
|
|
110
|
+
normalizedArgs.push((tx) => tx.object.denyList());
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (argType === '0x2::accumulator::AccumulatorRoot') {
|
|
115
|
+
// Chain-wide shared singleton at a fixed address (SUI_ACCUMULATOR_ROOT_OBJECT_ID).
|
|
116
|
+
normalizedArgs.push((tx) => tx.object('0xacc'));
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (argType === '0x3::sui_system::SuiSystemState') {
|
|
121
|
+
normalizedArgs.push((tx) => tx.object.system());
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
let arg;
|
|
126
|
+
if (Array.isArray(args)) {
|
|
127
|
+
if (index >= args.length) {
|
|
128
|
+
throw new Error(
|
|
129
|
+
`Invalid number of arguments, expected at least ${index + 1}, got ${args.length}`,
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
arg = args[index];
|
|
133
|
+
} else {
|
|
134
|
+
if (!parameterNames) {
|
|
135
|
+
throw new Error(`Expected arguments to be passed as an array`);
|
|
136
|
+
}
|
|
137
|
+
const name = parameterNames[index];
|
|
138
|
+
arg =
|
|
139
|
+
name !== undefined && Object.prototype.hasOwnProperty.call(args, name)
|
|
140
|
+
? args[name as keyof typeof args]
|
|
141
|
+
: undefined;
|
|
142
|
+
|
|
143
|
+
if (arg === undefined) {
|
|
144
|
+
throw new Error(`Parameter ${name} is required`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
index += 1;
|
|
149
|
+
|
|
150
|
+
if (typeof arg === 'function' || isArgument(arg)) {
|
|
151
|
+
normalizedArgs.push(arg as TransactionArgument);
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const bcsType = argType === null ? null : getPureBcsSchema(argType);
|
|
156
|
+
|
|
157
|
+
if (bcsType) {
|
|
158
|
+
const bytes = bcsType.serialize(arg as never);
|
|
159
|
+
normalizedArgs.push((tx) => tx.pure(bytes));
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (typeof arg === 'string') {
|
|
164
|
+
normalizedArgs.push((tx) => tx.object(arg));
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
throw new Error(`Invalid argument ${stringify(arg)} for type ${argType}`);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return normalizedArgs;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/* -------------------------- Config-mapped arguments -------------------------- */
|
|
175
|
+
|
|
176
|
+
/** Context passed to config resolver functions. */
|
|
177
|
+
export interface ConfigResolverContext {
|
|
178
|
+
/**
|
|
179
|
+
* The matched parameter's own instantiated type arguments (not the whole function's type
|
|
180
|
+
* argument tuple). Concrete instantiations are canonical type tags; generic positions pass
|
|
181
|
+
* the caller's `typeArguments` strings through as provided.
|
|
182
|
+
*/
|
|
183
|
+
typeArguments: string[];
|
|
184
|
+
/** The package address the generated call will be sent to. */
|
|
185
|
+
packageAddress: string;
|
|
186
|
+
/** The Move module of the generated call. */
|
|
187
|
+
moduleName: string;
|
|
188
|
+
/** The Move function of the generated call. */
|
|
189
|
+
functionName: string;
|
|
190
|
+
/** The Move name of the matched parameter, when the summary includes parameter names. */
|
|
191
|
+
parameterName?: string;
|
|
192
|
+
/** The matched parameter's position in the generated function's arguments. */
|
|
193
|
+
parameterIndex: number;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* A non-callback transaction argument in a generated config object, used for keys whose matched
|
|
198
|
+
* parameter can't be supplied as an object id string.
|
|
199
|
+
*/
|
|
200
|
+
export type ConfigObjectValue = Exclude<TransactionObjectArgument, (...args: never[]) => unknown>;
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* A plain value in a generated config object: an object id or a non-callback transaction
|
|
204
|
+
* argument. Keys that can resolve multiple bindings are typed as resolver functions instead.
|
|
205
|
+
*/
|
|
206
|
+
export type ConfigValue = string | ConfigObjectValue;
|
|
207
|
+
|
|
208
|
+
/* -------------------------- Move type tags -------------------------- */
|
|
209
|
+
|
|
210
|
+
/** A type argument: a type tag string, or a BCS type whose name is a Move type. */
|
|
211
|
+
export type TypeArgument = string | BcsType<any>;
|
|
212
|
+
|
|
213
|
+
export interface TypeTagOptions {
|
|
214
|
+
package?: string;
|
|
215
|
+
typeArguments?: readonly TypeArgument[];
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* `typeArguments` is required when the type's name contains unfilled
|
|
220
|
+
* `phantom X` parameters (at any depth). Everything else — argument arity,
|
|
221
|
+
* position contents, and tag validity — is validated at runtime.
|
|
222
|
+
*/
|
|
223
|
+
type TypeTagParams<Name extends string> = Name extends `${string}phantom ${string}`
|
|
224
|
+
? [options: TypeTagOptions & { typeArguments: readonly TypeArgument[] }]
|
|
225
|
+
: [options?: TypeTagOptions];
|
|
226
|
+
|
|
227
|
+
type ResolveTypeTagOptions<Name extends string> = { client: ClientWithCoreApi } & (
|
|
228
|
+
Name extends `${string}phantom ${string}`
|
|
229
|
+
? TypeTagOptions & { typeArguments: readonly TypeArgument[] }
|
|
230
|
+
: TypeTagOptions
|
|
231
|
+
);
|
|
232
|
+
|
|
233
|
+
const HAS_PHANTOM_REGEX = /phantom [A-Za-z_$][A-Za-z0-9_$]*/;
|
|
234
|
+
|
|
235
|
+
function splitTopLevelTypeArgs(inner: string): string[] {
|
|
236
|
+
const parts: string[] = [];
|
|
237
|
+
let depth = 0;
|
|
238
|
+
let current = '';
|
|
239
|
+
for (const char of inner) {
|
|
240
|
+
if (char === ',' && depth === 0) {
|
|
241
|
+
parts.push(current.trim());
|
|
242
|
+
current = '';
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
if (char === '<') depth++;
|
|
246
|
+
if (char === '>') depth--;
|
|
247
|
+
current += char;
|
|
248
|
+
}
|
|
249
|
+
if (current) parts.push(current.trim());
|
|
250
|
+
return parts;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
function buildTypeTag(name: string, options: TypeTagOptions | undefined): string {
|
|
254
|
+
const lt = name.indexOf('<');
|
|
255
|
+
const base = lt === -1 ? name : name.slice(0, lt);
|
|
256
|
+
|
|
257
|
+
if (base.split('::').length !== 3) {
|
|
258
|
+
throw new Error(`${name} is not a top-level Move type`);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
let result = name;
|
|
262
|
+
|
|
263
|
+
if (options?.typeArguments) {
|
|
264
|
+
const baked = lt === -1 ? [] : splitTopLevelTypeArgs(name.slice(lt + 1, -1));
|
|
265
|
+
const supplied = options.typeArguments.map((arg) => {
|
|
266
|
+
if (typeof arg === 'string') {
|
|
267
|
+
return arg;
|
|
268
|
+
}
|
|
269
|
+
if (arg && typeof arg.serialize === 'function' && typeof arg.name === 'string') {
|
|
270
|
+
return arg.name;
|
|
271
|
+
}
|
|
272
|
+
throw new Error(`Invalid type argument ${stringify(arg)}`);
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
if (supplied.length !== baked.length) {
|
|
276
|
+
throw new Error(
|
|
277
|
+
`Expected ${baked.length} type arguments for ${base}, got ${supplied.length}`,
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
result = supplied.length === 0 ? base : `${base}<${supplied.join(', ')}>`;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if (HAS_PHANTOM_REGEX.test(result)) {
|
|
285
|
+
throw new Error(
|
|
286
|
+
options?.typeArguments
|
|
287
|
+
? `A type argument contains an unfilled phantom parameter in ${result}`
|
|
288
|
+
: `Missing type arguments for ${result}`,
|
|
289
|
+
);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
if (options?.package) {
|
|
293
|
+
const [, ...rest] = result.split('::');
|
|
294
|
+
result = [options.package, ...rest].join('::');
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// fully validate address-only tags (MVR names can't be parsed as type tags)
|
|
298
|
+
if (!HAS_PHANTOM_REGEX.test(result) && !/[@/]/.test(result)) {
|
|
299
|
+
TypeTagSerializer.parseFromStr(result);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
return result;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
async function resolveBuiltTypeTag(
|
|
306
|
+
name: string,
|
|
307
|
+
options: { client: ClientWithCoreApi } & TypeTagOptions,
|
|
308
|
+
): Promise<string> {
|
|
309
|
+
const { client, ...rest } = options;
|
|
310
|
+
const { type } = await client.core.mvr.resolveType({
|
|
311
|
+
type: buildTypeTag(name, rest),
|
|
312
|
+
});
|
|
313
|
+
return normalizeStructTag(type);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
export class MoveStruct<
|
|
317
|
+
T extends Record<string, BcsType<any>>,
|
|
318
|
+
const Name extends string = string,
|
|
319
|
+
> extends BcsStruct<T, Name> {
|
|
320
|
+
/**
|
|
321
|
+
* Build the type tag for this struct.
|
|
322
|
+
*
|
|
323
|
+
* `typeArguments` is the full positional list, in Move declaration order, and
|
|
324
|
+
* is required when the struct has unfilled phantom parameters. The result may
|
|
325
|
+
* contain MVR names: those are valid in transaction `typeArguments`, but for
|
|
326
|
+
* queries or comparisons against on-chain data use `resolveTypeTag` instead.
|
|
327
|
+
*/
|
|
328
|
+
typeTag(...args: TypeTagParams<Name>): string {
|
|
329
|
+
return buildTypeTag(this.name, args[0] as TypeTagOptions | undefined);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Build the type tag for this struct, then resolve any MVR names through the
|
|
334
|
+
* client (using its configured overrides and the MVR API) and return the
|
|
335
|
+
* normalized, address-only form suitable for queries and comparisons against
|
|
336
|
+
* on-chain data.
|
|
337
|
+
*/
|
|
338
|
+
async resolveTypeTag(options: ResolveTypeTagOptions<Name>): Promise<string> {
|
|
339
|
+
return resolveBuiltTypeTag(this.name, options as { client: ClientWithCoreApi } & TypeTagOptions);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
async get<Include extends Omit<SuiClientTypes.ObjectInclude, 'content' | 'json'> = {}>({
|
|
343
|
+
objectId,
|
|
344
|
+
...options
|
|
345
|
+
}: GetOptions<Include>): Promise<
|
|
346
|
+
SuiClientTypes.Object<Include & { content: true, json: true }> & { json: BcsStruct<T>['$inferType'] }
|
|
347
|
+
> {
|
|
348
|
+
const [res] = await this.getMany<Include>({
|
|
349
|
+
...options,
|
|
350
|
+
objectIds: [objectId],
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
if (!res) {
|
|
354
|
+
throw new Error(`No object found for id ${objectId}`);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
return res;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
async getMany<Include extends Omit<SuiClientTypes.ObjectInclude, 'content' | 'json'> = {}>({
|
|
361
|
+
client,
|
|
362
|
+
...options
|
|
363
|
+
}: GetManyOptions<Include>): Promise<
|
|
364
|
+
Array<SuiClientTypes.Object<Include & { content: true, json: true }> & { json: BcsStruct<T>['$inferType'] }>
|
|
365
|
+
> {
|
|
366
|
+
const response = (await client.core.getObjects({
|
|
367
|
+
...options,
|
|
368
|
+
include: {
|
|
369
|
+
...options.include,
|
|
370
|
+
content: true,
|
|
371
|
+
},
|
|
372
|
+
})) as SuiClientTypes.GetObjectsResponse<Include & { content: true }>;
|
|
373
|
+
|
|
374
|
+
return response.objects.map((obj) => {
|
|
375
|
+
if (obj instanceof Error) {
|
|
376
|
+
throw obj;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
return {
|
|
380
|
+
...obj,
|
|
381
|
+
json: this.parse(obj.content),
|
|
382
|
+
};
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
export class MoveEnum<
|
|
388
|
+
T extends Record<string, BcsType<any> | null>,
|
|
389
|
+
const Name extends string,
|
|
390
|
+
> extends BcsEnum<T, Name> {
|
|
391
|
+
/** Build the type tag for this enum. See `MoveStruct.typeTag` for semantics. */
|
|
392
|
+
typeTag(...args: TypeTagParams<Name>): string {
|
|
393
|
+
return buildTypeTag(this.name, args[0] as TypeTagOptions | undefined);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/** Build and resolve the type tag for this enum. See `MoveStruct.resolveTypeTag`. */
|
|
397
|
+
async resolveTypeTag(options: ResolveTypeTagOptions<Name>): Promise<string> {
|
|
398
|
+
return resolveBuiltTypeTag(this.name, options as { client: ClientWithCoreApi } & TypeTagOptions);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
export class MoveTuple<
|
|
403
|
+
const T extends readonly BcsType<any>[],
|
|
404
|
+
const Name extends string,
|
|
405
|
+
> extends BcsTuple<T, Name> {
|
|
406
|
+
/** Build the type tag for this struct. See `MoveStruct.typeTag` for semantics. */
|
|
407
|
+
typeTag(...args: TypeTagParams<Name>): string {
|
|
408
|
+
return buildTypeTag(this.name, args[0] as TypeTagOptions | undefined);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/** Build and resolve the type tag for this struct. See `MoveStruct.resolveTypeTag`. */
|
|
412
|
+
async resolveTypeTag(options: ResolveTypeTagOptions<Name>): Promise<string> {
|
|
413
|
+
return resolveBuiltTypeTag(this.name, options as { client: ClientWithCoreApi } & TypeTagOptions);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
function stringify(val: unknown) {
|
|
418
|
+
if (typeof val === 'object') {
|
|
419
|
+
return JSON.stringify(val, (_key, value) =>
|
|
420
|
+
typeof value === 'bigint' ? value.toString() : value,
|
|
421
|
+
);
|
|
422
|
+
}
|
|
423
|
+
if (typeof val === 'bigint') {
|
|
424
|
+
return val.toString();
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
return val;
|
|
428
|
+
}
|
package/src/contracts.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// Copyright (c) Miso Labs, Inc.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
// Barrel for the codegen-generated, ABI-bound bindings (BCS structs + type-safe
|
|
5
|
+
// Move calls). Re-exported from the package root as the `contracts` namespace.
|
|
6
|
+
//
|
|
7
|
+
// The generated default `@local-pkg/partyos` identity is a source label only:
|
|
8
|
+
// callers must inject the exact published address through `PartyDeployment`
|
|
9
|
+
// before building a transaction.
|
|
10
|
+
|
|
11
|
+
import * as rawParty from "./contracts/partyos/party.ts";
|
|
12
|
+
|
|
13
|
+
type PublicModule<M extends object, K extends readonly (keyof M)[]> = Omit<M, K[number]>;
|
|
14
|
+
function withoutUnsafeCalls<M extends object, K extends readonly (keyof M)[]>(
|
|
15
|
+
module: M,
|
|
16
|
+
keys: K,
|
|
17
|
+
): PublicModule<M, K> {
|
|
18
|
+
return Object.fromEntries(
|
|
19
|
+
Object.entries(module).filter(([key]) => !keys.includes(key as keyof M)),
|
|
20
|
+
) as PublicModule<M, K>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Public Move functions that return references. A PTB can borrow internally,
|
|
25
|
+
* but a Move-call command result cannot carry a reference to a later command,
|
|
26
|
+
* so they are kept out of the curated barrel and the client's `call` namespace.
|
|
27
|
+
*/
|
|
28
|
+
export const PARTY_REF_RETURNING_CALLS = ["groupMembers", "uid", "uidMut"] as const;
|
|
29
|
+
|
|
30
|
+
/** Party core (BCS codecs remain available; PTB-inaccessible references do not). */
|
|
31
|
+
export const party = withoutUnsafeCalls(rawParty, PARTY_REF_RETURNING_CALLS);
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// Copyright (c) Miso Labs, Inc.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { normalizeSuiAddress } from "@mysten/sui/utils";
|
|
5
|
+
|
|
6
|
+
/** Sui networks for which this SDK may bundle a verified deployment. */
|
|
7
|
+
export type PartyosNetwork = "mainnet" | "testnet";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The single independently published package required by this SDK surface:
|
|
11
|
+
* the `partyos` object-model package (module `party`).
|
|
12
|
+
*
|
|
13
|
+
* This name is a stable deployment-manifest key, not a Move module name. Its
|
|
14
|
+
* value is never inferred from a source label or a previous publish.
|
|
15
|
+
*/
|
|
16
|
+
const CANONICAL_PARTYOS_PACKAGE_NAMES = ["partyos"] as const;
|
|
17
|
+
|
|
18
|
+
export type PartyosPackageName = (typeof CANONICAL_PARTYOS_PACKAGE_NAMES)[number];
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Exact package address from one compatible publish. Fill this only from the
|
|
22
|
+
* verified immutable publish record.
|
|
23
|
+
*/
|
|
24
|
+
export type PartyDeployment = Readonly<Record<PartyosPackageName, string>>;
|
|
25
|
+
|
|
26
|
+
/** Verified immutable deployments bundled with this SDK release. */
|
|
27
|
+
export const PARTYOS_DEPLOYMENTS = Object.freeze({
|
|
28
|
+
testnet: Object.freeze({
|
|
29
|
+
partyos: "0xc9fc5d918da992b7c6499880fc509635def384d8529948b28f58494daedf8ec8",
|
|
30
|
+
} as const),
|
|
31
|
+
} as const) satisfies Partial<Record<PartyosNetwork, PartyDeployment>>;
|
|
32
|
+
|
|
33
|
+
/** Resolve a verified manifest, failing closed for unbundled networks. */
|
|
34
|
+
export function getPartyDeployment(network: string): PartyDeployment {
|
|
35
|
+
const deployment = (PARTYOS_DEPLOYMENTS as Partial<Record<string, PartyDeployment>>)[network];
|
|
36
|
+
if (!deployment) {
|
|
37
|
+
throw new Error(
|
|
38
|
+
`@misofm/partyos: no verified PartyOS deployment is bundled for network "${network}". ` +
|
|
39
|
+
"Inject the exact post-publish manifest or pass an explicit deployment; historic package IDs are rejected.",
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
return normalizePartyDeployment(deployment);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Validates an explicit manifest before any Move target is constructed. This is
|
|
47
|
+
* useful at configuration boundaries such as environment-file loading.
|
|
48
|
+
*/
|
|
49
|
+
export function assertPartyDeployment(deployment: unknown): asserts deployment is PartyDeployment {
|
|
50
|
+
if (!deployment || typeof deployment !== "object" || Array.isArray(deployment)) {
|
|
51
|
+
throw new Error(
|
|
52
|
+
`@misofm/partyos: deployment must be an object with exactly these package IDs: ${CANONICAL_PARTYOS_PACKAGE_NAMES.join(", ")}.`,
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
const entries = deployment as Record<string, unknown>;
|
|
56
|
+
const keys = Object.keys(entries);
|
|
57
|
+
const unexpected = keys.filter(
|
|
58
|
+
(key) => !CANONICAL_PARTYOS_PACKAGE_NAMES.includes(key as PartyosPackageName),
|
|
59
|
+
);
|
|
60
|
+
if (unexpected.length > 0 || keys.length !== CANONICAL_PARTYOS_PACKAGE_NAMES.length) {
|
|
61
|
+
throw new Error(
|
|
62
|
+
`@misofm/partyos: deployment must contain exactly these package IDs: ${CANONICAL_PARTYOS_PACKAGE_NAMES.join(", ")}.`,
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
for (const name of CANONICAL_PARTYOS_PACKAGE_NAMES) {
|
|
66
|
+
const packageId = entries[name];
|
|
67
|
+
if (typeof packageId !== "string") {
|
|
68
|
+
throw new Error(`@misofm/partyos: deployment is missing package ID for "${name}".`);
|
|
69
|
+
}
|
|
70
|
+
let normalized: string;
|
|
71
|
+
try {
|
|
72
|
+
normalized = normalizeSuiAddress(packageId);
|
|
73
|
+
} catch {
|
|
74
|
+
throw new Error(`@misofm/partyos: deployment package ID for "${name}" is not a valid Sui address.`);
|
|
75
|
+
}
|
|
76
|
+
if (packageId !== normalized) {
|
|
77
|
+
throw new Error(
|
|
78
|
+
`@misofm/partyos: deployment package ID for "${name}" must be normalized (${normalized}).`,
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** Validate and snapshot an untrusted manifest so later caller mutation is inert. */
|
|
85
|
+
export function normalizePartyDeployment(deployment: unknown): PartyDeployment {
|
|
86
|
+
assertPartyDeployment(deployment);
|
|
87
|
+
return Object.freeze(
|
|
88
|
+
Object.fromEntries(CANONICAL_PARTYOS_PACKAGE_NAMES.map((name) => [name, deployment[name]])),
|
|
89
|
+
) as PartyDeployment;
|
|
90
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// Copyright (c) Miso Labs, Inc.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
// `@misofm/partyos` — the PartyOS object model: Party identity, its admin cap,
|
|
5
|
+
// and consent-based group membership. Everything Miso offers on top of a Party
|
|
6
|
+
// (profiles, media, roles, tags, genres, CTAs, platform links, the party
|
|
7
|
+
// wallet) is an extension and ships from `@misofm/platform`.
|
|
8
|
+
export * from "./types.ts";
|
|
9
|
+
export * from "./transactions.ts";
|
|
10
|
+
export * from "./queries.ts";
|
|
11
|
+
export * from "./client.ts";
|
|
12
|
+
export * from "./deployments.ts";
|
|
13
|
+
|
|
14
|
+
// Generated, ABI-bound bindings (BCS structs + type-safe Move calls).
|
|
15
|
+
export * as contracts from "./contracts.ts";
|
package/src/internal.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Copyright (c) Miso Labs, Inc.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
// The single boundary between generated BCS-parse output (snake_case, Move-shaped)
|
|
5
|
+
// and the public camelCase types.
|
|
6
|
+
|
|
7
|
+
import { fromBase64 } from "@mysten/sui/utils";
|
|
8
|
+
import type { Party } from "./types.ts";
|
|
9
|
+
|
|
10
|
+
// deno-lint-ignore no-explicit-any -- generated parse output is loosely typed
|
|
11
|
+
export function mapParty(id: string, d: any): Party {
|
|
12
|
+
const kind = d.kind;
|
|
13
|
+
const createdAtMs = Number(d.created_at_ms);
|
|
14
|
+
// PartyKind is `Individual | Group(VecSet<ID>)`. The enum parses to
|
|
15
|
+
// `{ $kind, Individual? , Group? }`; Group's payload is a VecSet `{ contents }`.
|
|
16
|
+
const groupPayload = kind?.Group ?? (kind?.$kind === "Group" ? kind.value : undefined);
|
|
17
|
+
if (groupPayload !== undefined) {
|
|
18
|
+
const contents = groupPayload?.contents ?? groupPayload ?? [];
|
|
19
|
+
const members = (Array.isArray(contents) ? contents : []).map((m: unknown) =>
|
|
20
|
+
typeof m === "string" ? m : (m as { id?: string })?.id ?? String(m),
|
|
21
|
+
);
|
|
22
|
+
return { id, kind: "group", name: d.name, members, createdAtMs };
|
|
23
|
+
}
|
|
24
|
+
return { id, kind: "individual", name: d.name, createdAtMs };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Normalizes a dynamic-field key's BCS bytes (Uint8Array or base64 string). */
|
|
28
|
+
export function keyBytes(bcs: unknown): Uint8Array {
|
|
29
|
+
return typeof bcs === "string" ? fromBase64(bcs) : (bcs as Uint8Array);
|
|
30
|
+
}
|