sui-effect 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +209 -0
- package/LICENSE +21 -0
- package/LLMS.md +6707 -0
- package/README.md +300 -0
- package/dist/domain/bcs.d.ts +101 -0
- package/dist/domain/bcs.d.ts.map +1 -0
- package/dist/domain/bcs.js +183 -0
- package/dist/domain/bcs.js.map +1 -0
- package/dist/domain/errors.d.ts +595 -0
- package/dist/domain/errors.d.ts.map +1 -0
- package/dist/domain/errors.js +476 -0
- package/dist/domain/errors.js.map +1 -0
- package/dist/domain/executed.d.ts +325 -0
- package/dist/domain/executed.d.ts.map +1 -0
- package/dist/domain/executed.js +253 -0
- package/dist/domain/executed.js.map +1 -0
- package/dist/domain/journal-entry.d.ts +468 -0
- package/dist/domain/journal-entry.d.ts.map +1 -0
- package/dist/domain/journal-entry.js +63 -0
- package/dist/domain/journal-entry.js.map +1 -0
- package/dist/domain/schemas.d.ts +950 -0
- package/dist/domain/schemas.d.ts.map +1 -0
- package/dist/domain/schemas.js +571 -0
- package/dist/domain/schemas.js.map +1 -0
- package/dist/domain/sui-schema.d.ts +12 -0
- package/dist/domain/sui-schema.d.ts.map +1 -0
- package/dist/domain/sui-schema.js +12 -0
- package/dist/domain/sui-schema.js.map +1 -0
- package/dist/extension.d.ts +7 -0
- package/dist/extension.d.ts.map +1 -0
- package/dist/extension.js +7 -0
- package/dist/extension.js.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/internal.d.ts +18 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +18 -0
- package/dist/internal.js.map +1 -0
- package/dist/journal.d.ts +51 -0
- package/dist/journal.d.ts.map +1 -0
- package/dist/journal.js +18 -0
- package/dist/journal.js.map +1 -0
- package/dist/script.d.ts +7 -0
- package/dist/script.d.ts.map +1 -0
- package/dist/script.js +7 -0
- package/dist/script.js.map +1 -0
- package/dist/services/Journal.d.ts +76 -0
- package/dist/services/Journal.d.ts.map +1 -0
- package/dist/services/Journal.js +70 -0
- package/dist/services/Journal.js.map +1 -0
- package/dist/services/JournalKeyValueStore.d.ts +73 -0
- package/dist/services/JournalKeyValueStore.d.ts.map +1 -0
- package/dist/services/JournalKeyValueStore.js +155 -0
- package/dist/services/JournalKeyValueStore.js.map +1 -0
- package/dist/services/Script.d.ts +210 -0
- package/dist/services/Script.d.ts.map +1 -0
- package/dist/services/Script.js +441 -0
- package/dist/services/Script.js.map +1 -0
- package/dist/services/Signer.d.ts +132 -0
- package/dist/services/Signer.d.ts.map +1 -0
- package/dist/services/Signer.js +158 -0
- package/dist/services/Signer.js.map +1 -0
- package/dist/services/SubmitConfig.d.ts +175 -0
- package/dist/services/SubmitConfig.d.ts.map +1 -0
- package/dist/services/SubmitConfig.js +52 -0
- package/dist/services/SubmitConfig.js.map +1 -0
- package/dist/services/Sui.d.ts +295 -0
- package/dist/services/Sui.d.ts.map +1 -0
- package/dist/services/Sui.js +414 -0
- package/dist/services/Sui.js.map +1 -0
- package/dist/services/SuiCore.d.ts +227 -0
- package/dist/services/SuiCore.d.ts.map +1 -0
- package/dist/services/SuiCore.js +400 -0
- package/dist/services/SuiCore.js.map +1 -0
- package/dist/services/SuiCoreFake.d.ts +278 -0
- package/dist/services/SuiCoreFake.d.ts.map +1 -0
- package/dist/services/SuiCoreFake.js +1003 -0
- package/dist/services/SuiCoreFake.js.map +1 -0
- package/dist/services/SuiExtension.d.ts +208 -0
- package/dist/services/SuiExtension.d.ts.map +1 -0
- package/dist/services/SuiExtension.js +355 -0
- package/dist/services/SuiExtension.js.map +1 -0
- package/dist/services/SuiGraphQL.d.ts +98 -0
- package/dist/services/SuiGraphQL.d.ts.map +1 -0
- package/dist/services/SuiGraphQL.js +118 -0
- package/dist/services/SuiGraphQL.js.map +1 -0
- package/dist/services/Tx.d.ts +687 -0
- package/dist/services/Tx.d.ts.map +1 -0
- package/dist/services/Tx.js +1224 -0
- package/dist/services/Tx.js.map +1 -0
- package/dist/testing.d.ts +88 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +163 -0
- package/dist/testing.js.map +1 -0
- package/dist/tx.d.ts +24 -0
- package/dist/tx.d.ts.map +1 -0
- package/dist/tx.js +24 -0
- package/dist/tx.js.map +1 -0
- package/docs/extensions.md +1685 -0
- package/examples/extension-template/README.md +170 -0
- package/examples/extension-template/package.json +44 -0
- package/examples/extension-template/scripts/check-package.ts +145 -0
- package/examples/extension-template/src/Escrow.ts +445 -0
- package/examples/extension-template/src/Platform.ts +136 -0
- package/examples/extension-template/src/errors.ts +61 -0
- package/examples/extension-template/src/extension.ts +63 -0
- package/examples/extension-template/src/index.ts +34 -0
- package/examples/extension-template/src/schema.ts +158 -0
- package/examples/extension-template/src/upstream.ts +66 -0
- package/examples/extension-template/test/escrow.test.ts +559 -0
- package/examples/extension-template/tsconfig.build.json +26 -0
- package/examples/extension-template/tsconfig.json +35 -0
- package/package.json +87 -0
package/AGENTS.md
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
# Agent guidance
|
|
2
|
+
|
|
3
|
+
`DESIGN.md` is the specification and wins over everything else; `docs/PLAN.md` is
|
|
4
|
+
the work plan. Where this file and the spec disagree, fix this file.
|
|
5
|
+
|
|
6
|
+
## Ground rules
|
|
7
|
+
|
|
8
|
+
- **Effect v4, pinned to exactly `4.0.0-rc.112`.** The peer range is the exact
|
|
9
|
+
version, not a range: rc.113 renamed `Config.nonEmptyString`, `Config.string`
|
|
10
|
+
and `Config.redacted` to `Config.NonEmptyString`, `Config.String` and
|
|
11
|
+
`Config.Redacted`, which this package calls at four sites (`Script.ts:64,66`,
|
|
12
|
+
`Signer.ts:150,154`, `SuiCore.ts:458-462`, `SuiGraphQL.ts:73-77`). v3 names
|
|
13
|
+
are compile errors. Never
|
|
14
|
+
write an Effect name from memory: verify it in `node_modules/effect/dist/*.d.ts`.
|
|
15
|
+
The house skill `effect-ts` and its review checklist are binding.
|
|
16
|
+
- **SDK names are the source of truth.** Read
|
|
17
|
+
`node_modules/@mysten/sui/docs/llms-index.md` first, then the version-matched
|
|
18
|
+
page, then confirm the signature in `node_modules/@mysten/sui/dist/**/*.d.mts`.
|
|
19
|
+
- Everything that is not public API lives in `src/internal.ts`, which is not in
|
|
20
|
+
the `exports` map. `src/index.ts` is exactly the public surface.
|
|
21
|
+
- **Every public name mirrors the SDK name it wraps**, so an agent that knows
|
|
22
|
+
`@mysten/sui` can guess sui-effect.
|
|
23
|
+
- Nothing under `src/` imports `@effect/platform-bun` or `bun:*`. `@effect/platform-bun`
|
|
24
|
+
is a devDependency for tests and examples only.
|
|
25
|
+
- No `Effect.runPromise` / `runSync` under `src/`, except at the two documented
|
|
26
|
+
edges: the Promise facade of `SuiExtension.fromService`, and `Script.run`,
|
|
27
|
+
which is a process entrypoint and whose whole job is to fork the root fiber,
|
|
28
|
+
await its `Exit` and exit.
|
|
29
|
+
- No `any`. No `unknown` in an error channel. No `console.log` in `src/`.
|
|
30
|
+
- **One Move type rule.** `typeMatches(expected, actual)` (`src/domain/bcs.ts`)
|
|
31
|
+
is the only comparison: a bare expected tag matches every instantiation of the
|
|
32
|
+
generic, a parameterized one is compared in full after normalization. The
|
|
33
|
+
bridge, `expectedType`, `SuiSchema.decode`'s `actualType` and the fake's
|
|
34
|
+
owned-object filter all go through it, and so must anything new.
|
|
35
|
+
- **A `TransportError` for your own transport** comes from
|
|
36
|
+
`TransportError.fromUnknown(method, cause, retryable?)`, never from
|
|
37
|
+
hand-building the three fields.
|
|
38
|
+
- Every public function carries a JSDoc block that **states its error union in
|
|
39
|
+
words** ("Fails with: `ObjectNotFound`, `TransportError`."), so `LLMS.md` can be
|
|
40
|
+
generated from the source.
|
|
41
|
+
- Every dependency is a `Context.Service` with static layers (`layer`,
|
|
42
|
+
`layerNoDeps`, `layerConfig`, a test layer). Every error is a
|
|
43
|
+
`Schema.TaggedError`. Schema decodes at every boundary. Time comes from
|
|
44
|
+
`DateTime`/`Clock`, randomness from `Random`, config from `Config`.
|
|
45
|
+
- Every service method is `Effect.fn("Service.method")`, which names its span.
|
|
46
|
+
The only exceptions are `Sui.getObject`, `getObjectOption` and `getObjects`,
|
|
47
|
+
whose declared types are overload sets `Effect.fn` cannot express; their
|
|
48
|
+
implementations are still `Effect.fn`.
|
|
49
|
+
- Every SDK call forwards the Effect's `AbortSignal` into the SDK's `signal`
|
|
50
|
+
option, so `Effect.timeout` and interruption cancel the request.
|
|
51
|
+
- Tests run on `bun test` with `effect/testing` (`TestClock`, `TestSchema`).
|
|
52
|
+
Tests provide their own layers and never touch the network, with one gated
|
|
53
|
+
exception: `test/live.devnet.test.ts` runs against devnet behind `SUI_LIVE=1`
|
|
54
|
+
and is the only proof that a default-built transaction is accepted by a real
|
|
55
|
+
validator. Localnet tests sit behind `SUI_LOCALNET=1`. A test that runs
|
|
56
|
+
`Tx.submit` or `Tx.run` provides `Journal.layerMemory`, because the default
|
|
57
|
+
journal is process-wide.
|
|
58
|
+
- Done means `bun run check` (typecheck, build, tests, and the extension
|
|
59
|
+
template's own check) is green. `LLMS.md` is generated — `bun run llms` after
|
|
60
|
+
any public signature or example change, and a test fails if it is stale.
|
|
61
|
+
`docs/extensions.md` is generated from `docs/extensions.tpl.md` by
|
|
62
|
+
`bun run docs:extensions`, and its code blocks must stay verbatim copies of
|
|
63
|
+
`examples/extension-template/`.
|
|
64
|
+
|
|
65
|
+
## The two tiers
|
|
66
|
+
|
|
67
|
+
| Tier | What it is | When to use it |
|
|
68
|
+
|---|---|---|
|
|
69
|
+
| `SuiCore` | A 1:1 Effect wrap of `ClientWithCoreApi`. One member per `SuiClientTypes.TransportMethods` key plus `getObject`, `getDynamicObjectField`, `waitForTransaction`, `signAndExecuteTransaction` and `use`. `Include` generics preserved. | Reaching a field or method `Sui` does not expose, and inside extension implementations. |
|
|
70
|
+
| `Sui` | The opinionated tier over `SuiCore`: fixed include sets, decoded BCS content, `Option` where absence is normal, chunked and integrity-checked batch reads (`getObjects` per-item `Result`, `getObjectsOrFail` first-error-wins), `Stream` pagination, one sender lock. | Almost all application and extension code. |
|
|
71
|
+
|
|
72
|
+
Reads go through `Sui`; writes go through `Tx`. An extension never calls
|
|
73
|
+
`SuiCore.executeTransaction` directly. `Sui` exposes the `SuiCore` it was built
|
|
74
|
+
over as `sui.core`, which is what lets every `Tx.*` function declare `R = Sui`
|
|
75
|
+
and nothing else.
|
|
76
|
+
|
|
77
|
+
## The lifecycle
|
|
78
|
+
|
|
79
|
+
| Name | What it is |
|
|
80
|
+
|---|---|
|
|
81
|
+
| `Signer` | A credential as a **value**, never a service: `{ address, scheme, signTransaction, signPersonalMessage }`. One process may hold two. Secret material never reaches the value. |
|
|
82
|
+
| `Tx.build/sign/cosign/sponsored/submit/reconcile/run/reconcileAll` | The lifecycle as functions, each with a closed error union, all `R = Sui`. |
|
|
83
|
+
| `SubmitConfig` | A `Context.Reference` holding expiration policy, the optional `validFor` wall-clock bound, the gas-budget ceiling, `preflight`, the sender lock, the resubmit schedule, attempts, timeout and expiry margin, plus `expiryEvidence`, `reconcileRecheck`, `awaitVisibility`, `visibilityTimeout` and `nonce`. |
|
|
84
|
+
| `Journal` | A `Context.Reference` with an in-memory default. `sui-effect/journal` swaps in a durable one over `KeyValueStore`; `Tx.reconcileAll()` is the explicit startup call. |
|
|
85
|
+
| `Script` | `{ sui, core, signer, network }` plus `Script.run` and `Script.exitCode`. `ScriptReadOnly` is the signer-less variant, a separate key on purpose. |
|
|
86
|
+
| `SuiExtension.fromService` | The Promise face of an Effect service, and the only place in `src/` allowed to run Effects. Options: `sui` (chain pinning), `warm` (build the runtime synchronously in `register`). The face carries `$ready()` and `$dispose()`; a synchronous member called before the runtime exists fails with `ExtensionNotReady`, while `Effect` and `Stream` members work cold. Every registration on one client shares one base `Sui`/`SuiCore` — one chain-id read and one sender-lock map — reference counted, so `$dispose()` releases it only when the last registration does. |
|
|
87
|
+
| `SuiGraphQL` | A bare tag over the SDK's `SuiGraphQLClient` (`layer`, `layerConfig`, `layerUnavailable`). sui-effect wraps no GraphQL API; the tag exists so extensions share one client. |
|
|
88
|
+
|
|
89
|
+
## Extensions
|
|
90
|
+
|
|
91
|
+
Downstream SDKs are extensions: one `Context.Service` on `Sui` and `Tx`, layers
|
|
92
|
+
that require `Sui` and never build a client, recipe fragments rather than
|
|
93
|
+
submissions, signers as parameters, errors that declare an `outcome`, and a
|
|
94
|
+
Promise face derived by `SuiExtension.fromService`. `docs/extensions.md` is the
|
|
95
|
+
contract and its review checklist; `examples/extension-template/` is the
|
|
96
|
+
copyable package every block of that guide is quoted from, and
|
|
97
|
+
`bun run check:template` is its own check.
|
|
98
|
+
|
|
99
|
+
`Tx.submit` journals `Signed` before the first execute, re-sends the identical
|
|
100
|
+
bytes (never a rebuild) on a retryable `TransportError` or a timeout, and
|
|
101
|
+
reconciles when the retries run out. A `TransportError` never escapes once bytes
|
|
102
|
+
may have been sent: it becomes `SubmissionUnknown`, which carries them.
|
|
103
|
+
`JournalError` escapes only from the `Signed` write, before anything is sent;
|
|
104
|
+
after the network has answered, a failed journal write is logged and the answer
|
|
105
|
+
stands.
|
|
106
|
+
|
|
107
|
+
`Tx.build` bounds a transaction to the current epoch and the next and names the
|
|
108
|
+
chain, records `sui.chainId` on `Built`/`Signed`, always simulates before
|
|
109
|
+
anything is signed (the SDK's resolver does it whenever there is anything to
|
|
110
|
+
resolve — a client with a base resolver and a preset gas budget resolves without
|
|
111
|
+
simulating, and `willResolve` sees that and runs one explicitly), and cancels
|
|
112
|
+
its in-flight request when interrupted, on **every** transport: the gRPC
|
|
113
|
+
resolver's simulate is reached by rebuilding the SDK's own
|
|
114
|
+
`GrpcCoreClient.resolveTransactionPlugin` over a client that carries the
|
|
115
|
+
signal. It sets no `maxTimestamp`: no Sui network accepts a timestamp
|
|
116
|
+
expiration yet (`test/live.devnet.test.ts`, behind `SUI_LIVE=1`, is the proof).
|
|
117
|
+
`Tx.run` takes `sponsor?: Signer` and requires it whenever the bytes name a gas
|
|
118
|
+
owner that is not the sender. `Tx.submit` waits for visibility before releasing
|
|
119
|
+
the sender lock.
|
|
120
|
+
|
|
121
|
+
`NotApplied` needs evidence that is checked twice: `"expired"` is
|
|
122
|
+
epoch-or-timestamp closed, then a `getTransaction` miss, then both again after
|
|
123
|
+
`SubmitConfig.reconcileRecheck`; `"inputConsumed"` is a **different**
|
|
124
|
+
transaction's own effects reporting `inputVersion` equal to the version the
|
|
125
|
+
bytes pinned. Reconcile follows the live object's `previousTransaction` — which
|
|
126
|
+
names the latest mutation, and is never evidence by itself — to that
|
|
127
|
+
transaction and reads `changedObjects[].inputVersion` off it. There is no
|
|
128
|
+
`v + 1` rule: Sui stamps every output with the transaction's Lamport version
|
|
129
|
+
(`max(input versions) + 1`), so the object "one version on" from a pinned one
|
|
130
|
+
usually never existed. `SuiCore.getObjectAtVersion` is still a public primitive;
|
|
131
|
+
it is no longer part of the rule. Every pinned reference is tried before the
|
|
132
|
+
answer is `SubmissionUnknown`, which is what almost every stuck submission gets.
|
|
133
|
+
Chain identity is compared before any recovery query, and
|
|
134
|
+
`reconcile`/`reconcileAll` turn every recovery read failure into
|
|
135
|
+
`SubmissionUnknown`.
|
|
136
|
+
|
|
137
|
+
`SuiCore` retries retryable `TransportError`s on reads only
|
|
138
|
+
(`Schedule.min([exponential("250 millis"), spaced("10 seconds")])` jittered, five
|
|
139
|
+
attempts). Retryable means gRPC `UNAVAILABLE`, `DEADLINE_EXCEEDED`,
|
|
140
|
+
`RESOURCE_EXHAUSTED`, `INTERNAL` or `UNKNOWN`, HTTP 5xx or 429, or a timeout;
|
|
141
|
+
`INTERNAL` and `UNKNOWN` are how grpc-web reports that the request never reached
|
|
142
|
+
a node at all. `executeTransaction` is never retried at this tier.
|
|
143
|
+
|
|
144
|
+
## The error taxonomy
|
|
145
|
+
|
|
146
|
+
Every failure is one flat tag; there is no error inheritance.
|
|
147
|
+
|
|
148
|
+
| Tag | Means |
|
|
149
|
+
|---|---|
|
|
150
|
+
| `TransportError` | The request did not reach a usable answer. `retryable` says whether a read may try again. |
|
|
151
|
+
| `ObjectNotFound` / `ObjectDeleted` / `ObjectUnavailable` | The three `ObjectError.reason` values. |
|
|
152
|
+
| `TransactionNotFound` | No transaction with that digest is known. |
|
|
153
|
+
| `NetworkMismatch` | The node is on another chain than the layer was built for. |
|
|
154
|
+
| `DecodeError` | BCS content or a schema boundary did not decode. |
|
|
155
|
+
| `SimulationFailed` | Simulation reported an execution failure. No gas charged. |
|
|
156
|
+
| `ExecutionFailed` | Applied on chain and failed. Gas charged. |
|
|
157
|
+
| `SubmissionUnknown` | Bytes may have been sent; the outcome is unknown. Carries the signed bytes, unless it came from reconciling a bare digest. |
|
|
158
|
+
| `NotApplied` | Provably never applied. `expired`: the expiry window was observed closed and the transaction missing, twice, `reconcileRecheck` apart. `inputConsumed`: the object at the version **after** a pinned one names a **different** transaction. An input that merely moved on is not evidence. |
|
|
159
|
+
| `SigningError` / `BuildError` / `PolicyDenied` / `JournalError` / `UnexpectedEffects` | Signing, building, preflight policy, journal, and effects that did not contain what was expected. |
|
|
160
|
+
| `GraphQLUnavailable` / `ExtensionNotReady` | No usable GraphQL endpoint; a synchronous Promise-face member used before its runtime existed. Both `not_applied`. |
|
|
161
|
+
|
|
162
|
+
`SuiError.outcome(e)` puts every failure on the axis a wrapper script acts on:
|
|
163
|
+
`"applied"` for `ExecutionFailed` and `UnexpectedEffects`, `"unknown"` for `SubmissionUnknown`,
|
|
164
|
+
`"not_applied"` for every other tag in the taxonomy, and `"unknown"` for
|
|
165
|
+
anything that is neither one of those tags nor declares an `outcome`.
|
|
166
|
+
`Script.exitCode` exits 1 for that last case rather than 3. An extension error
|
|
167
|
+
may declare its own `outcome`, and should. `SuiError.isRetryable`, `SuiError.describe` (one actionable line) and
|
|
168
|
+
`SuiError.toJson` round it out.
|
|
169
|
+
|
|
170
|
+
## Testing
|
|
171
|
+
|
|
172
|
+
`sui-effect/testing` ships `SuiCoreFake.layer(script)`, `layerTest(script)`
|
|
173
|
+
(the real `Sui` over the fake `SuiCore`), `layerExtensionTest(layer, script)`
|
|
174
|
+
(an extension's own layer over that) and `SuiTest` (`putObject`, `bumpVersion`,
|
|
175
|
+
`recordTransaction`, `deleteObject`, `setClock`, `setEpoch`, `scriptExecute`,
|
|
176
|
+
`scriptSimulate`, `scriptGetTransaction`, `calls`), which is the whole harness
|
|
177
|
+
an extension's tests need. Call recording is reached through `SuiTest.calls`,
|
|
178
|
+
not off the fake handle. The fake serves in-memory objects with
|
|
179
|
+
BCS content, the Clock object `0x6`, and scripted outcomes
|
|
180
|
+
(`FakeOutcome.succeed`, `failWith`, `transportError`, `notFound`, `timeoutThen`)
|
|
181
|
+
for simulate, execute, `getTransaction` and the resolver's budget simulation
|
|
182
|
+
(`buildSimulate`, which is how a test makes `Tx.build` fail with
|
|
183
|
+
`SimulationFailed`). It records every call so a test can
|
|
184
|
+
assert the include set that was sent. It also implements
|
|
185
|
+
`resolveTransactionPlugin` and `listCoins`, so `transaction.build({ client })`
|
|
186
|
+
against the fake's `client` resolves gas and object inputs from the script with
|
|
187
|
+
no network, and it keys transactions by
|
|
188
|
+
`TransactionDataBuilder.getDigestFromBytes` of the bytes it was handed. Any
|
|
189
|
+
method the script does not cover dies with a message naming it: a test never
|
|
190
|
+
silently passes against a stub. Its `client` implements `$extend`, so a derived
|
|
191
|
+
Promise face is testable the way a consumer writes it; `listOwnedObjects`
|
|
192
|
+
filters through `typeMatches` rather than string equality, and `getDynamicField`
|
|
193
|
+
matches an entry on **both** `name.type` and `name.bcs` — an entry scripted
|
|
194
|
+
without `bcs` still matches any key of its type, so two same-typed keys on one
|
|
195
|
+
parent can be told apart and a test can prove which key bytes a lookup used.
|
|
196
|
+
`FakeScript.transactions` (and `SuiTest.recordTransaction`) answers
|
|
197
|
+
`getTransaction` **by digest**, before the ordered script, which is what a
|
|
198
|
+
`NotApplied { inputConsumed }` test needs: the rule reads
|
|
199
|
+
`changedObjects[].inputVersion` off the consuming transaction, and
|
|
200
|
+
`FakeChange.inputVersion` is how a test says which version that was. A scripted
|
|
201
|
+
`commandResults` entry may give either array; the missing one defaults to `[]`
|
|
202
|
+
rather than failing a `Simulation` decode.
|
|
203
|
+
|
|
204
|
+
The fake enforces the invariants the lifecycle depends on: a known digest
|
|
205
|
+
executes idempotently, gas selection excludes object inputs, the coin set
|
|
206
|
+
evolves (deleted, mutated with `FakeChange.balance`, gas-bumped, created), a
|
|
207
|
+
submission with fewer signatures than the bytes name signers is refused, and a
|
|
208
|
+
version history is served through `tryGetPastObject`, which is what
|
|
209
|
+
`SuiCore.getObjectAtVersion` reads.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Unconfirmed Labs
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|