@misofm/musicos 0.2.0 → 0.3.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/README.md +90 -13
- package/dist/client.d.ts +27 -26
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +58 -51
- package/dist/client.js.map +1 -1
- package/dist/deployments.d.ts +9 -0
- package/dist/deployments.d.ts.map +1 -1
- package/dist/deployments.js +14 -0
- package/dist/deployments.js.map +1 -1
- package/dist/errors.d.ts +10 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +17 -0
- package/dist/errors.js.map +1 -0
- package/dist/events.d.ts +6 -1
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +0 -5
- package/dist/events.js.map +1 -1
- package/dist/execute.d.ts +1 -48
- package/dist/execute.d.ts.map +1 -1
- package/dist/execute.js +5 -106
- package/dist/execute.js.map +1 -1
- package/dist/internal.d.ts +45 -6
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js.map +1 -1
- package/dist/queries.d.ts +38 -62
- package/dist/queries.d.ts.map +1 -1
- package/dist/queries.js +240 -266
- package/dist/queries.js.map +1 -1
- package/dist/transactions.d.ts +2 -1
- package/dist/transactions.d.ts.map +1 -1
- package/dist/transactions.js.map +1 -1
- package/dist/types.d.ts +129 -79
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +169 -1
- package/dist/types.js.map +1 -1
- package/dist/view.d.ts +3 -2
- package/dist/view.d.ts.map +1 -1
- package/dist/view.js +19 -6
- package/dist/view.js.map +1 -1
- package/package.json +8 -1
- package/src/client.ts +78 -98
- package/src/deployments.ts +15 -0
- package/src/errors.ts +30 -0
- package/src/events.ts +1 -1
- package/src/execute.ts +5 -133
- package/src/internal.ts +17 -23
- package/src/queries.ts +386 -424
- package/src/transactions.ts +2 -1
- package/src/types.ts +59 -48
- package/src/view.ts +23 -9
package/dist/view.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../src/view.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../src/view.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGhC,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAExD,OAAO,EAAiB,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAEjE,MAAM,WAAW,2BAA2B;IAC1C,4DAA4D;IAC5D,MAAM,EAAE,MAAM,CAAC;IACf,4CAA4C;IAC5C,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,+DAA+D;IAC/D,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,oDAAoD;IACpD,KAAK,EAAE,aAAa,CAAC;IACrB,wEAAwE;IACxE,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,+GA4ChC,CAAC"}
|
package/dist/view.js
CHANGED
|
@@ -4,8 +4,10 @@
|
|
|
4
4
|
// through the Core `simulateTransaction` API to read a computed value without
|
|
5
5
|
// changing state — used where the value is a pure function of inputs the chain
|
|
6
6
|
// derives (e.g. the deterministic release id).
|
|
7
|
+
import { Effect } from "effect";
|
|
7
8
|
import { Transaction } from "@mysten/sui/transactions";
|
|
8
9
|
import { bcs } from "@mysten/sui/bcs";
|
|
10
|
+
import { SuiClient, SuiRpcError } from "@misofm/effect";
|
|
9
11
|
import * as release from "./contracts/musicos/release.js";
|
|
10
12
|
import { asU256, asU64 } from "./numeric.js";
|
|
11
13
|
/**
|
|
@@ -14,7 +16,7 @@ import { asU256, asU64 } from "./numeric.js";
|
|
|
14
16
|
* Tracks embedded in a release must reference this exact ID, so it is computed
|
|
15
17
|
* up front and threaded into the core release builder.
|
|
16
18
|
*/
|
|
17
|
-
export
|
|
19
|
+
export const deriveTargetReleaseId = Effect.fn("deriveTargetReleaseId")(function* (misoPackageId, params) {
|
|
18
20
|
if (params.recordingIds.length !== params.splitBps.length) {
|
|
19
21
|
throw new Error(`deriveTargetReleaseId: recordingIds (${params.recordingIds.length}) and splitBps (${params.splitBps.length}) length mismatch.`);
|
|
20
22
|
}
|
|
@@ -29,14 +31,25 @@ export async function deriveTargetReleaseId(client, misoPackageId, params) {
|
|
|
29
31
|
asU256("release nonce", params.nonce),
|
|
30
32
|
],
|
|
31
33
|
}));
|
|
34
|
+
const client = yield* SuiClient;
|
|
32
35
|
// gRPC/Core equivalent of devInspect: simulate with per-command return values.
|
|
33
|
-
const res =
|
|
36
|
+
const res = yield* Effect.tryPromise({
|
|
37
|
+
try: (signal) => client.core.simulateTransaction({ transaction: tx, include: { commandResults: true }, signal }),
|
|
38
|
+
catch: (cause) => new SuiRpcError({ operation: "simulateTransaction", cause }),
|
|
39
|
+
});
|
|
34
40
|
if (res.$kind !== "Transaction") {
|
|
35
|
-
|
|
41
|
+
return yield* new SuiRpcError({
|
|
42
|
+
operation: "simulateTransaction",
|
|
43
|
+
cause: new Error(`derive_target_release_id simulation failed: ${JSON.stringify(res.FailedTransaction.status)}`),
|
|
44
|
+
});
|
|
36
45
|
}
|
|
37
46
|
const returned = res.commandResults?.[0]?.returnValues?.[0]?.bcs;
|
|
38
|
-
if (!returned)
|
|
39
|
-
|
|
47
|
+
if (!returned) {
|
|
48
|
+
return yield* new SuiRpcError({
|
|
49
|
+
operation: "simulateTransaction",
|
|
50
|
+
cause: new Error("derive_target_release_id returned no value."),
|
|
51
|
+
});
|
|
52
|
+
}
|
|
40
53
|
return bcs.Address.parse(returned);
|
|
41
|
-
}
|
|
54
|
+
});
|
|
42
55
|
//# sourceMappingURL=view.js.map
|
package/dist/view.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"view.js","sourceRoot":"","sources":["../src/view.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,sCAAsC;AAEtC,kFAAkF;AAClF,8EAA8E;AAC9E,+EAA+E;AAC/E,+CAA+C;AAE/C,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"view.js","sourceRoot":"","sources":["../src/view.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@misofm/musicos",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"packageManager": "bun@1.4.0",
|
|
5
5
|
"description": "Typed bindings, queries, event decoders, and PTB builders for the Miso object model (Composition, Recording, Release, Track) on Sui.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -92,6 +92,10 @@
|
|
|
92
92
|
"types": "./dist/contracts/*.d.ts",
|
|
93
93
|
"default": "./dist/contracts/*.js"
|
|
94
94
|
},
|
|
95
|
+
"./errors": {
|
|
96
|
+
"types": "./dist/errors.d.ts",
|
|
97
|
+
"default": "./dist/errors.js"
|
|
98
|
+
},
|
|
95
99
|
"./package.json": "./package.json"
|
|
96
100
|
},
|
|
97
101
|
"files": [
|
|
@@ -102,17 +106,20 @@
|
|
|
102
106
|
"package.json"
|
|
103
107
|
],
|
|
104
108
|
"dependencies": {
|
|
109
|
+
"@misofm/effect": "0.1.0",
|
|
105
110
|
"@mysten/bcs": "^2.1.1"
|
|
106
111
|
},
|
|
107
112
|
"devDependencies": {
|
|
108
113
|
"@mysten/sui": "2.29.0",
|
|
109
114
|
"@types/bun": "^1.4.0",
|
|
115
|
+
"effect": "4.0.0-rc.112",
|
|
110
116
|
"typedoc": "^0.28.20",
|
|
111
117
|
"typedoc-plugin-markdown": "^4.13.0",
|
|
112
118
|
"typescript": "^7.0.2"
|
|
113
119
|
},
|
|
114
120
|
"peerDependencies": {
|
|
115
121
|
"@mysten/sui": "2.29.0",
|
|
122
|
+
"effect": "4.0.0-rc.112",
|
|
116
123
|
"typescript": "^5.7 || ^6 || ^7"
|
|
117
124
|
},
|
|
118
125
|
"main": "./dist/index.js"
|
package/src/client.ts
CHANGED
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
// Copyright (c) Miso Labs, Inc.
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
+
import type { ConflictingWorkKindError } from "./errors.ts";
|
|
4
5
|
import type {
|
|
5
6
|
ClientWithCoreApi,
|
|
6
7
|
SuiClientRegistration,
|
|
7
8
|
} from "@mysten/sui/client";
|
|
8
9
|
import type { SuiGraphQLClient } from "@mysten/sui/graphql";
|
|
10
|
+
import { Effect } from "effect";
|
|
11
|
+
import {
|
|
12
|
+
GraphQLUnavailableError,
|
|
13
|
+
SuiClient,
|
|
14
|
+
SuiGraphQL,
|
|
15
|
+
type BcsDecodeError,
|
|
16
|
+
type ObjectNotFoundError,
|
|
17
|
+
type SuiRpcError,
|
|
18
|
+
} from "@misofm/effect";
|
|
9
19
|
import {
|
|
10
20
|
getMisoDeployment,
|
|
11
21
|
normalizeMisoDeployment,
|
|
@@ -26,6 +36,7 @@ import type {
|
|
|
26
36
|
RecordingAdminCap,
|
|
27
37
|
Release,
|
|
28
38
|
ReleaseAdminCap,
|
|
39
|
+
ReleaseRegistry,
|
|
29
40
|
} from "./types.ts";
|
|
30
41
|
|
|
31
42
|
// Generated call modules (type-safe Move calls) and BCS structs.
|
|
@@ -66,7 +77,7 @@ function isFullDeployment(
|
|
|
66
77
|
* ```ts
|
|
67
78
|
* const client = new SuiGrpcClient({ network: 'testnet' })
|
|
68
79
|
* .$extend(miso());
|
|
69
|
-
* const composition = await client.miso.getCompositionById('0x...');
|
|
80
|
+
* const composition = await Effect.runPromise(client.miso.getCompositionById('0x...'));
|
|
70
81
|
* ```
|
|
71
82
|
*/
|
|
72
83
|
export function miso<const Name extends string = "miso">(
|
|
@@ -143,92 +154,77 @@ export class MisoProtocolClient {
|
|
|
143
154
|
return this.#deployment.packageId;
|
|
144
155
|
}
|
|
145
156
|
|
|
157
|
+
/** Provides `SuiClient` from this client's `ClientWithCoreApi`, so a method's program has `R = never`. */
|
|
158
|
+
#run<A, E>(effect: Effect.Effect<A, E, SuiClient>): Effect.Effect<A, E> {
|
|
159
|
+
return effect.pipe(Effect.provide(SuiClient.layer(this.#client)));
|
|
160
|
+
}
|
|
161
|
+
|
|
146
162
|
// === Composition ===
|
|
147
163
|
|
|
148
|
-
|
|
149
|
-
return queries.getCompositionById(
|
|
164
|
+
getCompositionById(compositionId: string): Effect.Effect<Composition, ObjectNotFoundError | SuiRpcError | BcsDecodeError> {
|
|
165
|
+
return this.#run(queries.getCompositionById(compositionId));
|
|
150
166
|
}
|
|
151
|
-
|
|
152
|
-
ids
|
|
153
|
-
): Promise<Record<string, Composition>> {
|
|
154
|
-
return queries.getCompositionsByIds(this.#client, ids);
|
|
167
|
+
getCompositionsByIds(ids: string[]): Effect.Effect<Record<string, Composition>, SuiRpcError | BcsDecodeError> {
|
|
168
|
+
return this.#run(queries.getCompositionsByIds(ids));
|
|
155
169
|
}
|
|
156
|
-
|
|
157
|
-
return queries.getWorksByIds(
|
|
170
|
+
getWorksByIds(ids: queries.WorkIds): Effect.Effect<queries.WorksById, ConflictingWorkKindError | SuiRpcError | BcsDecodeError> {
|
|
171
|
+
return this.#run(queries.getWorksByIds(ids));
|
|
158
172
|
}
|
|
159
|
-
|
|
173
|
+
getWorkAddressesByShareTypes(
|
|
160
174
|
shareTypes: queries.WorkShareTypes,
|
|
161
|
-
):
|
|
162
|
-
return
|
|
163
|
-
|
|
164
|
-
shareTypes,
|
|
165
|
-
this.#
|
|
166
|
-
);
|
|
175
|
+
): Effect.Effect<queries.WorkAddressesByShareType, SuiRpcError | GraphQLUnavailableError> {
|
|
176
|
+
if (!this.#graphqlClient) return Effect.fail(new GraphQLUnavailableError());
|
|
177
|
+
return queries
|
|
178
|
+
.getWorkAddressesByShareTypes(shareTypes, this.#misoPackageId)
|
|
179
|
+
.pipe(Effect.provide(SuiGraphQL.layer(this.#graphqlClient)));
|
|
167
180
|
}
|
|
168
|
-
|
|
169
|
-
return queries.getCompositionShareType(
|
|
181
|
+
getCompositionShareType(compositionId: string): Effect.Effect<string, ObjectNotFoundError | SuiRpcError> {
|
|
182
|
+
return this.#run(queries.getCompositionShareType(compositionId));
|
|
170
183
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
this.#
|
|
184
|
+
getCompositionByShareType(
|
|
185
|
+
shareType: string,
|
|
186
|
+
): Effect.Effect<Composition, ObjectNotFoundError | SuiRpcError | BcsDecodeError | GraphQLUnavailableError> {
|
|
187
|
+
if (!this.#graphqlClient) return Effect.fail(new GraphQLUnavailableError());
|
|
188
|
+
return queries.getCompositionByShareType(shareType, this.#misoPackageId).pipe(
|
|
189
|
+
Effect.provide(SuiGraphQL.layer(this.#graphqlClient)),
|
|
190
|
+
Effect.provide(SuiClient.layer(this.#client)),
|
|
177
191
|
);
|
|
178
192
|
}
|
|
179
|
-
|
|
180
|
-
adminCapId
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
async getOwnedCompositionAdminCaps(
|
|
185
|
-
owner: string,
|
|
186
|
-
): Promise<CompositionAdminCap[]> {
|
|
187
|
-
return queries.getOwnedCompositionAdminCaps(
|
|
188
|
-
this.#client,
|
|
189
|
-
owner,
|
|
190
|
-
this.#misoPackageId,
|
|
191
|
-
);
|
|
193
|
+
getCompositionAdminCapById(adminCapId: string): Effect.Effect<CompositionAdminCap, ObjectNotFoundError | SuiRpcError> {
|
|
194
|
+
return this.#run(queries.getCompositionAdminCapById(adminCapId));
|
|
195
|
+
}
|
|
196
|
+
getOwnedCompositionAdminCaps(owner: string): Effect.Effect<CompositionAdminCap[], SuiRpcError> {
|
|
197
|
+
return this.#run(queries.getOwnedCompositionAdminCaps(owner, this.#misoPackageId));
|
|
192
198
|
}
|
|
193
199
|
deriveCompositionAdminCapId(compositionId: string): string {
|
|
194
|
-
return queries.deriveCompositionAdminCapId(
|
|
195
|
-
compositionId,
|
|
196
|
-
this.#misoPackageId,
|
|
197
|
-
);
|
|
200
|
+
return queries.deriveCompositionAdminCapId(compositionId, this.#misoPackageId);
|
|
198
201
|
}
|
|
199
202
|
|
|
200
203
|
// === Recording ===
|
|
201
204
|
|
|
202
|
-
|
|
203
|
-
return queries.getRecordingById(
|
|
205
|
+
getRecordingById(recordingId: string): Effect.Effect<Recording, ObjectNotFoundError | SuiRpcError | BcsDecodeError> {
|
|
206
|
+
return this.#run(queries.getRecordingById(recordingId));
|
|
204
207
|
}
|
|
205
|
-
|
|
206
|
-
return queries.getRecordingsByIds(
|
|
208
|
+
getRecordingsByIds(ids: string[]): Effect.Effect<Record<string, Recording>, SuiRpcError | BcsDecodeError> {
|
|
209
|
+
return this.#run(queries.getRecordingsByIds(ids));
|
|
207
210
|
}
|
|
208
|
-
|
|
209
|
-
return queries.getRecordingShareType(
|
|
211
|
+
getRecordingShareType(recordingId: string): Effect.Effect<string, ObjectNotFoundError | SuiRpcError> {
|
|
212
|
+
return this.#run(queries.getRecordingShareType(recordingId));
|
|
210
213
|
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
this.#
|
|
214
|
+
getRecordingByShareType(
|
|
215
|
+
shareType: string,
|
|
216
|
+
): Effect.Effect<Recording, ObjectNotFoundError | SuiRpcError | BcsDecodeError | GraphQLUnavailableError> {
|
|
217
|
+
if (!this.#graphqlClient) return Effect.fail(new GraphQLUnavailableError());
|
|
218
|
+
return queries.getRecordingByShareType(shareType, this.#misoPackageId).pipe(
|
|
219
|
+
Effect.provide(SuiGraphQL.layer(this.#graphqlClient)),
|
|
220
|
+
Effect.provide(SuiClient.layer(this.#client)),
|
|
217
221
|
);
|
|
218
222
|
}
|
|
219
|
-
|
|
220
|
-
adminCapId
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
async getOwnedRecordingAdminCaps(
|
|
225
|
-
owner: string,
|
|
226
|
-
): Promise<RecordingAdminCap[]> {
|
|
227
|
-
return queries.getOwnedRecordingAdminCaps(
|
|
228
|
-
this.#client,
|
|
229
|
-
owner,
|
|
230
|
-
this.#misoPackageId,
|
|
231
|
-
);
|
|
223
|
+
getRecordingAdminCapById(adminCapId: string): Effect.Effect<RecordingAdminCap, ObjectNotFoundError | SuiRpcError> {
|
|
224
|
+
return this.#run(queries.getRecordingAdminCapById(adminCapId));
|
|
225
|
+
}
|
|
226
|
+
getOwnedRecordingAdminCaps(owner: string): Effect.Effect<RecordingAdminCap[], SuiRpcError> {
|
|
227
|
+
return this.#run(queries.getOwnedRecordingAdminCaps(owner, this.#misoPackageId));
|
|
232
228
|
}
|
|
233
229
|
deriveRecordingAdminCapId(recordingId: string): string {
|
|
234
230
|
return queries.deriveRecordingAdminCapId(recordingId, this.#misoPackageId);
|
|
@@ -236,54 +232,47 @@ export class MisoProtocolClient {
|
|
|
236
232
|
|
|
237
233
|
// === Release ===
|
|
238
234
|
|
|
239
|
-
|
|
240
|
-
return queries.getReleaseById(
|
|
235
|
+
getReleaseById(releaseId: string): Effect.Effect<Release, ObjectNotFoundError | SuiRpcError | BcsDecodeError> {
|
|
236
|
+
return this.#run(queries.getReleaseById(releaseId));
|
|
241
237
|
}
|
|
242
238
|
/** Read the shared canonical core `miso::release::ReleaseRegistry`. */
|
|
243
|
-
|
|
244
|
-
return queries.getReleaseRegistryById(
|
|
239
|
+
getReleaseRegistryById(registryId: string): Effect.Effect<ReleaseRegistry, ObjectNotFoundError | SuiRpcError | BcsDecodeError> {
|
|
240
|
+
return this.#run(queries.getReleaseRegistryById(registryId));
|
|
245
241
|
}
|
|
246
|
-
|
|
247
|
-
return queries.getReleasesByIds(
|
|
242
|
+
getReleasesByIds(ids: string[]): Effect.Effect<Record<string, Release>, SuiRpcError | BcsDecodeError> {
|
|
243
|
+
return this.#run(queries.getReleasesByIds(ids));
|
|
248
244
|
}
|
|
249
|
-
|
|
250
|
-
return queries.getReleaseAdminCapById(
|
|
245
|
+
getReleaseAdminCapById(adminCapId: string): Effect.Effect<ReleaseAdminCap, ObjectNotFoundError | SuiRpcError> {
|
|
246
|
+
return this.#run(queries.getReleaseAdminCapById(adminCapId));
|
|
251
247
|
}
|
|
252
248
|
deriveReleaseAdminCapId(releaseId: string): string {
|
|
253
249
|
return queries.deriveReleaseAdminCapId(releaseId, this.#misoPackageId);
|
|
254
250
|
}
|
|
255
|
-
|
|
256
|
-
return queries.getOwnedReleaseAdminCaps(
|
|
257
|
-
this.#client,
|
|
258
|
-
owner,
|
|
259
|
-
this.#misoPackageId,
|
|
260
|
-
);
|
|
251
|
+
getOwnedReleaseAdminCaps(owner: string): Effect.Effect<ReleaseAdminCap[], SuiRpcError> {
|
|
252
|
+
return this.#run(queries.getOwnedReleaseAdminCaps(owner, this.#misoPackageId));
|
|
261
253
|
}
|
|
254
|
+
|
|
262
255
|
// === Share Currency ===
|
|
263
256
|
|
|
264
|
-
|
|
265
|
-
return queries.getShareCurrencyType(
|
|
257
|
+
getShareCurrencyType(shareCurrencyId: string): Effect.Effect<string, ObjectNotFoundError | SuiRpcError> {
|
|
258
|
+
return this.#run(queries.getShareCurrencyType(shareCurrencyId));
|
|
266
259
|
}
|
|
267
260
|
/**
|
|
268
261
|
* The `TreasuryCap<shareType>` owned by `owner`. Takes the share TYPE — if you
|
|
269
262
|
* hold only the `Currency` object id, resolve it first with
|
|
270
263
|
* {@link getShareCurrencyType}.
|
|
271
264
|
*/
|
|
272
|
-
|
|
273
|
-
shareType
|
|
274
|
-
owner: string,
|
|
275
|
-
): Promise<string> {
|
|
276
|
-
return queries.getShareCurrencyTreasuryCap(this.#client, shareType, owner);
|
|
265
|
+
getShareCurrencyTreasuryCap(shareType: string, owner: string): Effect.Effect<string, SuiRpcError> {
|
|
266
|
+
return this.#run(queries.getShareCurrencyTreasuryCap(shareType, owner));
|
|
277
267
|
}
|
|
278
268
|
|
|
279
269
|
// === Simulate-based reads (view) ===
|
|
280
270
|
|
|
281
271
|
get view() {
|
|
282
|
-
const client = this.#client;
|
|
283
272
|
const misoPackageId = this.#misoPackageId;
|
|
284
273
|
return {
|
|
285
274
|
deriveTargetReleaseId: (params: view.DeriveTargetReleaseIdParams) =>
|
|
286
|
-
view.deriveTargetReleaseId(
|
|
275
|
+
this.#run(view.deriveTargetReleaseId(misoPackageId, params)),
|
|
287
276
|
};
|
|
288
277
|
}
|
|
289
278
|
|
|
@@ -326,15 +315,6 @@ export class MisoProtocolClient {
|
|
|
326
315
|
events: eventParsers,
|
|
327
316
|
};
|
|
328
317
|
}
|
|
329
|
-
|
|
330
|
-
#requireGraphQL(): SuiGraphQLClient {
|
|
331
|
-
if (!this.#graphqlClient) {
|
|
332
|
-
throw new Error(
|
|
333
|
-
"GraphQL client required. Pass graphqlClient to miso() options.",
|
|
334
|
-
);
|
|
335
|
-
}
|
|
336
|
-
return this.#graphqlClient;
|
|
337
|
-
}
|
|
338
318
|
}
|
|
339
319
|
|
|
340
320
|
/** @deprecated Prefer the layer-specific `MisoProtocolClient` name. */
|
package/src/deployments.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
// Copyright (c) Miso Labs, Inc.
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
+
import { Effect } from "effect";
|
|
4
5
|
import { normalizeSuiAddress } from "@mysten/sui/utils";
|
|
6
|
+
import { DeploymentError } from "@misofm/effect/errors";
|
|
5
7
|
|
|
6
8
|
/** Sui networks for which this SDK may bundle a verified deployment. */
|
|
7
9
|
export type MisoNetwork = "mainnet" | "testnet";
|
|
@@ -164,3 +166,16 @@ export function normalizeMisoDeployment(deployment: unknown): MisoDeployment {
|
|
|
164
166
|
Object.fromEntries(CANONICAL_MISO_PACKAGE_NAMES.map((name) => [name, deployment[name]])),
|
|
165
167
|
) as MisoDeployment;
|
|
166
168
|
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Effect-returning form of {@link assertMisoDeployment} + {@link normalizeMisoDeployment}, for
|
|
172
|
+
* configuration boundaries that are already composing `Effect` programs (e.g. loading a
|
|
173
|
+
* deployment manifest from a config service). Synchronous and pure — validation is not I/O — so
|
|
174
|
+
* both this and the throwing form are fine; use whichever fits the call site.
|
|
175
|
+
*/
|
|
176
|
+
export function validateMisoDeployment(deployment: unknown): Effect.Effect<MisoDeployment, DeploymentError> {
|
|
177
|
+
return Effect.try({
|
|
178
|
+
try: () => normalizeMisoDeployment(deployment),
|
|
179
|
+
catch: (cause) => new DeploymentError({ message: cause instanceof Error ? cause.message : String(cause) }),
|
|
180
|
+
});
|
|
181
|
+
}
|
package/src/errors.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Copyright (c) Miso Labs, Inc.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
// `@misofm/musicos` has no failure modes of its own beyond the shared Sui
|
|
5
|
+
// read/write vocabulary — every query is a Core object read, a GraphQL type
|
|
6
|
+
// discovery, or a BCS decode, and every one of those is already covered by
|
|
7
|
+
// `@misofm/effect`'s tagged errors. Re-exported here so callers can import the
|
|
8
|
+
// complete error vocabulary from one place (`@misofm/musicos/errors`) without
|
|
9
|
+
// also depending on `@misofm/effect` directly.
|
|
10
|
+
import { Schema } from "effect";
|
|
11
|
+
|
|
12
|
+
export {
|
|
13
|
+
ObjectNotFoundError,
|
|
14
|
+
ObjectTypeMismatchError,
|
|
15
|
+
SuiRpcError,
|
|
16
|
+
BcsDecodeError,
|
|
17
|
+
TransactionFailedError,
|
|
18
|
+
GraphQLUnavailableError,
|
|
19
|
+
DeploymentError,
|
|
20
|
+
type SuiReadError,
|
|
21
|
+
} from "@misofm/effect/errors";
|
|
22
|
+
|
|
23
|
+
/** One object id was requested under two different work kinds in a single batched read. */
|
|
24
|
+
export class ConflictingWorkKindError extends Schema.TaggedError<ConflictingWorkKindError>()(
|
|
25
|
+
"ConflictingWorkKindError",
|
|
26
|
+
{
|
|
27
|
+
objectId: Schema.String,
|
|
28
|
+
kinds: Schema.Array(Schema.String),
|
|
29
|
+
},
|
|
30
|
+
) {}
|
package/src/events.ts
CHANGED
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
* and nested layouts exactly, which is the safe indexer boundary.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
import type { BcsParser } from "@misofm/effect";
|
|
10
11
|
import * as release from "./contracts/musicos/release.ts";
|
|
11
|
-
import type { BcsParser } from "./queries.ts";
|
|
12
12
|
|
|
13
13
|
/** Decode raw event BCS with the corresponding generated codec. */
|
|
14
14
|
export function decodeEvent<T>(codec: BcsParser<T>, bytes: Uint8Array): T {
|
package/src/execute.ts
CHANGED
|
@@ -2,136 +2,8 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
// Transaction execution + effect extraction (the Signer-parameter pattern).
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
|
|
10
|
-
// changes, and net gas for downstream extraction. Everything here is
|
|
11
|
-
// transport-agnostic — it takes any `ClientWithCoreApi`, so gRPC / JSON-RPC /
|
|
12
|
-
// GraphQL clients all work.
|
|
13
|
-
//
|
|
14
|
-
|
|
15
|
-
import { Transaction } from "@mysten/sui/transactions";
|
|
16
|
-
import type { ClientWithCoreApi, SuiClientTypes } from "@mysten/sui/client";
|
|
17
|
-
import type { Signer } from "@mysten/sui/cryptography";
|
|
18
|
-
import type { TxThunk } from "./transactions.ts";
|
|
19
|
-
|
|
20
|
-
/** The effect fields every submit path requests, so extraction is uniform. */
|
|
21
|
-
export const FULL_INCLUDE = { effects: true, objectTypes: true, balanceChanges: true } as const;
|
|
22
|
-
type FullInclude = typeof FULL_INCLUDE;
|
|
23
|
-
|
|
24
|
-
export interface ExecResult {
|
|
25
|
-
digest: string;
|
|
26
|
-
/** Objects created/mutated/deleted by the transaction. */
|
|
27
|
-
changedObjects: SuiClientTypes.ChangedObject[];
|
|
28
|
-
/** Map of changed objectId → fully-qualified type. */
|
|
29
|
-
objectTypes: Record<string, string>;
|
|
30
|
-
/** Net coin balance deltas by address. */
|
|
31
|
-
balanceChanges: SuiClientTypes.BalanceChange[];
|
|
32
|
-
/** Net gas cost in MIST (computation + storage − rebate). */
|
|
33
|
-
gasUsed: number;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/** Builds a fresh Transaction from one or more thunks (awaiting async ones). */
|
|
37
|
-
export async function buildTx(...thunks: TxThunk[]): Promise<Transaction> {
|
|
38
|
-
const tx = new Transaction();
|
|
39
|
-
for (const thunk of thunks) await thunk(tx);
|
|
40
|
-
return tx;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/** Normalizes the `{ $kind }` transaction-result envelope into an {@link ExecResult}. */
|
|
44
|
-
export function toExecResult(res: SuiClientTypes.TransactionResult<FullInclude>): ExecResult {
|
|
45
|
-
if (res.$kind !== "Transaction") {
|
|
46
|
-
const failed = res.FailedTransaction;
|
|
47
|
-
const status = failed.effects?.status;
|
|
48
|
-
const err = status && !status.success ? JSON.stringify(status.error) : "unknown error";
|
|
49
|
-
throw new Error(`Transaction failed: ${err} (digest ${failed.digest})`);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const t = res.Transaction;
|
|
53
|
-
const effects = t.effects as SuiClientTypes.TransactionEffects;
|
|
54
|
-
if (!effects.status.success) {
|
|
55
|
-
throw new Error(`Transaction reverted: ${JSON.stringify(effects.status.error)} (digest ${t.digest})`);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return {
|
|
59
|
-
digest: t.digest,
|
|
60
|
-
changedObjects: effects.changedObjects,
|
|
61
|
-
objectTypes: (t.objectTypes as Record<string, string>) ?? {},
|
|
62
|
-
balanceChanges: (t.balanceChanges as SuiClientTypes.BalanceChange[]) ?? [],
|
|
63
|
-
gasUsed: netGas(effects.gasUsed),
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/** Signs, executes, and waits for a transaction; returns changes, types, gas. */
|
|
68
|
-
export async function signAndExecute(client: ClientWithCoreApi, signer: Signer, tx: Transaction): Promise<ExecResult> {
|
|
69
|
-
const res = await client.core.signAndExecuteTransaction({ transaction: tx, signer, include: FULL_INCLUDE });
|
|
70
|
-
const result = toExecResult(res);
|
|
71
|
-
await client.core.waitForTransaction({ digest: result.digest });
|
|
72
|
-
return result;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/** Convenience: build from thunks, then sign+execute in one call. */
|
|
76
|
-
export async function execThunks(client: ClientWithCoreApi, signer: Signer, ...thunks: TxThunk[]): Promise<ExecResult> {
|
|
77
|
-
return signAndExecute(client, signer, await buildTx(...thunks));
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// ── Object-change extractors ────────────────────────────────────────────────
|
|
81
|
-
|
|
82
|
-
/** The package id from the (single) newly-published package. */
|
|
83
|
-
export function publishedPackageId(r: ExecResult): string {
|
|
84
|
-
const pkg = r.changedObjects.find((c) => c.idOperation === "Created" && c.outputState === "PackageWrite");
|
|
85
|
-
if (!pkg) throw new Error("No published package found in object changes.");
|
|
86
|
-
return pkg.objectId;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/** All package ids newly published by the transaction (up to 5 per PTB). */
|
|
90
|
-
export function allPublishedPackageIds(r: ExecResult): string[] {
|
|
91
|
-
return r.changedObjects
|
|
92
|
-
.filter((c) => c.idOperation === "Created" && c.outputState === "PackageWrite")
|
|
93
|
-
.map((c) => c.objectId);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/** The first newly-created object whose type contains `substr`. */
|
|
97
|
-
export function createdByType(r: ExecResult, substr: string): string {
|
|
98
|
-
const id = maybeCreatedByType(r, substr);
|
|
99
|
-
if (!id) throw new Error(`No created object with type containing "${substr}" found in object changes.`);
|
|
100
|
-
return id;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/** Like {@link createdByType} but returns undefined instead of throwing. */
|
|
104
|
-
export function maybeCreatedByType(r: ExecResult, substr: string): string | undefined {
|
|
105
|
-
for (const c of r.changedObjects) {
|
|
106
|
-
if (c.idOperation === "Created" && (r.objectTypes[c.objectId] ?? "").includes(substr)) return c.objectId;
|
|
107
|
-
}
|
|
108
|
-
return undefined;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/** The first newly-created object whose type is EXACTLY `type` (for non-generic types). */
|
|
112
|
-
export function createdByExactType(r: ExecResult, type: string): string {
|
|
113
|
-
for (const c of r.changedObjects) {
|
|
114
|
-
if (c.idOperation === "Created" && r.objectTypes[c.objectId] === type) return c.objectId;
|
|
115
|
-
}
|
|
116
|
-
throw new Error(`No created object of exact type "${type}" found in object changes.`);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/** All newly-created objects whose type contains `substr`. */
|
|
120
|
-
export function allCreatedByType(r: ExecResult, substr: string): { objectId: string; objectType: string }[] {
|
|
121
|
-
const out: { objectId: string; objectType: string }[] = [];
|
|
122
|
-
for (const c of r.changedObjects) {
|
|
123
|
-
const type = r.objectTypes[c.objectId] ?? "";
|
|
124
|
-
if (c.idOperation === "Created" && type.includes(substr)) out.push({ objectId: c.objectId, objectType: type });
|
|
125
|
-
}
|
|
126
|
-
return out;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/** The signed balance delta for `address` in `coinType`, or "0" if absent. */
|
|
130
|
-
export function balanceDelta(r: ExecResult, address: string, coinType: string): string {
|
|
131
|
-
const change = r.balanceChanges.find((b) => b.address === address && b.coinType === coinType);
|
|
132
|
-
return change?.amount ?? "0";
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
function netGas(gasUsed: SuiClientTypes.GasCostSummary): number {
|
|
136
|
-
return Number(gasUsed.computationCost) + Number(gasUsed.storageCost) - Number(gasUsed.storageRebate);
|
|
137
|
-
}
|
|
5
|
+
// This module is a thin re-export of `@misofm/effect/execute` so the
|
|
6
|
+
// `@misofm/musicos/execute` subpath keeps resolving for existing callers —
|
|
7
|
+
// the implementation is transport-agnostic and shared across every `@misofm/*`
|
|
8
|
+
// SDK, so there is exactly one copy of it.
|
|
9
|
+
export * from "@misofm/effect/execute";
|