@misofm/platform 0.25.0 → 0.26.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 +144 -45
- package/dist/auth.d.ts +8 -13
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +78 -59
- package/dist/auth.js.map +1 -1
- package/dist/catalog.d.ts +5 -5
- package/dist/catalog.d.ts.map +1 -1
- package/dist/catalog.js +33 -21
- package/dist/catalog.js.map +1 -1
- package/dist/client.d.ts +17 -30
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +53 -75
- package/dist/client.js.map +1 -1
- package/dist/cover.d.ts +4 -3
- package/dist/cover.d.ts.map +1 -1
- package/dist/cover.js +28 -17
- package/dist/cover.js.map +1 -1
- package/dist/credits.d.ts +12 -10
- package/dist/credits.d.ts.map +1 -1
- package/dist/credits.js +60 -33
- package/dist/credits.js.map +1 -1
- package/dist/deployments.d.ts +21 -13
- package/dist/deployments.d.ts.map +1 -1
- package/dist/deployments.js +84 -37
- package/dist/deployments.js.map +1 -1
- package/dist/errors.d.ts +91 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +111 -0
- package/dist/errors.js.map +1 -0
- package/dist/execute.d.ts +3 -1
- package/dist/execute.d.ts.map +1 -1
- package/dist/execute.js +9 -4
- package/dist/execute.js.map +1 -1
- package/dist/genre.d.ts +25 -41
- package/dist/genre.d.ts.map +1 -1
- package/dist/genre.js +71 -20
- package/dist/genre.js.map +1 -1
- package/dist/party/client.d.ts +16 -13
- package/dist/party/client.d.ts.map +1 -1
- package/dist/party/client.js +33 -22
- package/dist/party/client.js.map +1 -1
- package/dist/party/extensions/links.d.ts +2 -1
- package/dist/party/extensions/links.d.ts.map +1 -1
- package/dist/party/extensions/links.js +2 -1
- package/dist/party/extensions/links.js.map +1 -1
- package/dist/party/queries.d.ts +12 -11
- package/dist/party/queries.d.ts.map +1 -1
- package/dist/party/queries.js +63 -57
- package/dist/party/queries.js.map +1 -1
- package/dist/party/types.d.ts +31 -20
- package/dist/party/types.d.ts.map +1 -1
- package/dist/party/types.js +82 -1
- package/dist/party/types.js.map +1 -1
- package/dist/pressing.d.ts +55 -35
- package/dist/pressing.d.ts.map +1 -1
- package/dist/pressing.js +99 -76
- package/dist/pressing.js.map +1 -1
- package/dist/queries.d.ts +1 -1
- package/dist/queries.d.ts.map +1 -1
- package/dist/queries.js +5 -4
- package/dist/queries.js.map +1 -1
- package/dist/read/artist.d.ts +6 -4
- package/dist/read/artist.d.ts.map +1 -1
- package/dist/read/artist.js +29 -27
- package/dist/read/artist.js.map +1 -1
- package/dist/read/catalog.d.ts +20 -17
- package/dist/read/catalog.d.ts.map +1 -1
- package/dist/read/catalog.js +120 -141
- package/dist/read/catalog.js.map +1 -1
- package/dist/read/client.d.ts +10 -9
- package/dist/read/client.d.ts.map +1 -1
- package/dist/read/client.js.map +1 -1
- package/dist/read/genres.d.ts +5 -3
- package/dist/read/genres.d.ts.map +1 -1
- package/dist/read/genres.js +18 -15
- package/dist/read/genres.js.map +1 -1
- package/dist/read/index.d.ts.map +1 -1
- package/dist/read/index.js +7 -1
- package/dist/read/index.js.map +1 -1
- package/dist/read/receipts.d.ts +15 -6
- package/dist/read/receipts.d.ts.map +1 -1
- package/dist/read/receipts.js +73 -60
- package/dist/read/receipts.js.map +1 -1
- package/dist/read/wallet.d.ts +11 -9
- package/dist/read/wallet.d.ts.map +1 -1
- package/dist/read/wallet.js +117 -132
- package/dist/read/wallet.js.map +1 -1
- package/dist/read/works.d.ts +9 -16
- package/dist/read/works.d.ts.map +1 -1
- package/dist/read/works.js +48 -117
- package/dist/read/works.js.map +1 -1
- package/dist/recording-extensions.d.ts +8 -7
- package/dist/recording-extensions.d.ts.map +1 -1
- package/dist/recording-extensions.js +30 -63
- package/dist/recording-extensions.js.map +1 -1
- package/dist/release-extensions.d.ts +3 -2
- package/dist/release-extensions.d.ts.map +1 -1
- package/dist/release-extensions.js +9 -10
- package/dist/release-extensions.js.map +1 -1
- package/dist/royalty.d.ts +51 -51
- package/dist/royalty.d.ts.map +1 -1
- package/dist/royalty.js +93 -11
- package/dist/royalty.js.map +1 -1
- package/dist/share.d.ts +7 -6
- package/dist/share.d.ts.map +1 -1
- package/dist/share.js +37 -30
- package/dist/share.js.map +1 -1
- package/dist/vault.d.ts +20 -8
- package/dist/vault.d.ts.map +1 -1
- package/dist/vault.js +31 -15
- package/dist/vault.js.map +1 -1
- package/package.json +11 -4
- package/src/auth.ts +89 -70
- package/src/catalog.ts +33 -49
- package/src/client.ts +117 -97
- package/src/cover.ts +17 -26
- package/src/credits.ts +43 -75
- package/src/deployments.ts +103 -69
- package/src/errors.ts +156 -0
- package/src/execute.ts +10 -6
- package/src/genre.ts +38 -23
- package/src/party/client.ts +35 -23
- package/src/party/extensions/links.ts +3 -2
- package/src/party/queries.ts +77 -65
- package/src/party/types.ts +52 -48
- package/src/pressing.ts +158 -161
- package/src/queries.ts +5 -5
- package/src/read/artist.ts +47 -42
- package/src/read/catalog.ts +200 -223
- package/src/read/client.ts +12 -11
- package/src/read/genres.ts +24 -16
- package/src/read/index.ts +7 -1
- package/src/read/receipts.ts +128 -67
- package/src/read/wallet.ts +194 -162
- package/src/read/works.ts +75 -194
- package/src/recording-extensions.ts +38 -92
- package/src/release-extensions.ts +7 -12
- package/src/royalty.ts +117 -20
- package/src/share.ts +44 -29
- package/src/vault.ts +47 -24
package/src/royalty.ts
CHANGED
|
@@ -7,10 +7,10 @@
|
|
|
7
7
|
// royalty pool plugins, routed-stake Actions bound to a VaultAdminCap) live in
|
|
8
8
|
// `./vault.ts` instead; this module does not duplicate those.
|
|
9
9
|
|
|
10
|
-
import type { ClientWithCoreApi } from "@mysten/sui/client";
|
|
11
10
|
import { Transaction, type TransactionArgument, type TransactionObjectArgument } from "@mysten/sui/transactions";
|
|
12
|
-
import { deriveObjectID } from "@mysten/sui/utils";
|
|
13
|
-
import {
|
|
11
|
+
import { deriveObjectID, normalizeStructTag } from "@mysten/sui/utils";
|
|
12
|
+
import { Effect, Schema } from "effect";
|
|
13
|
+
import { decodeBcs, getOptionalObjectContent, type BcsDecodeError, type SuiClient, type SuiRpcError } from "@misofm/effect";
|
|
14
14
|
|
|
15
15
|
import { RoyaltyPool as RoyaltyPoolBcs } from "./contracts/royalty_pool/pool.ts";
|
|
16
16
|
import { Stake as RoyaltyStakeBcs } from "./contracts/royalty_pool/stake.ts";
|
|
@@ -22,34 +22,131 @@ import * as routedStake from "./contracts/routed_stake/routed_stake.ts";
|
|
|
22
22
|
/** Key bytes for Move unit structs (single `0x00` for `dummy_field: bool = false`). */
|
|
23
23
|
const UNIT_STRUCT_KEY_BYTES = new Uint8Array([0x00]);
|
|
24
24
|
|
|
25
|
+
// ============================================================================
|
|
26
|
+
// Domain types
|
|
27
|
+
// ============================================================================
|
|
28
|
+
|
|
29
|
+
/** A stake's active registration against one royalty pool, keyed by currency type. */
|
|
30
|
+
export class RoyaltyStakeRegistration extends Schema.Class<RoyaltyStakeRegistration>(
|
|
31
|
+
"@misofm/platform/RoyaltyStakeRegistration",
|
|
32
|
+
)({
|
|
33
|
+
currencyType: Schema.String,
|
|
34
|
+
poolId: Schema.String,
|
|
35
|
+
/** Reward debt in `shares · index` units (u256, decimal string). */
|
|
36
|
+
debt: Schema.String,
|
|
37
|
+
}) {}
|
|
38
|
+
|
|
39
|
+
/** A bare `royalty_pool::pool::RoyaltyPool<Share, Currency>` object. Phantom type arguments do not affect BCS. */
|
|
40
|
+
export class RoyaltyPool extends Schema.Class<RoyaltyPool>("@misofm/platform/RoyaltyPool")({
|
|
41
|
+
id: Schema.String,
|
|
42
|
+
/** Currency balance held by the pool (u64, decimal string). */
|
|
43
|
+
balance: Schema.String,
|
|
44
|
+
/** Sum of every registered stake's shares (u64, decimal string). */
|
|
45
|
+
stakedShares: Schema.String,
|
|
46
|
+
/** Cumulative reward-per-share index (u256, decimal string). */
|
|
47
|
+
cumulativeRewardPerShare: Schema.String,
|
|
48
|
+
/** Deposit remainder not yet folded into the index (u128, decimal string). */
|
|
49
|
+
carry: Schema.String,
|
|
50
|
+
/** Lifetime sum of every deposited value; analytics only (u128, decimal string). */
|
|
51
|
+
cumulativeDeposits: Schema.String,
|
|
52
|
+
}) {}
|
|
53
|
+
|
|
54
|
+
/** A bare `royalty_pool::stake::Stake<Share>` object. */
|
|
55
|
+
export class RoyaltyStake extends Schema.Class<RoyaltyStake>("@misofm/platform/RoyaltyStake")({
|
|
56
|
+
id: Schema.String,
|
|
57
|
+
/** The staked balance (u64, decimal string). Immutable after creation. */
|
|
58
|
+
balance: Schema.String,
|
|
59
|
+
registrations: Schema.Array(RoyaltyStakeRegistration),
|
|
60
|
+
}) {}
|
|
61
|
+
|
|
62
|
+
/** A bare `routed_stake::routed_stake::RoutedStake<StakeShare, PoolShare>` object. */
|
|
63
|
+
export class RoutedStake extends Schema.Class<RoutedStake>("@misofm/platform/RoutedStake")({
|
|
64
|
+
id: Schema.String,
|
|
65
|
+
/** The wrapped position; `null` between `unstake` and `restake`. */
|
|
66
|
+
stake: Schema.NullOr(RoyaltyStake),
|
|
67
|
+
}) {}
|
|
68
|
+
|
|
25
69
|
// ============================================================================
|
|
26
70
|
// Reads
|
|
27
71
|
// ============================================================================
|
|
28
72
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
client: ClientWithCoreApi,
|
|
32
|
-
poolId: string,
|
|
33
|
-
) {
|
|
34
|
-
return getObjectByBcs(client, poolId, RoyaltyPoolBcs);
|
|
73
|
+
function mapRegistration(currencyType: string, poolId: string, debt: string): typeof RoyaltyStakeRegistration.Encoded {
|
|
74
|
+
return { currencyType: normalizeStructTag(currencyType), poolId, debt };
|
|
35
75
|
}
|
|
36
76
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
)
|
|
42
|
-
|
|
77
|
+
function mapRoyaltyPool(poolId: string, parsed: ReturnType<typeof RoyaltyPoolBcs.parse>): typeof RoyaltyPool.Encoded {
|
|
78
|
+
return {
|
|
79
|
+
id: poolId,
|
|
80
|
+
balance: String(parsed.balance.value),
|
|
81
|
+
stakedShares: String(parsed.staked_shares),
|
|
82
|
+
cumulativeRewardPerShare: String(parsed.cumulative_reward_per_share),
|
|
83
|
+
carry: String(parsed.carry),
|
|
84
|
+
cumulativeDeposits: String(parsed.cumulative_deposits),
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function mapRoyaltyStake(stakeId: string, parsed: ReturnType<typeof RoyaltyStakeBcs.parse>): typeof RoyaltyStake.Encoded {
|
|
89
|
+
return {
|
|
90
|
+
id: stakeId,
|
|
91
|
+
balance: String(parsed.balance.value),
|
|
92
|
+
registrations: parsed.registrations.contents.map((entry) =>
|
|
93
|
+
mapRegistration(entry.key.name, entry.value.pool_id, String(entry.value.debt)),
|
|
94
|
+
),
|
|
95
|
+
};
|
|
43
96
|
}
|
|
44
97
|
|
|
45
|
-
|
|
46
|
-
export async function getRoutedStakeById(
|
|
47
|
-
client: ClientWithCoreApi,
|
|
98
|
+
function mapRoutedStake(
|
|
48
99
|
routedStakeId: string,
|
|
49
|
-
|
|
50
|
-
|
|
100
|
+
parsed: ReturnType<typeof RoutedStakeBcs.parse>,
|
|
101
|
+
): typeof RoutedStake.Encoded {
|
|
102
|
+
return {
|
|
103
|
+
id: routedStakeId,
|
|
104
|
+
stake: parsed.stake ? mapRoyaltyStake(routedStakeId, parsed.stake) : null,
|
|
105
|
+
};
|
|
51
106
|
}
|
|
52
107
|
|
|
108
|
+
/** One royalty pool by object ID, or `null` when no such object exists. */
|
|
109
|
+
export const getRoyaltyPoolById = Effect.fn("getRoyaltyPoolById")(function* (
|
|
110
|
+
poolId: string,
|
|
111
|
+
): Effect.fn.Return<RoyaltyPool | null, BcsDecodeError | SuiRpcError, SuiClient> {
|
|
112
|
+
const found = yield* getOptionalObjectContent(poolId);
|
|
113
|
+
if (found._tag === "None") return null;
|
|
114
|
+
return yield* decodeBcs(
|
|
115
|
+
{ parse: (bytes) => mapRoyaltyPool(poolId, RoyaltyPoolBcs.parse(bytes)) },
|
|
116
|
+
RoyaltyPool,
|
|
117
|
+
found.value.content,
|
|
118
|
+
{ type: "RoyaltyPool", objectId: poolId },
|
|
119
|
+
);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
/** One owned `Stake<Share>` by object ID, or `null` when no such object exists. */
|
|
123
|
+
export const getRoyaltyStakeById = Effect.fn("getRoyaltyStakeById")(function* (
|
|
124
|
+
stakeId: string,
|
|
125
|
+
): Effect.fn.Return<RoyaltyStake | null, BcsDecodeError | SuiRpcError, SuiClient> {
|
|
126
|
+
const found = yield* getOptionalObjectContent(stakeId);
|
|
127
|
+
if (found._tag === "None") return null;
|
|
128
|
+
return yield* decodeBcs(
|
|
129
|
+
{ parse: (bytes) => mapRoyaltyStake(stakeId, RoyaltyStakeBcs.parse(bytes)) },
|
|
130
|
+
RoyaltyStake,
|
|
131
|
+
found.value.content,
|
|
132
|
+
{ type: "RoyaltyStake", objectId: stakeId },
|
|
133
|
+
);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
/** One shared routed stake by object ID, or `null` when no such object exists. */
|
|
137
|
+
export const getRoutedStakeById = Effect.fn("getRoutedStakeById")(function* (
|
|
138
|
+
routedStakeId: string,
|
|
139
|
+
): Effect.fn.Return<RoutedStake | null, BcsDecodeError | SuiRpcError, SuiClient> {
|
|
140
|
+
const found = yield* getOptionalObjectContent(routedStakeId);
|
|
141
|
+
if (found._tag === "None") return null;
|
|
142
|
+
return yield* decodeBcs(
|
|
143
|
+
{ parse: (bytes) => mapRoutedStake(routedStakeId, RoutedStakeBcs.parse(bytes)) },
|
|
144
|
+
RoutedStake,
|
|
145
|
+
found.value.content,
|
|
146
|
+
{ type: "RoutedStake", objectId: routedStakeId },
|
|
147
|
+
);
|
|
148
|
+
});
|
|
149
|
+
|
|
53
150
|
/** Deterministically derive the royalty-pool ID for a parent and type pair. */
|
|
54
151
|
export function deriveRoyaltyPoolId(
|
|
55
152
|
parentId: string,
|
package/src/share.ts
CHANGED
|
@@ -21,10 +21,10 @@
|
|
|
21
21
|
// currency still gets a descriptive, work-specific name.
|
|
22
22
|
|
|
23
23
|
import type { ParallelTransactionExecutor } from "@mysten/sui/transactions";
|
|
24
|
-
import type { ClientWithCoreApi } from "@mysten/sui/client";
|
|
25
24
|
import type { Signer } from "@mysten/sui/cryptography";
|
|
26
25
|
import { fromBase64, fromHex, toBase64 } from "@mysten/sui/utils";
|
|
27
26
|
import { update_constants } from "@mysten/move-bytecode-template";
|
|
27
|
+
import { Effect } from "effect";
|
|
28
28
|
import {
|
|
29
29
|
execThunks,
|
|
30
30
|
publishedPackageId,
|
|
@@ -33,6 +33,7 @@ import {
|
|
|
33
33
|
allCreatedByType,
|
|
34
34
|
type ExecResult,
|
|
35
35
|
} from "@misofm/musicos";
|
|
36
|
+
import { SuiClient, SuiRpcError, type TransactionFailedError } from "@misofm/effect";
|
|
36
37
|
|
|
37
38
|
import { publishShareCurrency, initializeShareCurrency, type PackageBytecode } from "./transactions.ts";
|
|
38
39
|
import { SHARE_TEMPLATE } from "./share-template.ts";
|
|
@@ -107,23 +108,21 @@ export interface CreateShareCurrencyParams {
|
|
|
107
108
|
}
|
|
108
109
|
|
|
109
110
|
/** Publishes an immutable package, then initializes a fresh share currency in a second tx. */
|
|
110
|
-
export
|
|
111
|
-
client: ClientWithCoreApi,
|
|
111
|
+
export const createShareCurrency = Effect.fn("createShareCurrency")(function* (
|
|
112
112
|
signer: Signer,
|
|
113
113
|
params: CreateShareCurrencyParams,
|
|
114
|
-
):
|
|
114
|
+
): Effect.fn.Return<ShareCurrency, TransactionFailedError | SuiRpcError, SuiClient> {
|
|
115
115
|
const signerAddress = signer.toSuiAddress();
|
|
116
116
|
const initializer = params.initializerAddress ?? signerAddress;
|
|
117
117
|
const recipient = params.treasuryCapRecipient ?? signerAddress;
|
|
118
118
|
|
|
119
119
|
// Tx 1: publish the share package with the initializer baked in.
|
|
120
120
|
const patched = patchInitializer(params.template ?? SHARE_TEMPLATE, initializer);
|
|
121
|
-
const publishRes =
|
|
121
|
+
const publishRes = yield* execThunks(signer, publishShareCurrency(patched));
|
|
122
122
|
const packageId = publishedPackageId(publishRes);
|
|
123
123
|
|
|
124
124
|
// Tx 2: initialize → creates the Currency object + transfers the TreasuryCap.
|
|
125
|
-
const initRes =
|
|
126
|
-
client,
|
|
125
|
+
const initRes = yield* execThunks(
|
|
127
126
|
signer,
|
|
128
127
|
initializeShareCurrency({
|
|
129
128
|
shareCurrencyPackageId: packageId,
|
|
@@ -141,7 +140,7 @@ export async function createShareCurrency(
|
|
|
141
140
|
treasuryCapId: createdByType(initRes, TREASURY_CAP_TYPE),
|
|
142
141
|
gasUsed: publishRes.gasUsed + initRes.gasUsed,
|
|
143
142
|
};
|
|
144
|
-
}
|
|
143
|
+
});
|
|
145
144
|
|
|
146
145
|
// ── Batched (parallel) ─────────────────────────────────────────────────────
|
|
147
146
|
|
|
@@ -158,12 +157,12 @@ function chunk<T>(items: T[], size: number): T[][] {
|
|
|
158
157
|
* consumes its UpgradeCap in the same PTB. Returns the published package ids
|
|
159
158
|
* (fungible — order is not meaningful; the caller assigns them to work slots).
|
|
160
159
|
*/
|
|
161
|
-
export
|
|
160
|
+
export const publishShareCurrencies = Effect.fn("publishShareCurrencies")(function* (
|
|
162
161
|
executor: ParallelTransactionExecutor,
|
|
163
162
|
initializerAddress: string,
|
|
164
163
|
count: number,
|
|
165
164
|
template: PackageBytecode = SHARE_TEMPLATE,
|
|
166
|
-
):
|
|
165
|
+
): Effect.fn.Return<{ packageIds: string[]; gasUsed: number }, SuiRpcError> {
|
|
167
166
|
if (count <= 0) return { packageIds: [], gasUsed: 0 };
|
|
168
167
|
|
|
169
168
|
// One patched template, reused for every publish (identical bytecode → distinct packages).
|
|
@@ -174,8 +173,10 @@ export async function publishShareCurrencies(
|
|
|
174
173
|
batchSizes.push(Math.min(PUBLISHES_PER_PTB, remaining));
|
|
175
174
|
}
|
|
176
175
|
|
|
177
|
-
const results =
|
|
178
|
-
batchSizes
|
|
176
|
+
const results = yield* Effect.forEach(
|
|
177
|
+
batchSizes,
|
|
178
|
+
(n) => executeViaExecutor(executor, ...Array.from({ length: n }, () => publishShareCurrency(patched))),
|
|
179
|
+
{ concurrency: "unbounded" },
|
|
179
180
|
);
|
|
180
181
|
|
|
181
182
|
const packageIds = results.flatMap(allPublishedPackageIds);
|
|
@@ -184,7 +185,7 @@ export async function publishShareCurrencies(
|
|
|
184
185
|
throw new Error(`Expected ${count} published share packages, got ${packageIds.length}.`);
|
|
185
186
|
}
|
|
186
187
|
return { packageIds, gasUsed };
|
|
187
|
-
}
|
|
188
|
+
});
|
|
188
189
|
|
|
189
190
|
/** Re-associates one init PTB's created objects back to their packages by share type. */
|
|
190
191
|
function currenciesFromResult(res: ExecResult, batchPkgs: string[]): ShareCurrency[] {
|
|
@@ -211,19 +212,22 @@ function currenciesFromResult(res: ExecResult, batchPkgs: string[]): ShareCurren
|
|
|
211
212
|
* persist that batch immediately. If any batch fails, the succeeded ones are already
|
|
212
213
|
* reported and this throws, so a resume re-initializes only the still-missing packages.
|
|
213
214
|
*/
|
|
214
|
-
export
|
|
215
|
+
export const initializeShareCurrencies = Effect.fn("initializeShareCurrencies")(function* (
|
|
215
216
|
executor: ParallelTransactionExecutor,
|
|
216
217
|
signerAddress: string,
|
|
217
218
|
packageIds: string[],
|
|
218
219
|
metaOf: (packageId: string) => ShareCurrencyMeta,
|
|
219
220
|
onBatch?: (currencies: ShareCurrency[], gasUsed: number) => void | Promise<void>,
|
|
220
|
-
):
|
|
221
|
+
): Effect.fn.Return<{ currencies: ShareCurrency[]; gasUsed: number }, never> {
|
|
221
222
|
if (packageIds.length === 0) return { currencies: [], gasUsed: 0 };
|
|
222
223
|
|
|
223
224
|
const batches = chunk(packageIds, INITS_PER_PTB);
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
225
|
+
// `Effect.either` per batch preserves `Promise.allSettled`'s partial-failure
|
|
226
|
+
// tolerance: one batch's `SuiRpcError` does not cancel the others in flight.
|
|
227
|
+
const outcomes = yield* Effect.forEach(
|
|
228
|
+
batches,
|
|
229
|
+
(batchPkgs) =>
|
|
230
|
+
executeViaExecutor(
|
|
227
231
|
executor,
|
|
228
232
|
...batchPkgs.map((pkg) => {
|
|
229
233
|
const meta = metaOf(pkg);
|
|
@@ -235,22 +239,33 @@ export async function initializeShareCurrencies(
|
|
|
235
239
|
treasuryCapRecipient: signerAddress,
|
|
236
240
|
});
|
|
237
241
|
}),
|
|
238
|
-
)
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
242
|
+
).pipe(
|
|
243
|
+
Effect.map((res) => ({ batchCurrencies: currenciesFromResult(res, batchPkgs), gasUsed: res.gasUsed })),
|
|
244
|
+
// A rejecting callback is this batch's failure, not a defect: a defect
|
|
245
|
+
// would fail the whole forEach and interrupt sibling batches whose
|
|
246
|
+
// transactions are already submitted.
|
|
247
|
+
Effect.tap(({ batchCurrencies, gasUsed }) =>
|
|
248
|
+
onBatch
|
|
249
|
+
? Effect.tryPromise({
|
|
250
|
+
try: () => Promise.resolve(onBatch(batchCurrencies, gasUsed)),
|
|
251
|
+
catch: (cause) => new SuiRpcError({ operation: "onBatch", cause }),
|
|
252
|
+
})
|
|
253
|
+
: Effect.void,
|
|
254
|
+
),
|
|
255
|
+
Effect.result,
|
|
256
|
+
),
|
|
257
|
+
{ concurrency: "unbounded" },
|
|
243
258
|
);
|
|
244
259
|
|
|
245
260
|
const currencies: ShareCurrency[] = [];
|
|
246
261
|
const errors: unknown[] = [];
|
|
247
262
|
let gasUsed = 0;
|
|
248
|
-
for (const
|
|
249
|
-
if (
|
|
250
|
-
currencies.push(...
|
|
251
|
-
gasUsed +=
|
|
263
|
+
for (const outcome of outcomes) {
|
|
264
|
+
if (outcome._tag === "Success") {
|
|
265
|
+
currencies.push(...outcome.success.batchCurrencies);
|
|
266
|
+
gasUsed += outcome.success.gasUsed;
|
|
252
267
|
} else {
|
|
253
|
-
errors.push(
|
|
268
|
+
errors.push(outcome.failure);
|
|
254
269
|
}
|
|
255
270
|
}
|
|
256
271
|
if (errors.length > 0) {
|
|
@@ -258,4 +273,4 @@ export async function initializeShareCurrencies(
|
|
|
258
273
|
throw new Error(`${errors.length}/${batches.length} initialize batch(es) failed: ${msg}`);
|
|
259
274
|
}
|
|
260
275
|
return { currencies, gasUsed };
|
|
261
|
-
}
|
|
276
|
+
});
|
package/src/vault.ts
CHANGED
|
@@ -13,13 +13,22 @@
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
import type { BcsType } from "@mysten/sui/bcs";
|
|
16
|
-
import type { ClientWithCoreApi } from "@mysten/sui/client";
|
|
17
16
|
import type {
|
|
18
17
|
Transaction,
|
|
19
18
|
TransactionArgument,
|
|
20
19
|
TransactionObjectArgument,
|
|
21
20
|
} from "@mysten/sui/transactions";
|
|
22
21
|
import { deriveObjectID, normalizeStructTag } from "@mysten/sui/utils";
|
|
22
|
+
import { Effect, Schema } from "effect";
|
|
23
|
+
import {
|
|
24
|
+
assertObjectType,
|
|
25
|
+
decodeBcs,
|
|
26
|
+
getOptionalObjectContent,
|
|
27
|
+
SuiClient,
|
|
28
|
+
SuiRpcError,
|
|
29
|
+
type BcsDecodeError,
|
|
30
|
+
type ObjectTypeMismatchError,
|
|
31
|
+
} from "@misofm/effect";
|
|
23
32
|
import * as vault from "./contracts/vault/vault.ts";
|
|
24
33
|
import * as releaseRevenueDistributor from "./contracts/release_revenue_distributor/release_revenue_distributor.ts";
|
|
25
34
|
import * as compositionRoyaltyPoolPlugin from "./contracts/composition_royalty_pool_plugin/composition_royalty_pool_plugin.ts";
|
|
@@ -948,27 +957,38 @@ export function parseReleaseTrackRevenueDistributedEvent(content: Uint8Array) {
|
|
|
948
957
|
};
|
|
949
958
|
}
|
|
950
959
|
|
|
951
|
-
/**
|
|
952
|
-
|
|
953
|
-
|
|
960
|
+
/**
|
|
961
|
+
* A caller-held handle to a shared `Vault<Cap>`: the vault's id and this cap's
|
|
962
|
+
* own id. There is no separate `Vault` BCS struct to decode — the vault
|
|
963
|
+
* itself is a UID-only shared object whose state lives entirely in dynamic
|
|
964
|
+
* fields, so `VaultAdminCap` is the addressable domain value for vault
|
|
965
|
+
* custody.
|
|
966
|
+
*/
|
|
967
|
+
export class VaultAdminCap extends Schema.Class<VaultAdminCap>("@misofm/platform/VaultAdminCap")({
|
|
968
|
+
id: Schema.String,
|
|
969
|
+
vaultId: Schema.String,
|
|
970
|
+
}) {}
|
|
971
|
+
|
|
972
|
+
function mapVaultAdminCap(id: string, parsed: ReturnType<typeof vault.VaultAdminCap.parse>): typeof VaultAdminCap.Encoded {
|
|
973
|
+
return { id, vaultId: parsed.vault_id };
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
/** Read and BCS-parse an owner-held VaultAdminCap, or `null` when no such object exists. */
|
|
977
|
+
export const getVaultAdminCap = Effect.fn("getVaultAdminCap")(function* (
|
|
954
978
|
vaultAdminCapId: string,
|
|
955
979
|
expected: { readonly vaultPackageId: string; readonly capType: string },
|
|
956
|
-
) {
|
|
957
|
-
const
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
980
|
+
): Effect.fn.Return<VaultAdminCap | null, ObjectTypeMismatchError | BcsDecodeError | SuiRpcError, SuiClient> {
|
|
981
|
+
const found = yield* getOptionalObjectContent(vaultAdminCapId);
|
|
982
|
+
if (found._tag === "None") return null;
|
|
983
|
+
const expectedType = normalizeStructTag(`${expected.vaultPackageId}::vault::VaultAdminCap<${expected.capType}>`);
|
|
984
|
+
yield* assertObjectType(vaultAdminCapId, normalizeStructTag(found.value.type), expectedType);
|
|
985
|
+
return yield* decodeBcs(
|
|
986
|
+
{ parse: (bytes) => mapVaultAdminCap(vaultAdminCapId, vault.VaultAdminCap.parse(bytes)) },
|
|
987
|
+
VaultAdminCap,
|
|
988
|
+
found.value.content,
|
|
989
|
+
{ type: "VaultAdminCap", objectId: vaultAdminCapId },
|
|
964
990
|
);
|
|
965
|
-
|
|
966
|
-
throw new Error(
|
|
967
|
-
`getVaultAdminCap: expected ${expectedType}, received ${object.type ?? "unknown"}`,
|
|
968
|
-
);
|
|
969
|
-
}
|
|
970
|
-
return parseVaultAdminCap(object.content);
|
|
971
|
-
}
|
|
991
|
+
});
|
|
972
992
|
|
|
973
993
|
/**
|
|
974
994
|
* Build a `vector<Receiving<Coin<Currency>>>` for receive-and-* plugin calls.
|
|
@@ -982,18 +1002,21 @@ export interface ReceivingObjectRef {
|
|
|
982
1002
|
}
|
|
983
1003
|
|
|
984
1004
|
/** Resolve owned coins to the exact references required by a Receiving input. */
|
|
985
|
-
export
|
|
986
|
-
client: ClientWithCoreApi,
|
|
1005
|
+
export const resolveReceivingCoins = Effect.fn("resolveReceivingCoins")(function* (
|
|
987
1006
|
coinIds: readonly string[],
|
|
988
|
-
):
|
|
989
|
-
const
|
|
1007
|
+
): Effect.fn.Return<ReceivingObjectRef[], SuiRpcError, SuiClient> {
|
|
1008
|
+
const client = yield* SuiClient;
|
|
1009
|
+
const { objects } = yield* Effect.tryPromise({
|
|
1010
|
+
try: (signal) => client.core.getObjects({ objectIds: [...coinIds], signal }),
|
|
1011
|
+
catch: (cause) => new SuiRpcError({ operation: "getObjects", cause }),
|
|
1012
|
+
});
|
|
990
1013
|
return objects.map((coin, index) => {
|
|
991
1014
|
if (coin instanceof Error || !coin) {
|
|
992
1015
|
throw new Error(`resolveReceivingCoins: could not resolve ${coinIds[index]}`);
|
|
993
1016
|
}
|
|
994
1017
|
return { objectId: coin.objectId, version: coin.version, digest: coin.digest };
|
|
995
1018
|
});
|
|
996
|
-
}
|
|
1019
|
+
});
|
|
997
1020
|
|
|
998
1021
|
export function receivingCoins(
|
|
999
1022
|
tx: Transaction,
|