@unconfirmed/sui-effect 0.1.0 → 0.1.1
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/AGENTS.md +16 -6
- package/CHANGELOG.md +40 -0
- package/LLMS.md +1609 -1098
- package/README.md +347 -3
- package/dist/domain/bcs.d.ts +44 -0
- package/dist/domain/bcs.d.ts.map +1 -1
- package/dist/domain/bcs.js +57 -0
- package/dist/domain/bcs.js.map +1 -1
- package/dist/domain/errors.d.ts +63 -21
- package/dist/domain/errors.d.ts.map +1 -1
- package/dist/domain/errors.js +35 -7
- package/dist/domain/errors.js.map +1 -1
- package/dist/domain/executed.d.ts +54 -18
- package/dist/domain/executed.d.ts.map +1 -1
- package/dist/domain/journal-entry.d.ts +6 -2
- package/dist/domain/journal-entry.d.ts.map +1 -1
- package/dist/domain/schemas.d.ts +207 -66
- package/dist/domain/schemas.d.ts.map +1 -1
- package/dist/domain/schemas.js +62 -2
- package/dist/domain/schemas.js.map +1 -1
- package/dist/domain/sui-schema.d.ts +3 -2
- package/dist/domain/sui-schema.d.ts.map +1 -1
- package/dist/domain/sui-schema.js +3 -2
- package/dist/domain/sui-schema.js.map +1 -1
- package/dist/extension.d.ts +1 -1
- package/dist/extension.d.ts.map +1 -1
- package/dist/extension.js +1 -1
- package/dist/extension.js.map +1 -1
- package/dist/services/SuiCore.d.ts +12 -0
- package/dist/services/SuiCore.d.ts.map +1 -1
- package/dist/services/SuiCore.js +124 -0
- package/dist/services/SuiCore.js.map +1 -1
- package/dist/services/SuiCoreFake.d.ts +12 -0
- package/dist/services/SuiCoreFake.d.ts.map +1 -1
- package/dist/services/SuiCoreFake.js +6 -1
- package/dist/services/SuiCoreFake.js.map +1 -1
- package/dist/services/SuiExtension.d.ts +127 -14
- package/dist/services/SuiExtension.d.ts.map +1 -1
- package/dist/services/SuiExtension.js +125 -28
- package/dist/services/SuiExtension.js.map +1 -1
- package/dist/services/SuiGraphQL.d.ts +13 -0
- package/dist/services/SuiGraphQL.d.ts.map +1 -1
- package/dist/services/SuiGraphQL.js +13 -0
- package/dist/services/SuiGraphQL.js.map +1 -1
- package/dist/services/Tx.d.ts +3 -1
- package/dist/services/Tx.d.ts.map +1 -1
- package/dist/testing.d.ts +21 -3
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +30 -3
- package/dist/testing.js.map +1 -1
- package/docs/extensions.md +338 -25
- package/examples/extension-template/test/escrow.test.ts +91 -2
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -67,6 +67,341 @@ That is `examples/script-claim.ts`, which a test runs against the in-memory
|
|
|
67
67
|
fake. Every failure it can produce is in the generator's inferred error type and
|
|
68
68
|
has its own exit code, with no handling lines anywhere.
|
|
69
69
|
|
|
70
|
+
## Side by side
|
|
71
|
+
|
|
72
|
+
The same two tasks, once against the canonical `@mysten/sui` 2.30 SDK (a
|
|
73
|
+
gRPC client, the Core API, `Transaction`) and once against sui-effect. Both
|
|
74
|
+
sides are exercised in `test/examples.test.ts`, and this section is asserted
|
|
75
|
+
to be the literal text of the four files it quotes.
|
|
76
|
+
|
|
77
|
+
### Read
|
|
78
|
+
|
|
79
|
+
`examples/compare-read.sdk.ts`:
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
/**
|
|
83
|
+
* Reads one Escrow object and an optional dynamic field on it, written
|
|
84
|
+
* against the canonical 2.30 SDK: a gRPC client, the Core API, manual BCS.
|
|
85
|
+
*
|
|
86
|
+
* Compare with `examples/compare-read.effect.ts`. Both print identical
|
|
87
|
+
* output for the same id.
|
|
88
|
+
*
|
|
89
|
+
* Run with `SUI_NETWORK=testnet ESCROW_ID=0x… bun examples/compare-read.sdk.ts`.
|
|
90
|
+
*/
|
|
91
|
+
import { bcs } from "@mysten/sui/bcs"
|
|
92
|
+
import type { ClientWithCoreApi } from "@mysten/sui/client"
|
|
93
|
+
import { ObjectError } from "@mysten/sui/client"
|
|
94
|
+
import { SuiGrpcClient } from "@mysten/sui/grpc"
|
|
95
|
+
|
|
96
|
+
const PKG = "0x0000000000000000000000000000000000000000000000000000000000000002"
|
|
97
|
+
const ESCROW_TYPE = `${PKG}::escrow::Escrow`
|
|
98
|
+
const EscrowBcs = bcs.struct("Escrow", { id: bcs.Address, amount: bcs.u64() })
|
|
99
|
+
// A note some escrows carry, keyed by the literal index 0. The key is a
|
|
100
|
+
// primitive `u64`, not a struct tag, so nothing here parses it as one.
|
|
101
|
+
const NOTE_NAME = { type: "u64", bcs: bcs.u64().serialize(0).toBytes() }
|
|
102
|
+
|
|
103
|
+
/** Reads the escrow at `id` plus its optional note. */
|
|
104
|
+
export const readEscrow = async (
|
|
105
|
+
client: ClientWithCoreApi,
|
|
106
|
+
id: string
|
|
107
|
+
): Promise<{ id: string; amount: string; note: string | undefined }> => {
|
|
108
|
+
let object
|
|
109
|
+
try {
|
|
110
|
+
;({ object } = await client.core.getObject({ objectId: id, include: { content: true } }))
|
|
111
|
+
} catch (error) {
|
|
112
|
+
// `getObject` throws rather than returning a value that says which of
|
|
113
|
+
// "missing", "deleted" or "unreachable" happened; that three-way split
|
|
114
|
+
// is `ObjectError.reason`, read by hand.
|
|
115
|
+
if (error instanceof ObjectError) {
|
|
116
|
+
if (error.reason === "notFound") throw new Error(`escrow ${id} does not exist`)
|
|
117
|
+
if (error.reason === "deleted") throw new Error(`escrow ${id} was deleted`)
|
|
118
|
+
throw new Error(`escrow ${id}: node could not say what happened to it`, { cause: error })
|
|
119
|
+
}
|
|
120
|
+
throw error
|
|
121
|
+
}
|
|
122
|
+
// No type parameters on this tag, so a plain string comparison is honest;
|
|
123
|
+
// a generic type would need to be parsed and compared piece by piece,
|
|
124
|
+
// which is what sui-effect's bridge does for every caller.
|
|
125
|
+
if (object.type !== ESCROW_TYPE) {
|
|
126
|
+
throw new Error(`${id} is a ${object.type}, not ${ESCROW_TYPE}`)
|
|
127
|
+
}
|
|
128
|
+
const { id: escrowId, amount } = EscrowBcs.parse(object.content)
|
|
129
|
+
|
|
130
|
+
let note: string | undefined
|
|
131
|
+
try {
|
|
132
|
+
const { dynamicField } = await client.core.getDynamicField({ parentId: id, name: NOTE_NAME })
|
|
133
|
+
note = bcs.u64().parse(dynamicField.value.bcs)
|
|
134
|
+
} catch (error) {
|
|
135
|
+
// Absence is normal here; only a reason other than "notFound"/"deleted"
|
|
136
|
+
// is a real problem.
|
|
137
|
+
if (!(error instanceof ObjectError) || error.reason === "unknown") throw error
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return { id: escrowId, amount, note }
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (import.meta.main) {
|
|
144
|
+
const id = process.env.ESCROW_ID
|
|
145
|
+
if (!id) throw new Error("ESCROW_ID is required")
|
|
146
|
+
const client = new SuiGrpcClient({
|
|
147
|
+
network: (process.env.SUI_NETWORK ?? "testnet") as "testnet",
|
|
148
|
+
baseUrl: process.env.SUI_RPC_URL ?? "https://fullnode.testnet.sui.io:443"
|
|
149
|
+
})
|
|
150
|
+
const escrow = await readEscrow(client, id)
|
|
151
|
+
console.log(`${escrow.id} holds ${escrow.amount}, note: ${escrow.note ?? "none"}`)
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
`examples/compare-read.effect.ts`:
|
|
156
|
+
|
|
157
|
+
```ts
|
|
158
|
+
/**
|
|
159
|
+
* Reads one Escrow object and its optional note through sui-effect.
|
|
160
|
+
*
|
|
161
|
+
* Compare with `examples/compare-read.sdk.ts`, which reads the same two
|
|
162
|
+
* things with the canonical SDK client. Both print identical output.
|
|
163
|
+
*
|
|
164
|
+
* Run with `SUI_NETWORK=testnet ESCROW_ID=0x… bun examples/compare-read.effect.ts`.
|
|
165
|
+
* Every failure this program can produce is in the generator's inferred error
|
|
166
|
+
* type: `ObjectNotFound`, `ObjectDeleted`, `ObjectUnavailable` and
|
|
167
|
+
* `DecodeError` (the last one is what a wrong Move type becomes, because
|
|
168
|
+
* `getObject`'s tag check runs before a byte is parsed), plus `TransportError`
|
|
169
|
+
* from both reads and, from the layer, `ConfigError` and `NetworkMismatch`.
|
|
170
|
+
*/
|
|
171
|
+
import { bcs } from "@mysten/sui/bcs"
|
|
172
|
+
import { Config, Console, Effect, Option } from "effect"
|
|
173
|
+
import { ObjectId, Sui, SuiSchema } from "../src/index.ts"
|
|
174
|
+
|
|
175
|
+
const PKG = "0x0000000000000000000000000000000000000000000000000000000000000002"
|
|
176
|
+
|
|
177
|
+
const Escrow = SuiSchema.bcs(
|
|
178
|
+
bcs.struct("Escrow", { id: bcs.Address, amount: bcs.u64() }),
|
|
179
|
+
`${PKG}::escrow::Escrow`
|
|
180
|
+
)
|
|
181
|
+
// The note's value has no struct tag of its own, so its codec carries none;
|
|
182
|
+
// the key is a primitive `u64`, which is why nothing here reaches for
|
|
183
|
+
// `normalizeStructTag` on it.
|
|
184
|
+
const Note = SuiSchema.bcs(bcs.u64())
|
|
185
|
+
const NOTE_NAME = { type: "u64", bcs: bcs.u64().serialize(0).toBytes() }
|
|
186
|
+
|
|
187
|
+
/** The program itself, exported so a test can run it against the fake. */
|
|
188
|
+
export const program = Effect.gen(function*() {
|
|
189
|
+
const sui = yield* Sui
|
|
190
|
+
const id = yield* Config.schema(ObjectId, "ESCROW_ID")
|
|
191
|
+
// No `ObjectError.reason` switch and no manual type comparison: a missing
|
|
192
|
+
// or deleted escrow and a wrong Move type are already three different tags
|
|
193
|
+
// in the type this line returns.
|
|
194
|
+
const escrow = yield* sui.getObject(id, { schema: Escrow })
|
|
195
|
+
const field = yield* sui.getDynamicFieldOption(id, NOTE_NAME)
|
|
196
|
+
const note = yield* Option.match(field, {
|
|
197
|
+
onNone: () => Effect.void,
|
|
198
|
+
onSome: (entry) => SuiSchema.decode(Note, entry.value.bcs)
|
|
199
|
+
})
|
|
200
|
+
yield* Console.log(`${escrow.id} holds ${escrow.content.amount}, note: ${note ?? "none"}`)
|
|
201
|
+
})
|
|
202
|
+
|
|
203
|
+
if (import.meta.main) {
|
|
204
|
+
// Imported here rather than at the top so that a test can import `program`
|
|
205
|
+
// without pulling a platform package into the test process.
|
|
206
|
+
const { BunRuntime } = await import("@effect/platform-bun")
|
|
207
|
+
BunRuntime.runMain(program.pipe(Effect.provide(Sui.layerConfig)))
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Write
|
|
212
|
+
|
|
213
|
+
`examples/compare-write.sdk.ts`:
|
|
214
|
+
|
|
215
|
+
```ts
|
|
216
|
+
/**
|
|
217
|
+
* Claims an escrow through a PTB, written against the canonical 2.30 SDK.
|
|
218
|
+
*
|
|
219
|
+
* Compare with `examples/compare-write.effect.ts`, which does the same thing
|
|
220
|
+
* through `Tx.run` and notes what that adds over this file. Both sign with
|
|
221
|
+
* `SUI_PRIVATE_KEY` and print the created receipt's object id.
|
|
222
|
+
*
|
|
223
|
+
* Run with:
|
|
224
|
+
* SUI_NETWORK=testnet SUI_PRIVATE_KEY=suiprivkey1… ESCROW_ID=0x… bun examples/compare-write.sdk.ts
|
|
225
|
+
*/
|
|
226
|
+
import { bcs } from "@mysten/sui/bcs"
|
|
227
|
+
import type { ClientWithCoreApi } from "@mysten/sui/client"
|
|
228
|
+
import type { Keypair } from "@mysten/sui/cryptography"
|
|
229
|
+
import { decodeSuiPrivateKey } from "@mysten/sui/cryptography"
|
|
230
|
+
import { SuiGrpcClient } from "@mysten/sui/grpc"
|
|
231
|
+
import { Ed25519Keypair } from "@mysten/sui/keypairs/ed25519"
|
|
232
|
+
import { Secp256k1Keypair } from "@mysten/sui/keypairs/secp256k1"
|
|
233
|
+
import { Secp256r1Keypair } from "@mysten/sui/keypairs/secp256r1"
|
|
234
|
+
import { Transaction } from "@mysten/sui/transactions"
|
|
235
|
+
|
|
236
|
+
const PKG = "0x0000000000000000000000000000000000000000000000000000000000000002"
|
|
237
|
+
const RECEIPT_TYPE = `${PKG}::escrow::Receipt`
|
|
238
|
+
const EscrowBcs = bcs.struct("Escrow", { id: bcs.Address, amount: bcs.u64() })
|
|
239
|
+
|
|
240
|
+
// The scheme flag on a Bech32 key names one of three keypair classes;
|
|
241
|
+
// nothing else decodes it, and a fourth scheme has no keypair class at all.
|
|
242
|
+
const KEYPAIR_FOR: Record<string, undefined | ((secretKey: Uint8Array) => Keypair)> = {
|
|
243
|
+
ED25519: Ed25519Keypair.fromSecretKey,
|
|
244
|
+
Secp256k1: Secp256k1Keypair.fromSecretKey,
|
|
245
|
+
Secp256r1: Secp256r1Keypair.fromSecretKey
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Reads the escrow, claims it, and returns the created receipt's object id.
|
|
250
|
+
*
|
|
251
|
+
* Builds, signs and executes as three explicit steps rather than the
|
|
252
|
+
* one-call `signAndExecuteTransaction`, so this can run against an in-memory
|
|
253
|
+
* client with no live network or signer behind it.
|
|
254
|
+
*/
|
|
255
|
+
export const claimEscrow = async (
|
|
256
|
+
client: ClientWithCoreApi,
|
|
257
|
+
escrowId: string,
|
|
258
|
+
keypair: Keypair
|
|
259
|
+
): Promise<string> => {
|
|
260
|
+
const { object } = await client.core.getObject({ objectId: escrowId, include: { content: true } })
|
|
261
|
+
const { amount } = EscrowBcs.parse(object.content)
|
|
262
|
+
|
|
263
|
+
const tx = new Transaction()
|
|
264
|
+
tx.setSenderIfNotSet(keypair.toSuiAddress())
|
|
265
|
+
tx.moveCall({ target: `${PKG}::escrow::claim`, arguments: [tx.object(escrowId), tx.pure.u64(amount)] })
|
|
266
|
+
const bytes = await tx.build({ client })
|
|
267
|
+
const { signature } = await keypair.signTransaction(bytes)
|
|
268
|
+
|
|
269
|
+
const result = await client.core.executeTransaction({
|
|
270
|
+
transaction: bytes,
|
|
271
|
+
signatures: [signature],
|
|
272
|
+
include: { effects: true, objectTypes: true }
|
|
273
|
+
})
|
|
274
|
+
const digest = (result.Transaction ?? result.FailedTransaction).digest
|
|
275
|
+
await client.core.waitForTransaction({ digest })
|
|
276
|
+
|
|
277
|
+
if (result.$kind === "FailedTransaction") {
|
|
278
|
+
const { error } = result.FailedTransaction.status
|
|
279
|
+
if (error?.$kind === "MoveAbort") {
|
|
280
|
+
const { abortCode, cleverError } = error.MoveAbort
|
|
281
|
+
throw new Error(`claim aborted: code ${abortCode}${cleverError?.constantName ? ` (${cleverError.constantName})` : ""}`)
|
|
282
|
+
}
|
|
283
|
+
throw new Error(`claim failed: ${error?.message}`)
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// Effects list every changed object by id; only the `objectTypes` join
|
|
287
|
+
// says which one is the receipt. sui-effect's `expectCreated` is this join,
|
|
288
|
+
// plus a check that exactly one match exists.
|
|
289
|
+
const { changedObjects } = result.Transaction.effects
|
|
290
|
+
const created = changedObjects.find(
|
|
291
|
+
(change) => change.idOperation === "Created" && result.Transaction.objectTypes[change.objectId] === RECEIPT_TYPE
|
|
292
|
+
)
|
|
293
|
+
if (created === undefined) throw new Error(`claim applied (${digest}) but created no ${RECEIPT_TYPE}`)
|
|
294
|
+
return created.objectId
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
if (import.meta.main) {
|
|
298
|
+
const escrowId = process.env.ESCROW_ID
|
|
299
|
+
const key = process.env.SUI_PRIVATE_KEY
|
|
300
|
+
if (!escrowId || !key) throw new Error("ESCROW_ID and SUI_PRIVATE_KEY are required")
|
|
301
|
+
const parsed = decodeSuiPrivateKey(key)
|
|
302
|
+
const fromSecretKey = KEYPAIR_FOR[parsed.scheme]
|
|
303
|
+
if (!fromSecretKey) throw new Error(`${parsed.scheme} has no keypair class here (use a remote signer)`)
|
|
304
|
+
const client = new SuiGrpcClient({
|
|
305
|
+
network: (process.env.SUI_NETWORK ?? "testnet") as "testnet",
|
|
306
|
+
baseUrl: process.env.SUI_RPC_URL ?? "https://fullnode.testnet.sui.io:443"
|
|
307
|
+
})
|
|
308
|
+
console.log(await claimEscrow(client, escrowId, fromSecretKey(parsed.secretKey)))
|
|
309
|
+
}
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
`examples/compare-write.effect.ts`:
|
|
313
|
+
|
|
314
|
+
```ts
|
|
315
|
+
/**
|
|
316
|
+
* Claims an escrow through `Tx.run`, sui-effect's write path.
|
|
317
|
+
*
|
|
318
|
+
* Compare with `examples/compare-write.sdk.ts`, which does the same thing
|
|
319
|
+
* against the canonical SDK client. Both sign with `SUI_PRIVATE_KEY` and
|
|
320
|
+
* print the created receipt's object id.
|
|
321
|
+
*
|
|
322
|
+
* What `Tx.run` adds over the SDK file: a default expiration bounded to the
|
|
323
|
+
* current epoch, a journal entry written before the first execute so a crash
|
|
324
|
+
* mid-flight leaves a record, resending the identical signed bytes rather
|
|
325
|
+
* than rebuilding on a transient failure, `reconcile` when a submission's
|
|
326
|
+
* outcome is unknown, and a sender lock so two concurrent claims from one
|
|
327
|
+
* address cannot pick the same gas coin. What it costs is the Effect
|
|
328
|
+
* vocabulary below.
|
|
329
|
+
*
|
|
330
|
+
* Run with:
|
|
331
|
+
* SUI_NETWORK=testnet SUI_PRIVATE_KEY=suiprivkey1… ESCROW_ID=0x… bun examples/compare-write.effect.ts
|
|
332
|
+
*/
|
|
333
|
+
import { bcs } from "@mysten/sui/bcs"
|
|
334
|
+
import { Config, Console, Effect } from "effect"
|
|
335
|
+
import { ObjectId, SuiSchema } from "../src/index.ts"
|
|
336
|
+
import { Script } from "../src/script.ts"
|
|
337
|
+
import { Tx } from "../src/tx.ts"
|
|
338
|
+
|
|
339
|
+
const PKG = "0x0000000000000000000000000000000000000000000000000000000000000002"
|
|
340
|
+
|
|
341
|
+
const Escrow = SuiSchema.bcs(
|
|
342
|
+
bcs.struct("Escrow", { id: bcs.Address, amount: bcs.u64() }),
|
|
343
|
+
`${PKG}::escrow::Escrow`
|
|
344
|
+
)
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* The program itself, exported so a test can run it against the fake. Every
|
|
348
|
+
* failure it can produce is in the generator's inferred error type, with no
|
|
349
|
+
* handling lines anywhere in this file: `ObjectNotFound`, `ObjectDeleted`,
|
|
350
|
+
* `ObjectUnavailable`, `DecodeError`, `TransportError`, `BuildError`,
|
|
351
|
+
* `SimulationFailed`, `SigningError`, `PolicyDenied`, `NotApplied`,
|
|
352
|
+
* `JournalError`, `UnexpectedEffects`, `ExecutionFailed`, `SubmissionUnknown`,
|
|
353
|
+
* plus `ConfigError` and `NetworkMismatch` from the layer.
|
|
354
|
+
*/
|
|
355
|
+
export const program = Effect.gen(function*() {
|
|
356
|
+
const { signer, sui } = yield* Script
|
|
357
|
+
const id = yield* Config.schema(ObjectId, "ESCROW_ID")
|
|
358
|
+
const escrow = yield* sui.getObject(id, { schema: Escrow })
|
|
359
|
+
const executed = yield* Tx.run((tx) => {
|
|
360
|
+
tx.moveCall({
|
|
361
|
+
target: `${PKG}::escrow::claim`,
|
|
362
|
+
arguments: [tx.object(id), tx.pure.u64(escrow.content.amount)]
|
|
363
|
+
})
|
|
364
|
+
}, { signer })
|
|
365
|
+
const receipt = yield* executed.expectCreated(`${PKG}::escrow::Receipt`)
|
|
366
|
+
yield* Console.log(receipt.id)
|
|
367
|
+
})
|
|
368
|
+
|
|
369
|
+
if (import.meta.main) {
|
|
370
|
+
await Script.run(program)
|
|
371
|
+
}
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
### What differs
|
|
375
|
+
|
|
376
|
+
- **Absence.** The SDK throws `ObjectError` and the reason (`notFound`,
|
|
377
|
+
`deleted`, `unknown`) is read off the caught value by hand; sui-effect's
|
|
378
|
+
`getObject` fails with `ObjectNotFound` / `ObjectDeleted` / `ObjectUnavailable`,
|
|
379
|
+
three separate tags a caller can `catchTag` without an `if` chain.
|
|
380
|
+
- **Wrong type.** The SDK compares `object.type` itself, and only gets away
|
|
381
|
+
with a plain string equality because this particular type has no type
|
|
382
|
+
parameters; a generic Move type would need the same piecewise comparison
|
|
383
|
+
sui-effect's bridge (`typeMatches`) already runs inside every `getObject`.
|
|
384
|
+
- **BCS.** Both sides hand a `BcsType` to a struct; the SDK calls `.parse`
|
|
385
|
+
itself, sui-effect calls it once, inside `getObject`, after the type check
|
|
386
|
+
above has already passed.
|
|
387
|
+
- **Signing.** Both decode `SUI_PRIVATE_KEY` and dispatch on the scheme flag
|
|
388
|
+
to the matching keypair class; sui-effect's version is `Signer.fromConfig`,
|
|
389
|
+
one call, done once in `src/services/Signer.ts` rather than in every script.
|
|
390
|
+
- **Effects.** The SDK inspects `$kind`, `status.error` and joins
|
|
391
|
+
`changedObjects` against `objectTypes` by hand to find the created object;
|
|
392
|
+
sui-effect's `expectCreated(type)` is that join, plus a check that exactly
|
|
393
|
+
one match exists, as a single call on `Executed`.
|
|
394
|
+
- **What sui-effect adds that neither SDK file has:** a default expiration
|
|
395
|
+
bounded to the current epoch, a journal entry written before the first
|
|
396
|
+
execute, resending identical signed bytes instead of rebuilding on a
|
|
397
|
+
transient failure, `reconcile` when a submission's outcome is unknown, and
|
|
398
|
+
a sender lock so two concurrent writes from one address cannot pick the
|
|
399
|
+
same gas coin.
|
|
400
|
+
- **What it costs.** The sui-effect files import `effect` and run inside
|
|
401
|
+
`Effect.gen`; a reader who does not already know Effect's vocabulary
|
|
402
|
+
(`Effect.fn`, `catchTag`, `Option.match`, `yield*`) has that to learn before
|
|
403
|
+
either file is legible.
|
|
404
|
+
|
|
70
405
|
## The two tiers
|
|
71
406
|
|
|
72
407
|
`SuiCore` is the mechanical tier: a one-to-one Effect wrap of the SDK's
|
|
@@ -172,7 +507,12 @@ pattern. A Promise face's **synchronous** members (recipe builders, a package
|
|
|
172
507
|
id) are real only once the runtime exists, so either `await client.<name>.$ready()`
|
|
173
508
|
once or register with `warm`; calling one before that fails with
|
|
174
509
|
`ExtensionNotReady` rather than returning a Promise the type does not mention
|
|
175
|
-
(`Effect` and `Stream` members work cold
|
|
510
|
+
(`Effect` and `Stream` members work cold: a cold call is a real `Promise` that
|
|
511
|
+
is also an `AsyncIterable`, and its rejection is pre-handled so an un-awaited
|
|
512
|
+
one cannot abort the process). A namespace member may be an `interface` — the
|
|
513
|
+
face maps it by type, not by declaration style — while a class instance with
|
|
514
|
+
`Effect`-returning methods is declared `SuiExtension.Leaf<T>` and built with
|
|
515
|
+
`SuiExtension.leaf(value)`.
|
|
176
516
|
Every registration on one client **shares one `Sui`**, and therefore one
|
|
177
517
|
sender-lock map, so two extensions never select gas for the same address at
|
|
178
518
|
once; `$dispose()` releases that shared base only when the last registration on
|
|
@@ -214,7 +554,9 @@ axis, and an extension error may declare its own. An error that is neither a tag
|
|
|
214
554
|
above nor declares an `outcome` is *unclassified*: `outcome` answers `"unknown"`,
|
|
215
555
|
because an unrecognised tag is no evidence that nothing happened, and
|
|
216
556
|
`Script.exitCode` exits 1 rather than 3, because it is no evidence that anything
|
|
217
|
-
was sent either. Declare `outcome` on every error your extension defines
|
|
557
|
+
was sent either. Declare `outcome` on every error your extension defines — as a
|
|
558
|
+
class field is fine, `toJson` reads it off the instance and serializes it either
|
|
559
|
+
way.
|
|
218
560
|
|
|
219
561
|
## Scripts
|
|
220
562
|
|
|
@@ -257,7 +599,9 @@ submission interrupts it from the outside and the bytes may be on the wire.
|
|
|
257
599
|
|
|
258
600
|
`@unconfirmed/sui-effect/testing` ships the in-memory `SuiCoreFake`, `layerTest(script)` (the
|
|
259
601
|
real `Sui` over the fake, so tests exercise the production high tier),
|
|
260
|
-
`layerExtensionTest(layer, script)` for an extension's own tests
|
|
602
|
+
`layerExtensionTest(layer, script, { extra })` for an extension's own tests
|
|
603
|
+
(`SuiGraphQL.layerUnavailable` is provided by default; `extra` is for anything
|
|
604
|
+
else the extension's layer requires), and `SuiTest`
|
|
261
605
|
for driving the fake's state and reading back what it was sent. No test in this
|
|
262
606
|
repository touches the network, and neither should yours.
|
|
263
607
|
|
package/dist/domain/bcs.d.ts
CHANGED
|
@@ -32,6 +32,50 @@ import type { ObjectId } from "./schemas.ts";
|
|
|
32
32
|
* from an object, which is every `getObject(id, { schema })` read.
|
|
33
33
|
*/
|
|
34
34
|
export declare const bcs: <T extends Input, Input>(bcsType: BcsType<T, Input>, expectedType?: string) => Schema.Codec<T, Uint8Array>;
|
|
35
|
+
/**
|
|
36
|
+
* A BCS layout plus the mapping into a domain value, as one codec.
|
|
37
|
+
*
|
|
38
|
+
* This is the shape every extension writes by hand and writes slightly
|
|
39
|
+
* differently: parse the bytes with a layout, then hand the raw struct to a
|
|
40
|
+
* constructor or a mapping function that may throw (an id that has to be
|
|
41
|
+
* branded, a `bigint` that has to be range-checked, a discriminant that has to
|
|
42
|
+
* become a union). Written out it is `SuiSchema.bcs(...)` piped into a
|
|
43
|
+
* `Schema.decodeTo` with a `transformOrFail` and an `Effect.try`, and the part
|
|
44
|
+
* that gets forgotten is turning the thrown value into a schema issue, so the
|
|
45
|
+
* failure arrives as a defect instead of a `DecodeError`.
|
|
46
|
+
*
|
|
47
|
+
* `map` is called with whatever the layout parsed. Returning a value decodes
|
|
48
|
+
* it; **throwing** fails the decode, and the thrown value's message becomes the
|
|
49
|
+
* `DecodeError.issue` the caller sees, with the expected type already on it.
|
|
50
|
+
* The result is a `Schema.Codec<A, Uint8Array>` like any other: pass it as
|
|
51
|
+
* `sui.getObject(id, { schema })`, and the Move type check still runs first
|
|
52
|
+
* because the annotation {@link bcs} leaves behind survives the composition.
|
|
53
|
+
*
|
|
54
|
+
* Encoding is not supported: a mapping function has no inverse, and inventing
|
|
55
|
+
* one silently is worse than saying so. Encode with the layout itself when you
|
|
56
|
+
* need bytes back.
|
|
57
|
+
*
|
|
58
|
+
* Fails with: `DecodeError` (through the schema), when the bytes do not parse
|
|
59
|
+
* or `map` throws.
|
|
60
|
+
*
|
|
61
|
+
* @since 0.1.1
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```ts
|
|
65
|
+
* import { ObjectId, SuiSchema } from "@unconfirmed/sui-effect"
|
|
66
|
+
*
|
|
67
|
+
* class Escrow {
|
|
68
|
+
* constructor(readonly id: ObjectId, readonly amount: bigint) {}
|
|
69
|
+
* }
|
|
70
|
+
*
|
|
71
|
+
* const EscrowContent = SuiSchema.decodeWith(
|
|
72
|
+
* EscrowLayout,
|
|
73
|
+
* `${packageId}::escrow::Escrow`,
|
|
74
|
+
* (raw) => new Escrow(ObjectId.normalize(raw.id), BigInt(raw.amount))
|
|
75
|
+
* )
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
export declare const decodeWith: <T extends Input, Input, A>(bcsType: BcsType<T, Input>, expectedType: string | undefined, map: (parsed: T) => A) => Schema.Codec<A, Uint8Array>;
|
|
35
79
|
/**
|
|
36
80
|
* The normalized Move type a codec built by {@link bcs} expects, or `undefined`
|
|
37
81
|
* for any other codec. `Sui.getObject` compares it with the object's own type
|
package/dist/domain/bcs.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bcs.d.ts","sourceRoot":"","sources":["../../src/domain/bcs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAE1C,OAAO,EAAE,MAAM,EAAE,MAAM,EAAgD,MAAM,QAAQ,CAAA;AACrF,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAY5C;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,GAAG,GAAI,CAAC,SAAS,KAAK,EAAE,KAAK,EACxC,SAAS,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,EAC1B,eAAe,MAAM,KACpB,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAgD5B,CAAA;AAuBD;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,GAAI,CAAC,EAAE,CAAC,EAAE,QAAQ,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAG,MAAM,GAAG,SAC/C,CAAA;AAU5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,eAAO,MAAM,WAAW,GAAI,UAAU,MAAM,EAAE,QAAQ,MAAM,KAAG,OAU9D,CAAA;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,aAAa,GAAI,CAAC,EAC7B,QAAQ,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,EACnC,SAAS,UAAU,EACnB,UAAU;IACR,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAA;IAC5B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAC7B,KACA,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,WAAW,CA0B9B,CAAA"}
|
|
1
|
+
{"version":3,"file":"bcs.d.ts","sourceRoot":"","sources":["../../src/domain/bcs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAE1C,OAAO,EAAE,MAAM,EAAE,MAAM,EAAgD,MAAM,QAAQ,CAAA;AACrF,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAY5C;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,GAAG,GAAI,CAAC,SAAS,KAAK,EAAE,KAAK,EACxC,SAAS,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,EAC1B,eAAe,MAAM,KACpB,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAgD5B,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,eAAO,MAAM,UAAU,GAAI,CAAC,SAAS,KAAK,EAAE,KAAK,EAAE,CAAC,EAClD,SAAS,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,EAC1B,cAAc,MAAM,GAAG,SAAS,EAChC,KAAK,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,KACpB,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAmC5B,CAAA;AAuBD;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,GAAI,CAAC,EAAE,CAAC,EAAE,QAAQ,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAG,MAAM,GAAG,SAC/C,CAAA;AAU5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,eAAO,MAAM,WAAW,GAAI,UAAU,MAAM,EAAE,QAAQ,MAAM,KAAG,OAU9D,CAAA;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,aAAa,GAAI,CAAC,EAC7B,QAAQ,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,EACnC,SAAS,UAAU,EACnB,UAAU;IACR,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAA;IAC5B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAC7B,KACA,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,WAAW,CA0B9B,CAAA"}
|
package/dist/domain/bcs.js
CHANGED
|
@@ -59,6 +59,63 @@ export const bcs = (bcsType, expectedType) => {
|
|
|
59
59
|
})
|
|
60
60
|
}))).annotate(normalized === undefined ? {} : { [SUI_TYPE_ANNOTATION]: normalized });
|
|
61
61
|
};
|
|
62
|
+
/**
|
|
63
|
+
* A BCS layout plus the mapping into a domain value, as one codec.
|
|
64
|
+
*
|
|
65
|
+
* This is the shape every extension writes by hand and writes slightly
|
|
66
|
+
* differently: parse the bytes with a layout, then hand the raw struct to a
|
|
67
|
+
* constructor or a mapping function that may throw (an id that has to be
|
|
68
|
+
* branded, a `bigint` that has to be range-checked, a discriminant that has to
|
|
69
|
+
* become a union). Written out it is `SuiSchema.bcs(...)` piped into a
|
|
70
|
+
* `Schema.decodeTo` with a `transformOrFail` and an `Effect.try`, and the part
|
|
71
|
+
* that gets forgotten is turning the thrown value into a schema issue, so the
|
|
72
|
+
* failure arrives as a defect instead of a `DecodeError`.
|
|
73
|
+
*
|
|
74
|
+
* `map` is called with whatever the layout parsed. Returning a value decodes
|
|
75
|
+
* it; **throwing** fails the decode, and the thrown value's message becomes the
|
|
76
|
+
* `DecodeError.issue` the caller sees, with the expected type already on it.
|
|
77
|
+
* The result is a `Schema.Codec<A, Uint8Array>` like any other: pass it as
|
|
78
|
+
* `sui.getObject(id, { schema })`, and the Move type check still runs first
|
|
79
|
+
* because the annotation {@link bcs} leaves behind survives the composition.
|
|
80
|
+
*
|
|
81
|
+
* Encoding is not supported: a mapping function has no inverse, and inventing
|
|
82
|
+
* one silently is worse than saying so. Encode with the layout itself when you
|
|
83
|
+
* need bytes back.
|
|
84
|
+
*
|
|
85
|
+
* Fails with: `DecodeError` (through the schema), when the bytes do not parse
|
|
86
|
+
* or `map` throws.
|
|
87
|
+
*
|
|
88
|
+
* @since 0.1.1
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```ts
|
|
92
|
+
* import { ObjectId, SuiSchema } from "@unconfirmed/sui-effect"
|
|
93
|
+
*
|
|
94
|
+
* class Escrow {
|
|
95
|
+
* constructor(readonly id: ObjectId, readonly amount: bigint) {}
|
|
96
|
+
* }
|
|
97
|
+
*
|
|
98
|
+
* const EscrowContent = SuiSchema.decodeWith(
|
|
99
|
+
* EscrowLayout,
|
|
100
|
+
* `${packageId}::escrow::Escrow`,
|
|
101
|
+
* (raw) => new Escrow(ObjectId.normalize(raw.id), BigInt(raw.amount))
|
|
102
|
+
* )
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
export const decodeWith = (bcsType, expectedType, map) => {
|
|
106
|
+
const target = Schema.declare((_u) => true);
|
|
107
|
+
return bcs(bcsType, expectedType).pipe(Schema.decodeTo(target, SchemaTransformation.transformOrFail({
|
|
108
|
+
decode: (parsed, options) => Effect.try({
|
|
109
|
+
try: () => map(parsed),
|
|
110
|
+
catch: (cause) => new SchemaIssue.InvalidValue({
|
|
111
|
+
message: `Could not map ${expectedType ?? bcsType.name} into its domain value: ${String(cause)}`
|
|
112
|
+
}, parsed, options)
|
|
113
|
+
}),
|
|
114
|
+
encode: (value, options) => Effect.fail(new SchemaIssue.Forbidden({
|
|
115
|
+
message: `${expectedType ?? bcsType.name} was built with SuiSchema.decodeWith, which has no encoder: serialize with the BCS layout instead`
|
|
116
|
+
}, value, options))
|
|
117
|
+
})));
|
|
118
|
+
};
|
|
62
119
|
const MAX_ENCODING_DEPTH = 32;
|
|
63
120
|
/**
|
|
64
121
|
* Walks the encoding chain looking for the annotation {@link bcs} leaves
|
package/dist/domain/bcs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bcs.js","sourceRoot":"","sources":["../../src/domain/bcs.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"bcs.js","sourceRoot":"","sources":["../../src/domain/bcs.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACtE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,QAAQ,CAAA;AACrF,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAGzC,MAAM,mBAAmB,GAAG,oBAAoB,CAAA;AAEhD,MAAM,aAAa,GAAG,CAAC,KAAa,EAAU,EAAE;IAC9C,IAAI,CAAC;QACH,OAAO,kBAAkB,CAAC,KAAK,CAAC,CAAA;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC,CAAA;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,MAAM,GAAG,GAAG,CACjB,OAA0B,EAC1B,YAAqB,EACQ,EAAE;IAC/B,MAAM,UAAU,GAAG,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,YAAY,CAAC,CAAA;IACvF,4EAA4E;IAC5E,+EAA+E;IAC/E,MAAM,KAAK,GAAG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAA;IACxC,4EAA4E;IAC5E,2EAA2E;IAC3E,mBAAmB;IACnB,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,EAAW,EAAW,EAAE,CAAC,IAAI,CAAC,CAAA;IAC7D,OAAO,MAAM,CAAC,UAAU,CAAC,IAAI,CAC3B,MAAM,CAAC,QAAQ,CACb,MAAM,EACN,oBAAoB,CAAC,eAAe,CAAgB;QAClD,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CACzB,MAAM,CAAC,GAAG,CAAC;YACT,GAAG,EAAE,GAAG,EAAE;gBACR,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;gBACnC,8DAA8D;gBAC9D,+DAA+D;gBAC/D,kEAAkE;gBAClE,8CAA8C;gBAC9C,IAAI,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;oBAChE,MAAM,IAAI,KAAK,CAAC,YAAY,KAAK,CAAC,MAAM,aAAa,KAAK,EAAE,CAAC,CAAA;gBAC/D,CAAC;gBACD,OAAO,MAAM,CAAA;YACf,CAAC;YACD,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CACf,IAAI,WAAW,CAAC,YAAY,CAC1B,EAAE,OAAO,EAAE,mBAAmB,KAAK,sBAAsB,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,EAC1E,KAAK,EACL,OAAO,CACR;SACJ,CAAC;QACJ,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CACzB,MAAM,CAAC,GAAG,CAAC;YACT,GAAG,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE;YAC7C,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CACf,IAAI,WAAW,CAAC,YAAY,CAC1B,EAAE,OAAO,EAAE,uBAAuB,KAAK,YAAY,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,EACpE,KAAK,EACL,OAAO,CACR;SACJ,CAAC;KACL,CAAC,CACH,CACF,CAAC,QAAQ,CACR,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,mBAAmB,CAAC,EAAE,UAAU,EAAE,CAC5B,CAAA;AAC7C,CAAC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CACxB,OAA0B,EAC1B,YAAgC,EAChC,GAAqB,EACQ,EAAE;IAC/B,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,EAAW,EAAW,EAAE,CAAC,IAAI,CAAC,CAAA;IAC7D,OAAO,GAAG,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,IAAI,CACpC,MAAM,CAAC,QAAQ,CACb,MAAM,EACN,oBAAoB,CAAC,eAAe,CAAO;QACzC,MAAM,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,CAC1B,MAAM,CAAC,GAAG,CAAC;YACT,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC;YACtB,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CACf,IAAI,WAAW,CAAC,YAAY,CAC1B;gBACE,OAAO,EAAE,iBACP,YAAY,IAAI,OAAO,CAAC,IAC1B,2BAA2B,MAAM,CAAC,KAAK,CAAC,EAAE;aAC3C,EACD,MAAM,EACN,OAAO,CACR;SACJ,CAAC;QACJ,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CACzB,MAAM,CAAC,IAAI,CACT,IAAI,WAAW,CAAC,SAAS,CACvB;YACE,OAAO,EAAE,GACP,YAAY,IAAI,OAAO,CAAC,IAC1B,mGAAmG;SACpG,EACD,KAAK,EACL,OAAO,CACR,CACF;KACJ,CAAC,CACH,CACwC,CAAA;AAC7C,CAAC,CAAA;AAED,MAAM,kBAAkB,GAAG,EAAE,CAAA;AAE7B;;;;;GAKG;AACH,MAAM,WAAW,GAAG,CAAC,GAAkB,EAAE,KAAa,EAAsB,EAAE;IAC5E,MAAM,UAAU,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC,mBAAmB,CAAC,CAAA;IACzD,IAAI,OAAO,UAAU,KAAK,QAAQ;QAAE,OAAO,UAAU,CAAA;IACrD,IAAI,KAAK,IAAI,kBAAkB;QAAE,OAAO,SAAS,CAAA;IACjD,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAA;IAC7B,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IAC5C,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,GAAG,CAAC,CAAC,CAAA;QAC7C,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,KAAK,CAAA;IACvC,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC,CAAA;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAO,MAA0B,EAAsB,EAAE,CACrF,WAAW,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;AAE5B,MAAM,SAAS,GAAG,CAAC,KAAa,EAAiD,EAAE;IACjF,IAAI,CAAC;QACH,OAAO,cAAc,CAAC,KAAK,CAAC,CAAA;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,QAAgB,EAAE,MAAc,EAAW,EAAE;IACvE,MAAM,WAAW,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAA;IACvC,IAAI,WAAW,KAAK,SAAS,IAAI,WAAW,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACnE,OAAO,aAAa,CAAC,QAAQ,CAAC,KAAK,aAAa,CAAC,MAAM,CAAC,CAAA;IAC1D,CAAC;IACD,MAAM,SAAS,GAAG,SAAS,CAAC,MAAM,CAAC,CAAA;IACnC,IAAI,SAAS,KAAK,SAAS;QAAE,OAAO,aAAa,CAAC,QAAQ,CAAC,KAAK,aAAa,CAAC,MAAM,CAAC,CAAA;IACrF,OAAO,WAAW,CAAC,OAAO,KAAK,SAAS,CAAC,OAAO;QAC9C,WAAW,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM;QACvC,WAAW,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI,CAAA;AACvC,CAAC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAC3B,MAAmC,EACnC,OAAmB,EACnB,OAIC,EAC8B,EAAE;IACjC,MAAM,QAAQ,GAAG,OAAO,EAAE,YAAY,IAAI,cAAc,CAAC,MAAM,CAAC,CAAA;IAChE,MAAM,YAAY,GAAG,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAA;IAC7E,MAAM,UAAU,GAAG,OAAO,EAAE,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAA;IACxF,MAAM,MAAM,GAAG,OAAO,EAAE,UAAU,CAAA;IAClC,IAAI,QAAQ,KAAK,SAAS,IAAI,MAAM,KAAK,SAAS,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,CAAC;QACrF,OAAO,MAAM,CAAC,IAAI,CAChB,IAAI,WAAW,CAAC;YACd,GAAG,UAAU;YACb,GAAG,YAAY;YACf,KAAK,EAAE,GACL,OAAO,EAAE,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,UAAU,OAAO,CAAC,QAAQ,MACjF,SAAS,MAAM,EAAE;SAClB,CAAC,CACH,CAAA;IACH,CAAC;IACD,OAAO,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CACrD,MAAM,CAAC,QAAQ,CACb,CAAC,KAAK,EAAE,EAAE,CACR,IAAI,WAAW,CAAC;QACd,GAAG,UAAU;QACb,GAAG,YAAY;QACf,KAAK,EAAE,KAAK,CAAC,OAAO;KACrB,CAAC,CACL,CACF,CAAA;AACH,CAAC,CAAA"}
|