@interest-protocol/blast-migrators-sdk 0.1.1 → 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 +12 -0
- package/dist/aborts.d.ts.map +1 -0
- package/dist/aborts.js +21 -0
- package/dist/aborts.js.map +1 -0
- package/dist/client.d.ts +8 -11
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +12 -14
- package/dist/client.js.map +1 -1
- package/dist/events.d.ts +30 -160
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +33 -168
- package/dist/events.js.map +1 -1
- package/dist/index.d.ts +1 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -3
- package/dist/index.js.map +1 -1
- package/dist/reducer.d.ts +20 -132
- package/dist/reducer.d.ts.map +1 -1
- package/dist/reducer.js +28 -361
- package/dist/reducer.js.map +1 -1
- package/dist/state.d.ts +32 -152
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +61 -167
- package/dist/state.js.map +1 -1
- package/dist/transactions.d.ts +204 -259
- package/dist/transactions.d.ts.map +1 -1
- package/dist/transactions.js +347 -449
- package/dist/transactions.js.map +1 -1
- package/package.json +7 -10
- package/src/aborts.ts +24 -0
- package/src/client.ts +19 -34
- package/src/events.ts +54 -261
- package/src/index.ts +1 -3
- package/src/reducer.ts +46 -538
- package/src/state.ts +88 -282
- package/src/transactions.ts +569 -838
- package/dist/bluefin-pool.d.ts +0 -57
- package/dist/bluefin-pool.d.ts.map +0 -1
- package/dist/bluefin-pool.js +0 -102
- package/dist/bluefin-pool.js.map +0 -1
- package/dist/cetus-pool.d.ts +0 -44
- package/dist/cetus-pool.d.ts.map +0 -1
- package/dist/cetus-pool.js +0 -57
- package/dist/cetus-pool.js.map +0 -1
- package/src/bluefin-pool.ts +0 -180
- package/src/cetus-pool.ts +0 -107
package/src/state.ts
CHANGED
|
@@ -1,316 +1,122 @@
|
|
|
1
1
|
import {
|
|
2
|
-
moveTypeNameBcs,
|
|
3
|
-
suiBalanceBcs,
|
|
4
|
-
suiIdBcs,
|
|
5
|
-
suiObjectIdBcs,
|
|
6
2
|
suiUidBcs,
|
|
3
|
+
u64Bcs,
|
|
4
|
+
unitKeyBcs,
|
|
7
5
|
} from "@interest-protocol/blast-core/bcs";
|
|
8
|
-
import { normalizePositiveU64 } from "@interest-protocol/blast-core/integers";
|
|
9
|
-
import type { SharedObjectReference } from "@interest-protocol/blast-core/sui";
|
|
10
|
-
import type { FeeSplit } from "@interest-protocol/blast-launchpad-sdk/allocation";
|
|
11
|
-
import {
|
|
12
|
-
bpsBcs,
|
|
13
|
-
feeSplitBcs,
|
|
14
|
-
} from "@interest-protocol/blast-launchpad-sdk/allocation";
|
|
15
6
|
import { bcs } from "@mysten/sui/bcs";
|
|
16
7
|
import type { ClientWithCoreApi } from "@mysten/sui/client";
|
|
17
8
|
import { ObjectError } from "@mysten/sui/client";
|
|
18
|
-
import {
|
|
19
|
-
|
|
20
|
-
normalizeSuiAddress,
|
|
21
|
-
normalizeSuiObjectId,
|
|
22
|
-
parseStructTag,
|
|
23
|
-
} from "@mysten/sui/utils";
|
|
24
|
-
|
|
25
|
-
/** Venues whose adapters the migrators package ships. */
|
|
26
|
-
export const MIGRATOR_VENUES = ["bluefin", "cetus"] as const;
|
|
27
|
-
export type MigratorVenue = (typeof MIGRATOR_VENUES)[number];
|
|
28
|
-
|
|
29
|
-
export type LaunchMigrationRoute = {
|
|
30
|
-
venue: MigratorVenue;
|
|
31
|
-
tickSpacing: number;
|
|
32
|
-
feeRate: bigint;
|
|
33
|
-
};
|
|
9
|
+
import { normalizeStructTag, normalizeSuiObjectId } from "@mysten/sui/utils";
|
|
10
|
+
import type { MigratorsDeployment } from "./transactions.ts";
|
|
34
11
|
|
|
35
12
|
/**
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
13
|
+
* BCS layout of `venue_config::VenueConfig`: its UID only. Venue records are
|
|
14
|
+
* dynamic fields of it, keyed by venue-sealed field-less structs
|
|
15
|
+
* (`PoolTierKey<Meme>()`, `CreationCapKey<Meme>()`) that encode as one zero
|
|
16
|
+
* byte.
|
|
39
17
|
*/
|
|
40
|
-
export
|
|
41
|
-
launch: {
|
|
42
|
-
migrationWitnessType: string;
|
|
43
|
-
poolTickSpacing: number;
|
|
44
|
-
poolFeeRate: bigint;
|
|
45
|
-
},
|
|
46
|
-
migratorsOriginalPackageId: string,
|
|
47
|
-
): LaunchMigrationRoute {
|
|
48
|
-
const tag = parseStructTag(launch.migrationWitnessType);
|
|
49
|
-
if (tag.address !== normalizeSuiAddress(migratorsOriginalPackageId)) {
|
|
50
|
-
throw new TypeError(
|
|
51
|
-
"the launch migrates through another migrators package",
|
|
52
|
-
);
|
|
53
|
-
}
|
|
54
|
-
const venue = tag.module as MigratorVenue;
|
|
55
|
-
if (!MIGRATOR_VENUES.includes(venue) || tag.name !== "Witness") {
|
|
56
|
-
throw new RangeError(
|
|
57
|
-
`unsupported migration route ${tag.module}::${tag.name}`,
|
|
58
|
-
);
|
|
59
|
-
}
|
|
60
|
-
return {
|
|
61
|
-
venue,
|
|
62
|
-
tickSpacing: launch.poolTickSpacing,
|
|
63
|
-
feeRate: launch.poolFeeRate,
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/** BCS layout of `blast_fun_migrators::vault::LpVault<Meme, Quote>`. */
|
|
68
|
-
export const lpVaultBcs = bcs.struct("LpVault", {
|
|
69
|
-
id: suiUidBcs,
|
|
70
|
-
pool_id: suiIdBcs,
|
|
71
|
-
partner_id: bcs.option(suiObjectIdBcs),
|
|
72
|
-
protocol_meme_residual: suiBalanceBcs,
|
|
73
|
-
protocol_quote_residual: suiBalanceBcs,
|
|
74
|
-
unpaid_protocol_meme: suiBalanceBcs,
|
|
75
|
-
unpaid_protocol_quote: suiBalanceBcs,
|
|
76
|
-
fee_split: feeSplitBcs,
|
|
77
|
-
creator_meme: suiBalanceBcs,
|
|
78
|
-
creator_quote: suiBalanceBcs,
|
|
79
|
-
auto_lp_meme: suiBalanceBcs,
|
|
80
|
-
auto_lp_quote: suiBalanceBcs,
|
|
81
|
-
rewards_meme: suiBalanceBcs,
|
|
82
|
-
rewards_quote: suiBalanceBcs,
|
|
83
|
-
burn_quote: suiBalanceBcs,
|
|
84
|
-
next_round: bcs.u64(),
|
|
85
|
-
last_checkpoint: bcs.option(bcs.u64()),
|
|
86
|
-
});
|
|
18
|
+
export const venueConfigBcs = bcs.struct("VenueConfig", { id: suiUidBcs });
|
|
87
19
|
|
|
88
|
-
/**
|
|
89
|
-
export const
|
|
90
|
-
|
|
91
|
-
|
|
20
|
+
/** `bluefin::PoolTier`: the Bluefin pool tier a Meme's migration uses. */
|
|
21
|
+
export const bluefinPoolTierBcs = bcs.struct("PoolTier", {
|
|
22
|
+
tick_spacing: bcs.u32(),
|
|
23
|
+
fee_rate: u64Bcs,
|
|
92
24
|
});
|
|
93
25
|
|
|
94
|
-
/**
|
|
95
|
-
export
|
|
96
|
-
id: suiUidBcs,
|
|
97
|
-
destination: bcs.Address,
|
|
98
|
-
defaults: lpFeeSharePairBcs,
|
|
99
|
-
coins: bcs.struct("Table", { id: suiUidBcs, size: bcs.u64() }),
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
export type LpVaultState = SharedObjectReference<true> & {
|
|
103
|
-
memeType: string;
|
|
104
|
-
quoteType: string;
|
|
105
|
-
poolId: string;
|
|
106
|
-
/** The partner the launch named, paid its cut of Blast's LP fees; null for none. */
|
|
107
|
-
partnerId: string | null;
|
|
108
|
-
/** Protocol-owned migration residuals, claimable by an administrator. */
|
|
109
|
-
protocolMemeResidual: bigint;
|
|
110
|
-
protocolQuoteResidual: bigint;
|
|
111
|
-
/** Blast's LP fees a partnered vault holds until `claimProtocolLpFeesWithPartner`. */
|
|
112
|
-
unpaidProtocolMeme: bigint;
|
|
113
|
-
unpaidProtocolQuote: bigint;
|
|
114
|
-
feeSplit: FeeSplit;
|
|
115
|
-
/** Creator LP fees claimable by the launch's live `CurveFeeCap`. */
|
|
116
|
-
creatorMeme: bigint;
|
|
117
|
-
creatorQuote: bigint;
|
|
118
|
-
/** Auto-LP amounts the pool did not take yet; the next collection retries. */
|
|
119
|
-
autoLpMeme: bigint;
|
|
120
|
-
autoLpQuote: bigint;
|
|
121
|
-
/** Rewards not yet reserved by a holder-reward round. */
|
|
122
|
-
rewardsMeme: bigint;
|
|
123
|
-
rewardsQuote: bigint;
|
|
124
|
-
/** Burn-share Quote waiting for a buyback admin to swap it for Meme to burn. */
|
|
125
|
-
burnQuote: bigint;
|
|
126
|
-
/** Number the next holder-reward round must carry. */
|
|
127
|
-
nextRound: bigint;
|
|
128
|
-
/** Checkpoint the next round must start at; null before the first round. */
|
|
129
|
-
lastCheckpoint: bigint | null;
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
export type LpVaultObject = SharedObjectReference<true> & {
|
|
133
|
-
type: string;
|
|
134
|
-
content: Uint8Array;
|
|
135
|
-
};
|
|
26
|
+
/** A Bluefin pool tier; `feeRate` is in Bluefin fee units (1,000,000 is 100%). */
|
|
27
|
+
export type BluefinPoolTier = { tickSpacing: number; feeRate: bigint };
|
|
136
28
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
protocolDestination: string;
|
|
142
|
-
defaultShares: LpFeeShares;
|
|
143
|
-
/** Table of per-coin share pairs, keyed by original Meme `TypeName`. */
|
|
144
|
-
coinSharesTableId: string;
|
|
145
|
-
coinSharesCount: bigint;
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
export function decodeLpVaultObject(
|
|
149
|
-
object: LpVaultObject,
|
|
150
|
-
originalPackageId: string,
|
|
151
|
-
): LpVaultState {
|
|
152
|
-
const tag = parseStructTag(object.type);
|
|
153
|
-
if (tag.module !== "vault" || tag.name !== "LpVault") {
|
|
154
|
-
throw new TypeError(`object ${object.objectId} is not an LP vault`);
|
|
155
|
-
}
|
|
156
|
-
if (tag.typeParams.length !== 2) {
|
|
157
|
-
throw new TypeError(
|
|
158
|
-
`LP vault ${object.objectId} must have two type arguments`,
|
|
159
|
-
);
|
|
160
|
-
}
|
|
161
|
-
if (tag.address !== normalizeSuiAddress(originalPackageId)) {
|
|
162
|
-
throw new TypeError(
|
|
163
|
-
`LP vault ${object.objectId} has an unexpected package`,
|
|
164
|
-
);
|
|
165
|
-
}
|
|
166
|
-
if (object.mutable !== true) {
|
|
167
|
-
throw new TypeError(`LP vault ${object.objectId} must be mutable`);
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
const parsed = lpVaultBcs.parse(object.content);
|
|
171
|
-
const objectId = normalizeSuiObjectId(object.objectId);
|
|
172
|
-
if (normalizeSuiObjectId(parsed.id.id.bytes) !== objectId) {
|
|
173
|
-
throw new TypeError(`LP vault ${object.objectId} has a mismatched UID`);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
return {
|
|
177
|
-
objectId,
|
|
178
|
-
initialSharedVersion: normalizePositiveU64(
|
|
179
|
-
"initialSharedVersion",
|
|
180
|
-
object.initialSharedVersion,
|
|
181
|
-
),
|
|
182
|
-
mutable: true,
|
|
183
|
-
memeType: normalizeTypeParameter(tag.typeParams[0]),
|
|
184
|
-
quoteType: normalizeTypeParameter(tag.typeParams[1]),
|
|
185
|
-
poolId: normalizeSuiObjectId(parsed.pool_id.bytes),
|
|
186
|
-
partnerId: parsed.partner_id,
|
|
187
|
-
protocolMemeResidual: BigInt(parsed.protocol_meme_residual.value),
|
|
188
|
-
protocolQuoteResidual: BigInt(parsed.protocol_quote_residual.value),
|
|
189
|
-
unpaidProtocolMeme: BigInt(parsed.unpaid_protocol_meme.value),
|
|
190
|
-
unpaidProtocolQuote: BigInt(parsed.unpaid_protocol_quote.value),
|
|
191
|
-
feeSplit: parsed.fee_split,
|
|
192
|
-
creatorMeme: BigInt(parsed.creator_meme.value),
|
|
193
|
-
creatorQuote: BigInt(parsed.creator_quote.value),
|
|
194
|
-
autoLpMeme: BigInt(parsed.auto_lp_meme.value),
|
|
195
|
-
autoLpQuote: BigInt(parsed.auto_lp_quote.value),
|
|
196
|
-
rewardsMeme: BigInt(parsed.rewards_meme.value),
|
|
197
|
-
rewardsQuote: BigInt(parsed.rewards_quote.value),
|
|
198
|
-
burnQuote: BigInt(parsed.burn_quote.value),
|
|
199
|
-
nextRound: BigInt(parsed.next_round),
|
|
200
|
-
lastCheckpoint:
|
|
201
|
-
parsed.last_checkpoint === null ? null : BigInt(parsed.last_checkpoint),
|
|
202
|
-
};
|
|
203
|
-
}
|
|
29
|
+
type VenueConfigReader = Pick<
|
|
30
|
+
MigratorsDeployment,
|
|
31
|
+
"originalPackageId" | "venueConfig"
|
|
32
|
+
>;
|
|
204
33
|
|
|
205
|
-
|
|
34
|
+
/**
|
|
35
|
+
* The tick spacing `cetus::prepare` recorded for `memeType`
|
|
36
|
+
* (`cetus::PoolTierKey<Meme>`), or null before the Meme is prepared for
|
|
37
|
+
* Cetus. Pass the Meme's original (defining) type address.
|
|
38
|
+
*/
|
|
39
|
+
export async function getCetusPoolTier(
|
|
206
40
|
client: ClientWithCoreApi,
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
): Promise<
|
|
210
|
-
const
|
|
211
|
-
|
|
212
|
-
include: { content: true },
|
|
213
|
-
});
|
|
214
|
-
if (object.owner.$kind !== "Shared") {
|
|
215
|
-
throw new TypeError(`LP vault ${object.objectId} is not a shared object`);
|
|
216
|
-
}
|
|
217
|
-
return decodeLpVaultObject(
|
|
218
|
-
{
|
|
219
|
-
objectId: object.objectId,
|
|
220
|
-
initialSharedVersion: object.owner.Shared.initialSharedVersion,
|
|
221
|
-
mutable: true,
|
|
222
|
-
type: object.type,
|
|
223
|
-
content: object.content,
|
|
224
|
-
},
|
|
225
|
-
originalPackageId,
|
|
226
|
-
);
|
|
41
|
+
migrators: VenueConfigReader,
|
|
42
|
+
memeType: string,
|
|
43
|
+
): Promise<number | null> {
|
|
44
|
+
const value = await venueField(client, migrators, "cetus", memeType);
|
|
45
|
+
return value === null ? null : bcs.u32().parse(value);
|
|
227
46
|
}
|
|
228
47
|
|
|
229
|
-
/**
|
|
230
|
-
|
|
48
|
+
/**
|
|
49
|
+
* The tier `bluefin::prepare` recorded for `memeType`
|
|
50
|
+
* (`bluefin::PoolTierKey<Meme>`), or null before the Meme is prepared for
|
|
51
|
+
* Bluefin.
|
|
52
|
+
*/
|
|
53
|
+
export async function getBluefinPoolTier(
|
|
231
54
|
client: ClientWithCoreApi,
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
): Promise<
|
|
235
|
-
const
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
}
|
|
239
|
-
if (object.owner.$kind !== "Shared") {
|
|
240
|
-
throw new TypeError(`LP-fee policy ${object.objectId} is not shared`);
|
|
241
|
-
}
|
|
242
|
-
const expected = normalizeStructTag(
|
|
243
|
-
`${normalizeSuiAddress(originalPackageId)}::lp_fee_policy::LpFeePolicy`,
|
|
244
|
-
);
|
|
245
|
-
if (normalizeStructTag(object.type) !== expected) {
|
|
246
|
-
throw new TypeError(`object ${object.objectId} is not the LP-fee policy`);
|
|
247
|
-
}
|
|
248
|
-
const parsed = lpFeePolicyBcs.parse(object.content);
|
|
249
|
-
if (
|
|
250
|
-
normalizeSuiObjectId(parsed.id.id.bytes) !==
|
|
251
|
-
normalizeSuiObjectId(object.objectId)
|
|
252
|
-
) {
|
|
253
|
-
throw new TypeError(
|
|
254
|
-
`LP-fee policy ${object.objectId} has a mismatched UID`,
|
|
255
|
-
);
|
|
256
|
-
}
|
|
257
|
-
return {
|
|
258
|
-
objectId: normalizeSuiObjectId(object.objectId),
|
|
259
|
-
initialSharedVersion: normalizePositiveU64(
|
|
260
|
-
"initialSharedVersion",
|
|
261
|
-
object.owner.Shared.initialSharedVersion,
|
|
262
|
-
),
|
|
263
|
-
mutable: false,
|
|
264
|
-
protocolDestination: normalizeSuiAddress(parsed.destination),
|
|
265
|
-
defaultShares: {
|
|
266
|
-
memeBps: parsed.defaults.meme_bps,
|
|
267
|
-
quoteBps: parsed.defaults.quote_bps,
|
|
268
|
-
},
|
|
269
|
-
coinSharesTableId: normalizeSuiObjectId(parsed.coins.id.id.bytes),
|
|
270
|
-
coinSharesCount: BigInt(parsed.coins.size),
|
|
271
|
-
};
|
|
55
|
+
migrators: VenueConfigReader,
|
|
56
|
+
memeType: string,
|
|
57
|
+
): Promise<BluefinPoolTier | null> {
|
|
58
|
+
const value = await venueField(client, migrators, "bluefin", memeType);
|
|
59
|
+
if (value === null) return null;
|
|
60
|
+
const tier = bluefinPoolTierBcs.parse(value);
|
|
61
|
+
return { tickSpacing: tier.tick_spacing, feeRate: tier.fee_rate };
|
|
272
62
|
}
|
|
273
63
|
|
|
274
64
|
/**
|
|
275
|
-
*
|
|
276
|
-
*
|
|
65
|
+
* The ID of the Meme type's Cetus `PoolCreationCap`, kept in `VenueConfig`
|
|
66
|
+
* under `cetus::CreationCapKey<Meme>` (the `pool_creation_cap_id` of its
|
|
67
|
+
* `CetusPoolReserved`), or null before the Meme is prepared for Cetus.
|
|
277
68
|
*/
|
|
278
|
-
export async function
|
|
69
|
+
export async function getCetusPoolCreationCapId(
|
|
279
70
|
client: ClientWithCoreApi,
|
|
280
|
-
|
|
71
|
+
migrators: VenueConfigReader,
|
|
281
72
|
memeType: string,
|
|
282
|
-
): Promise<
|
|
73
|
+
): Promise<string | null> {
|
|
283
74
|
try {
|
|
284
|
-
const {
|
|
285
|
-
parentId:
|
|
286
|
-
name:
|
|
287
|
-
type: "0x1::type_name::TypeName",
|
|
288
|
-
bcs: moveTypeNameBcs
|
|
289
|
-
.serialize(originalTypeNameText(memeType))
|
|
290
|
-
.toBytes(),
|
|
291
|
-
},
|
|
75
|
+
const { object } = await client.core.getDynamicObjectField({
|
|
76
|
+
parentId: normalizeSuiObjectId(migrators.venueConfig.objectId),
|
|
77
|
+
name: venueKey(migrators, "cetus", "CreationCapKey", memeType),
|
|
292
78
|
});
|
|
293
|
-
|
|
294
|
-
return { memeBps: pair.meme_bps, quoteBps: pair.quote_bps, source: "coin" };
|
|
79
|
+
return normalizeSuiObjectId(object.objectId);
|
|
295
80
|
} catch (error) {
|
|
296
|
-
if (
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
return { ...policy.defaultShares, source: "default" };
|
|
81
|
+
if (error instanceof ObjectError && error.reason === "notFound")
|
|
82
|
+
return null;
|
|
83
|
+
throw error;
|
|
300
84
|
}
|
|
301
85
|
}
|
|
302
86
|
|
|
303
|
-
/**
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
87
|
+
/**
|
|
88
|
+
* The `VenueConfig` dynamic-field name `<original>::<venue>::<key><Meme>()`:
|
|
89
|
+
* the key type with the Meme's original type address, and one zero byte.
|
|
90
|
+
*/
|
|
91
|
+
function venueKey(
|
|
92
|
+
migrators: Pick<MigratorsDeployment, "originalPackageId">,
|
|
93
|
+
venue: "cetus" | "bluefin",
|
|
94
|
+
key: "PoolTierKey" | "CreationCapKey",
|
|
95
|
+
memeType: string,
|
|
96
|
+
): { type: string; bcs: Uint8Array } {
|
|
97
|
+
return {
|
|
98
|
+
type: normalizeStructTag(
|
|
99
|
+
`${normalizeSuiObjectId(migrators.originalPackageId)}::${venue}::${key}<${normalizeStructTag(memeType)}>`,
|
|
100
|
+
),
|
|
101
|
+
bcs: unitKeyBcs.serialize(null).toBytes(),
|
|
102
|
+
};
|
|
307
103
|
}
|
|
308
104
|
|
|
309
|
-
function
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
105
|
+
async function venueField(
|
|
106
|
+
client: ClientWithCoreApi,
|
|
107
|
+
migrators: VenueConfigReader,
|
|
108
|
+
venue: "cetus" | "bluefin",
|
|
109
|
+
memeType: string,
|
|
110
|
+
): Promise<Uint8Array | null> {
|
|
111
|
+
try {
|
|
112
|
+
const { dynamicField } = await client.core.getDynamicField({
|
|
113
|
+
parentId: normalizeSuiObjectId(migrators.venueConfig.objectId),
|
|
114
|
+
name: venueKey(migrators, venue, "PoolTierKey", memeType),
|
|
115
|
+
});
|
|
116
|
+
return dynamicField.value.bcs;
|
|
117
|
+
} catch (error) {
|
|
118
|
+
if (error instanceof ObjectError && error.reason === "notFound")
|
|
119
|
+
return null;
|
|
120
|
+
throw error;
|
|
314
121
|
}
|
|
315
|
-
return normalizeStructTag(type);
|
|
316
122
|
}
|