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.
Files changed (115) hide show
  1. package/AGENTS.md +209 -0
  2. package/LICENSE +21 -0
  3. package/LLMS.md +6707 -0
  4. package/README.md +300 -0
  5. package/dist/domain/bcs.d.ts +101 -0
  6. package/dist/domain/bcs.d.ts.map +1 -0
  7. package/dist/domain/bcs.js +183 -0
  8. package/dist/domain/bcs.js.map +1 -0
  9. package/dist/domain/errors.d.ts +595 -0
  10. package/dist/domain/errors.d.ts.map +1 -0
  11. package/dist/domain/errors.js +476 -0
  12. package/dist/domain/errors.js.map +1 -0
  13. package/dist/domain/executed.d.ts +325 -0
  14. package/dist/domain/executed.d.ts.map +1 -0
  15. package/dist/domain/executed.js +253 -0
  16. package/dist/domain/executed.js.map +1 -0
  17. package/dist/domain/journal-entry.d.ts +468 -0
  18. package/dist/domain/journal-entry.d.ts.map +1 -0
  19. package/dist/domain/journal-entry.js +63 -0
  20. package/dist/domain/journal-entry.js.map +1 -0
  21. package/dist/domain/schemas.d.ts +950 -0
  22. package/dist/domain/schemas.d.ts.map +1 -0
  23. package/dist/domain/schemas.js +571 -0
  24. package/dist/domain/schemas.js.map +1 -0
  25. package/dist/domain/sui-schema.d.ts +12 -0
  26. package/dist/domain/sui-schema.d.ts.map +1 -0
  27. package/dist/domain/sui-schema.js +12 -0
  28. package/dist/domain/sui-schema.js.map +1 -0
  29. package/dist/extension.d.ts +7 -0
  30. package/dist/extension.d.ts.map +1 -0
  31. package/dist/extension.js +7 -0
  32. package/dist/extension.js.map +1 -0
  33. package/dist/index.d.ts +31 -0
  34. package/dist/index.d.ts.map +1 -0
  35. package/dist/index.js +31 -0
  36. package/dist/index.js.map +1 -0
  37. package/dist/internal.d.ts +18 -0
  38. package/dist/internal.d.ts.map +1 -0
  39. package/dist/internal.js +18 -0
  40. package/dist/internal.js.map +1 -0
  41. package/dist/journal.d.ts +51 -0
  42. package/dist/journal.d.ts.map +1 -0
  43. package/dist/journal.js +18 -0
  44. package/dist/journal.js.map +1 -0
  45. package/dist/script.d.ts +7 -0
  46. package/dist/script.d.ts.map +1 -0
  47. package/dist/script.js +7 -0
  48. package/dist/script.js.map +1 -0
  49. package/dist/services/Journal.d.ts +76 -0
  50. package/dist/services/Journal.d.ts.map +1 -0
  51. package/dist/services/Journal.js +70 -0
  52. package/dist/services/Journal.js.map +1 -0
  53. package/dist/services/JournalKeyValueStore.d.ts +73 -0
  54. package/dist/services/JournalKeyValueStore.d.ts.map +1 -0
  55. package/dist/services/JournalKeyValueStore.js +155 -0
  56. package/dist/services/JournalKeyValueStore.js.map +1 -0
  57. package/dist/services/Script.d.ts +210 -0
  58. package/dist/services/Script.d.ts.map +1 -0
  59. package/dist/services/Script.js +441 -0
  60. package/dist/services/Script.js.map +1 -0
  61. package/dist/services/Signer.d.ts +132 -0
  62. package/dist/services/Signer.d.ts.map +1 -0
  63. package/dist/services/Signer.js +158 -0
  64. package/dist/services/Signer.js.map +1 -0
  65. package/dist/services/SubmitConfig.d.ts +175 -0
  66. package/dist/services/SubmitConfig.d.ts.map +1 -0
  67. package/dist/services/SubmitConfig.js +52 -0
  68. package/dist/services/SubmitConfig.js.map +1 -0
  69. package/dist/services/Sui.d.ts +295 -0
  70. package/dist/services/Sui.d.ts.map +1 -0
  71. package/dist/services/Sui.js +414 -0
  72. package/dist/services/Sui.js.map +1 -0
  73. package/dist/services/SuiCore.d.ts +227 -0
  74. package/dist/services/SuiCore.d.ts.map +1 -0
  75. package/dist/services/SuiCore.js +400 -0
  76. package/dist/services/SuiCore.js.map +1 -0
  77. package/dist/services/SuiCoreFake.d.ts +278 -0
  78. package/dist/services/SuiCoreFake.d.ts.map +1 -0
  79. package/dist/services/SuiCoreFake.js +1003 -0
  80. package/dist/services/SuiCoreFake.js.map +1 -0
  81. package/dist/services/SuiExtension.d.ts +208 -0
  82. package/dist/services/SuiExtension.d.ts.map +1 -0
  83. package/dist/services/SuiExtension.js +355 -0
  84. package/dist/services/SuiExtension.js.map +1 -0
  85. package/dist/services/SuiGraphQL.d.ts +98 -0
  86. package/dist/services/SuiGraphQL.d.ts.map +1 -0
  87. package/dist/services/SuiGraphQL.js +118 -0
  88. package/dist/services/SuiGraphQL.js.map +1 -0
  89. package/dist/services/Tx.d.ts +687 -0
  90. package/dist/services/Tx.d.ts.map +1 -0
  91. package/dist/services/Tx.js +1224 -0
  92. package/dist/services/Tx.js.map +1 -0
  93. package/dist/testing.d.ts +88 -0
  94. package/dist/testing.d.ts.map +1 -0
  95. package/dist/testing.js +163 -0
  96. package/dist/testing.js.map +1 -0
  97. package/dist/tx.d.ts +24 -0
  98. package/dist/tx.d.ts.map +1 -0
  99. package/dist/tx.js +24 -0
  100. package/dist/tx.js.map +1 -0
  101. package/docs/extensions.md +1685 -0
  102. package/examples/extension-template/README.md +170 -0
  103. package/examples/extension-template/package.json +44 -0
  104. package/examples/extension-template/scripts/check-package.ts +145 -0
  105. package/examples/extension-template/src/Escrow.ts +445 -0
  106. package/examples/extension-template/src/Platform.ts +136 -0
  107. package/examples/extension-template/src/errors.ts +61 -0
  108. package/examples/extension-template/src/extension.ts +63 -0
  109. package/examples/extension-template/src/index.ts +34 -0
  110. package/examples/extension-template/src/schema.ts +158 -0
  111. package/examples/extension-template/src/upstream.ts +66 -0
  112. package/examples/extension-template/test/escrow.test.ts +559 -0
  113. package/examples/extension-template/tsconfig.build.json +26 -0
  114. package/examples/extension-template/tsconfig.json +35 -0
  115. package/package.json +87 -0
@@ -0,0 +1,687 @@
1
+ import { Transaction } from "@mysten/sui/transactions";
2
+ import { Effect, Schema } from "effect";
3
+ import { BuildError, ExecutionFailed, JournalError, NotApplied, PolicyDenied, SigningError, SimulationFailed, SubmissionUnknown, TransportError } from "../domain/errors.ts";
4
+ import { Executed } from "../domain/executed.ts";
5
+ import { Digest, SignedTransaction, SuiAddress } from "../domain/schemas.ts";
6
+ import type { Signer } from "./Signer.ts";
7
+ import type { Recipe } from "./Sui.ts";
8
+ import { Sui } from "./Sui.ts";
9
+ /** A transaction built into bytes, with the expiration the builder settled on. */
10
+ export type { Built } from "../domain/schemas.ts";
11
+ /** Signed bytes: everything `executeTransaction` needs, plus what `reconcile` needs. */
12
+ export type Signed = SignedTransaction;
13
+ /** The schema of {@link Signed}. */
14
+ export declare const Signed: Schema.Struct<{
15
+ readonly digest: Schema.brand<Schema.String, "Digest">;
16
+ readonly bytes: Schema.Uint8ArrayFromBase64;
17
+ readonly signatures: Schema.$Array<Schema.brand<Schema.String, "Signature">>;
18
+ readonly sender: Schema.brand<Schema.decodeTo<Schema.toType<Schema.String>, Schema.String, never, never>, "SuiAddress">;
19
+ readonly expiration: Schema.optional<Schema.toTaggedUnion<"$kind", readonly [Schema.Struct<{
20
+ readonly $kind: Schema.Literal<"None">;
21
+ readonly None: Schema.Literal<true>;
22
+ }>, Schema.Struct<{
23
+ readonly $kind: Schema.Literal<"Epoch">;
24
+ readonly Epoch: Schema.decodeTo<Schema.BigInt, Schema.Union<readonly [Schema.String, Schema.Number]>, never, never>;
25
+ }>, Schema.Struct<{
26
+ readonly $kind: Schema.Literal<"ValidDuring">;
27
+ readonly ValidDuring: Schema.Struct<{
28
+ readonly minEpoch: Schema.NullOr<Schema.decodeTo<Schema.BigInt, Schema.Union<readonly [Schema.String, Schema.Number]>, never, never>>;
29
+ readonly maxEpoch: Schema.NullOr<Schema.decodeTo<Schema.BigInt, Schema.Union<readonly [Schema.String, Schema.Number]>, never, never>>;
30
+ readonly minTimestamp: Schema.NullOr<Schema.decodeTo<Schema.BigInt, Schema.Union<readonly [Schema.String, Schema.Number]>, never, never>>;
31
+ readonly maxTimestamp: Schema.NullOr<Schema.decodeTo<Schema.BigInt, Schema.Union<readonly [Schema.String, Schema.Number]>, never, never>>;
32
+ readonly chain: Schema.String;
33
+ readonly nonce: Schema.Number;
34
+ }>;
35
+ }>, Schema.Struct<{
36
+ readonly $kind: Schema.Literal<"Validity">;
37
+ readonly Validity: Schema.Struct<{
38
+ readonly allowedProposers: Schema.NullOr<Schema.Struct<{
39
+ readonly epoch: Schema.decodeTo<Schema.BigInt, Schema.Union<readonly [Schema.String, Schema.Number]>, never, never>;
40
+ readonly proposers: Schema.$Array<Schema.Number>;
41
+ }>>;
42
+ readonly minEpoch: Schema.NullOr<Schema.decodeTo<Schema.BigInt, Schema.Union<readonly [Schema.String, Schema.Number]>, never, never>>;
43
+ readonly maxEpoch: Schema.NullOr<Schema.decodeTo<Schema.BigInt, Schema.Union<readonly [Schema.String, Schema.Number]>, never, never>>;
44
+ readonly minTimestamp: Schema.NullOr<Schema.decodeTo<Schema.BigInt, Schema.Union<readonly [Schema.String, Schema.Number]>, never, never>>;
45
+ readonly maxTimestamp: Schema.NullOr<Schema.decodeTo<Schema.BigInt, Schema.Union<readonly [Schema.String, Schema.Number]>, never, never>>;
46
+ readonly chain: Schema.String;
47
+ readonly nonce: Schema.Number;
48
+ }>;
49
+ }>]>>;
50
+ readonly chain: Schema.optional<Schema.String>;
51
+ }>;
52
+ /** What `Tx.reconcile` can be asked about. */
53
+ export type ReconcileInput = Digest | Signed | SubmissionUnknown;
54
+ /**
55
+ * Everything {@link submit} can fail with, as one name.
56
+ *
57
+ * An extension that wraps a submission spells its own errors plus this, rather
58
+ * than repeating four tags that will grow with the taxonomy.
59
+ */
60
+ export type SubmitError = ExecutionFailed | NotApplied | SubmissionUnknown | JournalError;
61
+ /**
62
+ * Everything {@link run} can fail with, as one name: {@link SubmitError} plus
63
+ * what building, preflighting and signing can produce.
64
+ */
65
+ export type RunError = BuildError | SimulationFailed | PolicyDenied | SigningError | SubmitError | TransportError;
66
+ /** What one entry of `Tx.reconcileAll` settled to. */
67
+ export type Reconciled = Executed | ExecutionFailed | NotApplied | SubmissionUnknown;
68
+ /**
69
+ * Builds a transaction into signable bytes.
70
+ *
71
+ * **Building always simulates.** On gRPC the SDK's resolve plugin simulates
72
+ * with checks enabled to choose the gas budget, and an execution failure there
73
+ * arrives as `SimulationFailed`. That costs nothing extra — but the resolver
74
+ * returns early for a transaction that was **already fully resolved** (every
75
+ * input resolved, gas price, budget and payment set), and then nothing
76
+ * simulates at all. `Tx.build` detects that case and runs one explicit
77
+ * `simulateTransaction` with checks enabled, so simulate-before-submit holds
78
+ * for every transaction: it costs nothing extra when the SDK had to resolve,
79
+ * and one call otherwise.
80
+ *
81
+ * An interrupted build cancels the request it started: the SDK is handed a
82
+ * client whose Core calls carry the Effect's `AbortSignal`.
83
+ *
84
+ * When the recipe set no expiration, `SubmitConfig.expiration` decides one.
85
+ * The default, `ValidDuring`, bounds the transaction to the **current epoch and
86
+ * the next**, names the chain (bytes signed for testnet cannot land on mainnet)
87
+ * and carries a `u32` nonce from `SubmitConfig.nonce`. There is **no
88
+ * wall-clock bound** unless `SubmitConfig.validFor` asks for one: no Sui
89
+ * network accepts a timestamp expiration yet, and a node refuses any
90
+ * transaction carrying one. The expiration that ends up in the bytes is
91
+ * recorded on the result, because it is what `Tx.reconcile` needs later to
92
+ * prove a transaction can no longer land.
93
+ *
94
+ * `Tx.build` takes no sender lock; `Tx.run` is what holds one from build
95
+ * through submit. Called on its own, two concurrent builds for one address can
96
+ * pick the same gas coin.
97
+ *
98
+ * Fails with: `BuildError` (the recipe threw, an input could not be resolved,
99
+ * or the budget the node chose is over `SubmitConfig.maxGasBudget`),
100
+ * `SimulationFailed` (the transaction would abort on chain),
101
+ * `TransportError`.
102
+ */
103
+ export declare const build: (input: Transaction | Recipe, opts: {
104
+ readonly sender: SuiAddress;
105
+ readonly gasOwner?: SuiAddress;
106
+ }) => Effect.Effect<{
107
+ readonly digest: string & import("effect/Brand").Brand<"Digest">;
108
+ readonly sender: string & import("effect/Brand").Brand<"SuiAddress">;
109
+ readonly bytes: Uint8Array<ArrayBufferLike>;
110
+ readonly chain?: string | undefined;
111
+ readonly expiration?: {
112
+ readonly $kind: "None";
113
+ readonly None: true;
114
+ } | {
115
+ readonly $kind: "Epoch";
116
+ readonly Epoch: bigint;
117
+ } | {
118
+ readonly $kind: "ValidDuring";
119
+ readonly ValidDuring: {
120
+ readonly minEpoch: bigint | null;
121
+ readonly maxEpoch: bigint | null;
122
+ readonly minTimestamp: bigint | null;
123
+ readonly maxTimestamp: bigint | null;
124
+ readonly chain: string;
125
+ readonly nonce: number;
126
+ };
127
+ } | {
128
+ readonly $kind: "Validity";
129
+ readonly Validity: {
130
+ readonly allowedProposers: {
131
+ readonly epoch: bigint;
132
+ readonly proposers: readonly number[];
133
+ } | null;
134
+ readonly minEpoch: bigint | null;
135
+ readonly maxEpoch: bigint | null;
136
+ readonly minTimestamp: bigint | null;
137
+ readonly maxTimestamp: bigint | null;
138
+ readonly chain: string;
139
+ readonly nonce: number;
140
+ };
141
+ } | undefined;
142
+ readonly gasOwner?: (string & import("effect/Brand").Brand<"SuiAddress">) | undefined;
143
+ }, TransportError | SimulationFailed | BuildError, Sui>;
144
+ /**
145
+ * Signs built bytes.
146
+ *
147
+ * The signer's address must be the transaction's sender or, for a sponsored
148
+ * transaction, its gas owner; anything else is a `SigningError` rather than a
149
+ * rejection at execution time. A `Signer.remote` therefore has to report the
150
+ * address it signs as truthfully.
151
+ *
152
+ * Fails with: `SigningError`.
153
+ */
154
+ export declare const sign: (built: {
155
+ readonly digest: string & import("effect/Brand").Brand<"Digest">;
156
+ readonly sender: string & import("effect/Brand").Brand<"SuiAddress">;
157
+ readonly bytes: Uint8Array<ArrayBufferLike>;
158
+ readonly chain?: string | undefined;
159
+ readonly expiration?: {
160
+ readonly $kind: "None";
161
+ readonly None: true;
162
+ } | {
163
+ readonly $kind: "Epoch";
164
+ readonly Epoch: bigint;
165
+ } | {
166
+ readonly $kind: "ValidDuring";
167
+ readonly ValidDuring: {
168
+ readonly minEpoch: bigint | null;
169
+ readonly maxEpoch: bigint | null;
170
+ readonly minTimestamp: bigint | null;
171
+ readonly maxTimestamp: bigint | null;
172
+ readonly chain: string;
173
+ readonly nonce: number;
174
+ };
175
+ } | {
176
+ readonly $kind: "Validity";
177
+ readonly Validity: {
178
+ readonly allowedProposers: {
179
+ readonly epoch: bigint;
180
+ readonly proposers: readonly number[];
181
+ } | null;
182
+ readonly minEpoch: bigint | null;
183
+ readonly maxEpoch: bigint | null;
184
+ readonly minTimestamp: bigint | null;
185
+ readonly maxTimestamp: bigint | null;
186
+ readonly chain: string;
187
+ readonly nonce: number;
188
+ };
189
+ } | undefined;
190
+ readonly gasOwner?: (string & import("effect/Brand").Brand<"SuiAddress">) | undefined;
191
+ }, signer: Signer) => Effect.Effect<{
192
+ readonly digest: string & import("effect/Brand").Brand<"Digest">;
193
+ readonly sender: string & import("effect/Brand").Brand<"SuiAddress">;
194
+ readonly signatures: readonly (string & import("effect/Brand").Brand<"Signature">)[];
195
+ readonly bytes: Uint8Array<ArrayBufferLike>;
196
+ readonly chain?: string | undefined;
197
+ readonly expiration?: {
198
+ readonly $kind: "None";
199
+ readonly None: true;
200
+ } | {
201
+ readonly $kind: "Epoch";
202
+ readonly Epoch: bigint;
203
+ } | {
204
+ readonly $kind: "ValidDuring";
205
+ readonly ValidDuring: {
206
+ readonly minEpoch: bigint | null;
207
+ readonly maxEpoch: bigint | null;
208
+ readonly minTimestamp: bigint | null;
209
+ readonly maxTimestamp: bigint | null;
210
+ readonly chain: string;
211
+ readonly nonce: number;
212
+ };
213
+ } | {
214
+ readonly $kind: "Validity";
215
+ readonly Validity: {
216
+ readonly allowedProposers: {
217
+ readonly epoch: bigint;
218
+ readonly proposers: readonly number[];
219
+ } | null;
220
+ readonly minEpoch: bigint | null;
221
+ readonly maxEpoch: bigint | null;
222
+ readonly minTimestamp: bigint | null;
223
+ readonly maxTimestamp: bigint | null;
224
+ readonly chain: string;
225
+ readonly nonce: number;
226
+ };
227
+ } | undefined;
228
+ }, SigningError, never>;
229
+ /**
230
+ * Adds one more signature to already signed bytes, for a sponsored or
231
+ * multi-party transaction. The bytes are untouched, so both parties sign
232
+ * exactly the same transaction.
233
+ *
234
+ * As in {@link sign}, the co-signer's address must be the sender or the gas
235
+ * owner named in the bytes.
236
+ *
237
+ * Fails with: `SigningError`.
238
+ */
239
+ export declare const cosign: (signed: {
240
+ readonly digest: string & import("effect/Brand").Brand<"Digest">;
241
+ readonly sender: string & import("effect/Brand").Brand<"SuiAddress">;
242
+ readonly signatures: readonly (string & import("effect/Brand").Brand<"Signature">)[];
243
+ readonly bytes: Uint8Array<ArrayBufferLike>;
244
+ readonly chain?: string | undefined;
245
+ readonly expiration?: {
246
+ readonly $kind: "None";
247
+ readonly None: true;
248
+ } | {
249
+ readonly $kind: "Epoch";
250
+ readonly Epoch: bigint;
251
+ } | {
252
+ readonly $kind: "ValidDuring";
253
+ readonly ValidDuring: {
254
+ readonly minEpoch: bigint | null;
255
+ readonly maxEpoch: bigint | null;
256
+ readonly minTimestamp: bigint | null;
257
+ readonly maxTimestamp: bigint | null;
258
+ readonly chain: string;
259
+ readonly nonce: number;
260
+ };
261
+ } | {
262
+ readonly $kind: "Validity";
263
+ readonly Validity: {
264
+ readonly allowedProposers: {
265
+ readonly epoch: bigint;
266
+ readonly proposers: readonly number[];
267
+ } | null;
268
+ readonly minEpoch: bigint | null;
269
+ readonly maxEpoch: bigint | null;
270
+ readonly minTimestamp: bigint | null;
271
+ readonly maxTimestamp: bigint | null;
272
+ readonly chain: string;
273
+ readonly nonce: number;
274
+ };
275
+ } | undefined;
276
+ }, signer: Signer) => Effect.Effect<{
277
+ readonly digest: string & import("effect/Brand").Brand<"Digest">;
278
+ readonly sender: string & import("effect/Brand").Brand<"SuiAddress">;
279
+ readonly signatures: readonly (string & import("effect/Brand").Brand<"Signature">)[];
280
+ readonly bytes: Uint8Array<ArrayBufferLike>;
281
+ readonly chain?: string | undefined;
282
+ readonly expiration?: {
283
+ readonly $kind: "None";
284
+ readonly None: true;
285
+ } | {
286
+ readonly $kind: "Epoch";
287
+ readonly Epoch: bigint;
288
+ } | {
289
+ readonly $kind: "ValidDuring";
290
+ readonly ValidDuring: {
291
+ readonly minEpoch: bigint | null;
292
+ readonly maxEpoch: bigint | null;
293
+ readonly minTimestamp: bigint | null;
294
+ readonly maxTimestamp: bigint | null;
295
+ readonly chain: string;
296
+ readonly nonce: number;
297
+ };
298
+ } | {
299
+ readonly $kind: "Validity";
300
+ readonly Validity: {
301
+ readonly allowedProposers: {
302
+ readonly epoch: bigint;
303
+ readonly proposers: readonly number[];
304
+ } | null;
305
+ readonly minEpoch: bigint | null;
306
+ readonly maxEpoch: bigint | null;
307
+ readonly minTimestamp: bigint | null;
308
+ readonly maxTimestamp: bigint | null;
309
+ readonly chain: string;
310
+ readonly nonce: number;
311
+ };
312
+ } | undefined;
313
+ }, SigningError, never>;
314
+ /**
315
+ * Turns a recipe into a sponsored one: the sender owns the transaction, the
316
+ * gas owner pays, and gas comes from the sponsor's address balance rather than
317
+ * from coin objects, so the two parties never have to agree on a gas coin and
318
+ * can sign in either order.
319
+ *
320
+ * Never fails; the recipe it returns throws only if the recipe it wraps does,
321
+ * which `Tx.build` reports as `BuildError`.
322
+ */
323
+ export declare const sponsored: (opts: {
324
+ readonly sender: SuiAddress;
325
+ readonly gasOwner: SuiAddress;
326
+ }) => (recipe: Recipe) => Recipe;
327
+ /**
328
+ * Sends signed bytes, and does not stop caring until it knows what happened.
329
+ *
330
+ * Before the first `executeTransaction` it writes a `Signed` journal entry, so
331
+ * a process that dies mid-flight leaves a record of bytes that may be on the
332
+ * wire. A retryable transport failure or a timeout re-sends the identical bytes
333
+ * on `SubmitConfig.resubmit`; nothing is ever rebuilt, so a retry can only land
334
+ * the transaction that was already signed. When the retries run out it runs
335
+ * `Tx.reconcile`, which either finds the transaction, proves it never applied,
336
+ * or says it does not know.
337
+ *
338
+ * `TransportError` never escapes: once bytes may have been sent, "the network
339
+ * was unreachable" is not an answer a caller can act on, so it becomes
340
+ * `SubmissionUnknown` carrying the signed bytes.
341
+ *
342
+ * `JournalError` can only come from the `Signed` write, before anything has
343
+ * been sent. Once the network has answered, a journal write that fails is
344
+ * logged with `Effect.logError` and the answer stands, because "the journal is
345
+ * broken" is not a thing a caller can act on and reporting it in place of a
346
+ * charged `ExecutionFailed` would invite a second submission.
347
+ *
348
+ * Fails with: `ExecutionFailed` (applied on chain and failed; gas was charged),
349
+ * `NotApplied` (provably never applied), `SubmissionUnknown` (the outcome is
350
+ * not known and the bytes are in the error), `JournalError` (only before the
351
+ * first send).
352
+ */
353
+ export declare const submit: (signed: Signed) => Effect.Effect<Executed, SubmitError, Sui>;
354
+ /**
355
+ * Finds out what happened to a transaction that was sent but never answered
356
+ * for.
357
+ *
358
+ * A transaction the node knows is `Executed`, or `ExecutionFailed` when it
359
+ * applied and aborted. A transaction the node does not know is only ever
360
+ * `NotApplied` on evidence, and there are exactly two kinds:
361
+ *
362
+ * - `"expired"`, under an **ordered and repeated** rule, because a closed
363
+ * expiration window proves only that the bytes cannot execute *later*, not
364
+ * that they did not execute *earlier*, and a transaction can execute between
365
+ * a lookup and an expiry check. So: the window must be observed closed, then
366
+ * `getTransaction` must miss, then — after `SubmitConfig.reconcileRecheck`
367
+ * (two seconds by default, through the `Clock`) — both must hold again. Any
368
+ * other order, or a single observation, is `SubmissionUnknown`. Set
369
+ * `SubmitConfig.expiryEvidence: "never"` to disable the rule entirely, which
370
+ * is what a deployment behind a mixed-node load balancer wants. The residual
371
+ * risk is a node whose transaction index lags its epoch view;
372
+ * - `"inputConsumed"` when the transaction that last mutated a pinned object is
373
+ * a **different** one **and its own effects report `inputVersion` equal to
374
+ * the version these bytes pinned**, so those exact bytes can never execute
375
+ * again.
376
+ *
377
+ * An input that merely advanced is not evidence: the transaction being
378
+ * reconciled is itself the likeliest thing to have advanced it, and calling
379
+ * that `NotApplied` would tell the documented retry idiom to execute the
380
+ * caller's intent a second time. When the live object names *our* digest the
381
+ * transaction applied and `getTransaction` is asked again; when the consuming
382
+ * transaction took a **later** version than ours — which is the common case,
383
+ * because Sui stamps every output with the transaction's Lamport version and
384
+ * the object "one version on" from ours usually never existed — nothing is
385
+ * proven and the answer is `SubmissionUnknown`, which carries the bytes so a
386
+ * later process, or a person, can settle it. Every pinned reference is tried
387
+ * before that answer is given.
388
+ *
389
+ * **Chain identity is checked before anything is asked.** Bytes built for one
390
+ * chain must never be declared expired by another chain's epoch, which a
391
+ * process-wide journal holding two networks' submissions makes easy to do. A
392
+ * mismatch is `SubmissionUnknown` naming both chains.
393
+ *
394
+ * **No `TransportError` escapes.** A recovery read that fails says nothing
395
+ * about whether the transaction applied, and `SuiError.outcome` puts
396
+ * `TransportError` on `"not_applied"` — which would tell a wrapper to retry a
397
+ * submission whose outcome is genuinely unknown. Every read failure here
398
+ * becomes `SubmissionUnknown` carrying the digest, the bytes and the cause. The
399
+ * tag stays in the signature so the union does not shrink under callers.
400
+ *
401
+ * Given only a `Digest` there can be no evidence, so an unknown transaction is
402
+ * always `SubmissionUnknown`. Pass the `Signed` bytes (or the
403
+ * `SubmissionUnknown` that carries them) to get the evidence rules.
404
+ *
405
+ * Fails with: `ExecutionFailed`, `NotApplied`, `SubmissionUnknown`,
406
+ * `TransportError`.
407
+ */
408
+ export declare const reconcile: (input: ReconcileInput) => Effect.Effect<Executed, TransportError | ExecutionFailed | SubmissionUnknown | NotApplied, Sui>;
409
+ /**
410
+ * Build, preflight, sign and submit, with the sender lock held throughout.
411
+ *
412
+ * Gas coins are chosen during build, so two transactions from one address that
413
+ * overlap can pick the same coin and one of them will fail on chain. `Tx.run`
414
+ * holds the sender lock from build through submit, which is the whole reason to
415
+ * prefer it over calling the steps separately.
416
+ *
417
+ * The address that matters is the one whose coins are being spent, which is the
418
+ * **gas owner** when there is one: two sponsored runs for different senders
419
+ * paid by one sponsor are exactly the case that picks the same coin twice. When
420
+ * sender and gas owner differ, both locks are held, in ascending address order
421
+ * — a fixed order, so two runs that each need the same pair cannot deadlock by
422
+ * taking them the other way round.
423
+ *
424
+ * When `SubmitConfig.preflight` is set it costs one extra simulate, and is
425
+ * where spend limits and target policies refuse a transaction before anything
426
+ * is signed.
427
+ *
428
+ * **A sponsored run needs both signatures.** A transaction whose gas owner is
429
+ * not its sender is signed by *both* parties; one signature is bytes a
430
+ * validator rejects. So when `opts.gasOwner` differs from the signer's address
431
+ * — or when the recipe itself set a different gas owner, which `Tx.sponsored`
432
+ * does — `opts.sponsor` is required and co-signs the same bytes. Without it
433
+ * `Tx.run` fails with `SigningError` naming the address whose signature is
434
+ * missing, before anything is built when the gas owner was given as an option
435
+ * and immediately after the build when it came out of the recipe. Use the
436
+ * explicit lifecycle (`Tx.build`, `Tx.sign`, `Tx.cosign`, `Tx.submit`) when the
437
+ * two parties cannot both sign in one process.
438
+ *
439
+ * Fails with: `BuildError`, `SimulationFailed`, `PolicyDenied`, `SigningError`,
440
+ * `ExecutionFailed`, `NotApplied`, `SubmissionUnknown`, `JournalError`,
441
+ * `TransportError` (from the build reads; once bytes are sent, transport
442
+ * failures become `SubmissionUnknown`).
443
+ */
444
+ export declare const run: (recipe: Transaction | Recipe, opts: {
445
+ readonly signer: Signer;
446
+ readonly gasOwner?: SuiAddress;
447
+ /**
448
+ * The gas owner's signer, for a sponsored transaction. Required whenever
449
+ * the bytes name a gas owner that is not the sender.
450
+ */
451
+ readonly sponsor?: Signer;
452
+ }) => Effect.Effect<Executed, TransportError | SimulationFailed | ExecutionFailed | SubmissionUnknown | NotApplied | SigningError | BuildError | PolicyDenied | JournalError, Sui>;
453
+ /**
454
+ * Settles every unresolved entry in the journal: the explicit startup call a
455
+ * long-lived application makes after building a durable `Journal`.
456
+ *
457
+ * Nothing here fails per entry: each one settles to an `Executed`, an
458
+ * `ExecutionFailed`, a `NotApplied` or a `SubmissionUnknown`, in the order the
459
+ * journal listed them, and the journal is updated to match. Every settled entry
460
+ * gets the same evidence rules `Tx.reconcile` applies — the ordered, repeated
461
+ * expiry rule, the chain-identity guard and the versioned consumer check — so a
462
+ * startup never reports a transaction that applied as `NotApplied`, and a
463
+ * recovery read that fails becomes that entry's `SubmissionUnknown` rather than
464
+ * escaping as a `TransportError` the taxonomy would call "not applied".
465
+ *
466
+ * The whole call fails only if the journal itself cannot be **read**: a write
467
+ * that fails after an entry has been settled is logged and the answer stands,
468
+ * the same rule `Tx.submit` follows.
469
+ *
470
+ * Fails with: `JournalError`, `TransportError`.
471
+ */
472
+ export declare const reconcileAll: () => Effect.Effect<readonly Reconciled[], TransportError | JournalError, Sui>;
473
+ /**
474
+ * The lifecycle, namespaced the way the spec spells it: `Tx.build`, `Tx.sign`,
475
+ * `Tx.cosign`, `Tx.sponsored`, `Tx.submit`, `Tx.reconcile`, `Tx.run`,
476
+ * `Tx.reconcileAll`.
477
+ */
478
+ export declare const Tx: {
479
+ readonly build: (input: Transaction | Recipe, opts: {
480
+ readonly sender: SuiAddress;
481
+ readonly gasOwner?: SuiAddress;
482
+ }) => Effect.Effect<{
483
+ readonly digest: string & import("effect/Brand").Brand<"Digest">;
484
+ readonly sender: string & import("effect/Brand").Brand<"SuiAddress">;
485
+ readonly bytes: Uint8Array<ArrayBufferLike>;
486
+ readonly chain?: string | undefined;
487
+ readonly expiration?: {
488
+ readonly $kind: "None";
489
+ readonly None: true;
490
+ } | {
491
+ readonly $kind: "Epoch";
492
+ readonly Epoch: bigint;
493
+ } | {
494
+ readonly $kind: "ValidDuring";
495
+ readonly ValidDuring: {
496
+ readonly minEpoch: bigint | null;
497
+ readonly maxEpoch: bigint | null;
498
+ readonly minTimestamp: bigint | null;
499
+ readonly maxTimestamp: bigint | null;
500
+ readonly chain: string;
501
+ readonly nonce: number;
502
+ };
503
+ } | {
504
+ readonly $kind: "Validity";
505
+ readonly Validity: {
506
+ readonly allowedProposers: {
507
+ readonly epoch: bigint;
508
+ readonly proposers: readonly number[];
509
+ } | null;
510
+ readonly minEpoch: bigint | null;
511
+ readonly maxEpoch: bigint | null;
512
+ readonly minTimestamp: bigint | null;
513
+ readonly maxTimestamp: bigint | null;
514
+ readonly chain: string;
515
+ readonly nonce: number;
516
+ };
517
+ } | undefined;
518
+ readonly gasOwner?: (string & import("effect/Brand").Brand<"SuiAddress">) | undefined;
519
+ }, TransportError | SimulationFailed | BuildError, Sui>;
520
+ readonly sign: (built: {
521
+ readonly digest: string & import("effect/Brand").Brand<"Digest">;
522
+ readonly sender: string & import("effect/Brand").Brand<"SuiAddress">;
523
+ readonly bytes: Uint8Array<ArrayBufferLike>;
524
+ readonly chain?: string | undefined;
525
+ readonly expiration?: {
526
+ readonly $kind: "None";
527
+ readonly None: true;
528
+ } | {
529
+ readonly $kind: "Epoch";
530
+ readonly Epoch: bigint;
531
+ } | {
532
+ readonly $kind: "ValidDuring";
533
+ readonly ValidDuring: {
534
+ readonly minEpoch: bigint | null;
535
+ readonly maxEpoch: bigint | null;
536
+ readonly minTimestamp: bigint | null;
537
+ readonly maxTimestamp: bigint | null;
538
+ readonly chain: string;
539
+ readonly nonce: number;
540
+ };
541
+ } | {
542
+ readonly $kind: "Validity";
543
+ readonly Validity: {
544
+ readonly allowedProposers: {
545
+ readonly epoch: bigint;
546
+ readonly proposers: readonly number[];
547
+ } | null;
548
+ readonly minEpoch: bigint | null;
549
+ readonly maxEpoch: bigint | null;
550
+ readonly minTimestamp: bigint | null;
551
+ readonly maxTimestamp: bigint | null;
552
+ readonly chain: string;
553
+ readonly nonce: number;
554
+ };
555
+ } | undefined;
556
+ readonly gasOwner?: (string & import("effect/Brand").Brand<"SuiAddress">) | undefined;
557
+ }, signer: Signer) => Effect.Effect<{
558
+ readonly digest: string & import("effect/Brand").Brand<"Digest">;
559
+ readonly sender: string & import("effect/Brand").Brand<"SuiAddress">;
560
+ readonly signatures: readonly (string & import("effect/Brand").Brand<"Signature">)[];
561
+ readonly bytes: Uint8Array<ArrayBufferLike>;
562
+ readonly chain?: string | undefined;
563
+ readonly expiration?: {
564
+ readonly $kind: "None";
565
+ readonly None: true;
566
+ } | {
567
+ readonly $kind: "Epoch";
568
+ readonly Epoch: bigint;
569
+ } | {
570
+ readonly $kind: "ValidDuring";
571
+ readonly ValidDuring: {
572
+ readonly minEpoch: bigint | null;
573
+ readonly maxEpoch: bigint | null;
574
+ readonly minTimestamp: bigint | null;
575
+ readonly maxTimestamp: bigint | null;
576
+ readonly chain: string;
577
+ readonly nonce: number;
578
+ };
579
+ } | {
580
+ readonly $kind: "Validity";
581
+ readonly Validity: {
582
+ readonly allowedProposers: {
583
+ readonly epoch: bigint;
584
+ readonly proposers: readonly number[];
585
+ } | null;
586
+ readonly minEpoch: bigint | null;
587
+ readonly maxEpoch: bigint | null;
588
+ readonly minTimestamp: bigint | null;
589
+ readonly maxTimestamp: bigint | null;
590
+ readonly chain: string;
591
+ readonly nonce: number;
592
+ };
593
+ } | undefined;
594
+ }, SigningError, never>;
595
+ readonly cosign: (signed: {
596
+ readonly digest: string & import("effect/Brand").Brand<"Digest">;
597
+ readonly sender: string & import("effect/Brand").Brand<"SuiAddress">;
598
+ readonly signatures: readonly (string & import("effect/Brand").Brand<"Signature">)[];
599
+ readonly bytes: Uint8Array<ArrayBufferLike>;
600
+ readonly chain?: string | undefined;
601
+ readonly expiration?: {
602
+ readonly $kind: "None";
603
+ readonly None: true;
604
+ } | {
605
+ readonly $kind: "Epoch";
606
+ readonly Epoch: bigint;
607
+ } | {
608
+ readonly $kind: "ValidDuring";
609
+ readonly ValidDuring: {
610
+ readonly minEpoch: bigint | null;
611
+ readonly maxEpoch: bigint | null;
612
+ readonly minTimestamp: bigint | null;
613
+ readonly maxTimestamp: bigint | null;
614
+ readonly chain: string;
615
+ readonly nonce: number;
616
+ };
617
+ } | {
618
+ readonly $kind: "Validity";
619
+ readonly Validity: {
620
+ readonly allowedProposers: {
621
+ readonly epoch: bigint;
622
+ readonly proposers: readonly number[];
623
+ } | null;
624
+ readonly minEpoch: bigint | null;
625
+ readonly maxEpoch: bigint | null;
626
+ readonly minTimestamp: bigint | null;
627
+ readonly maxTimestamp: bigint | null;
628
+ readonly chain: string;
629
+ readonly nonce: number;
630
+ };
631
+ } | undefined;
632
+ }, signer: Signer) => Effect.Effect<{
633
+ readonly digest: string & import("effect/Brand").Brand<"Digest">;
634
+ readonly sender: string & import("effect/Brand").Brand<"SuiAddress">;
635
+ readonly signatures: readonly (string & import("effect/Brand").Brand<"Signature">)[];
636
+ readonly bytes: Uint8Array<ArrayBufferLike>;
637
+ readonly chain?: string | undefined;
638
+ readonly expiration?: {
639
+ readonly $kind: "None";
640
+ readonly None: true;
641
+ } | {
642
+ readonly $kind: "Epoch";
643
+ readonly Epoch: bigint;
644
+ } | {
645
+ readonly $kind: "ValidDuring";
646
+ readonly ValidDuring: {
647
+ readonly minEpoch: bigint | null;
648
+ readonly maxEpoch: bigint | null;
649
+ readonly minTimestamp: bigint | null;
650
+ readonly maxTimestamp: bigint | null;
651
+ readonly chain: string;
652
+ readonly nonce: number;
653
+ };
654
+ } | {
655
+ readonly $kind: "Validity";
656
+ readonly Validity: {
657
+ readonly allowedProposers: {
658
+ readonly epoch: bigint;
659
+ readonly proposers: readonly number[];
660
+ } | null;
661
+ readonly minEpoch: bigint | null;
662
+ readonly maxEpoch: bigint | null;
663
+ readonly minTimestamp: bigint | null;
664
+ readonly maxTimestamp: bigint | null;
665
+ readonly chain: string;
666
+ readonly nonce: number;
667
+ };
668
+ } | undefined;
669
+ }, SigningError, never>;
670
+ readonly sponsored: (opts: {
671
+ readonly sender: SuiAddress;
672
+ readonly gasOwner: SuiAddress;
673
+ }) => (recipe: Recipe) => Recipe;
674
+ readonly submit: (signed: Signed) => Effect.Effect<Executed, SubmitError, Sui>;
675
+ readonly reconcile: (input: ReconcileInput) => Effect.Effect<Executed, TransportError | ExecutionFailed | SubmissionUnknown | NotApplied, Sui>;
676
+ readonly run: (recipe: Transaction | Recipe, opts: {
677
+ readonly signer: Signer;
678
+ readonly gasOwner?: SuiAddress;
679
+ /**
680
+ * The gas owner's signer, for a sponsored transaction. Required whenever
681
+ * the bytes name a gas owner that is not the sender.
682
+ */
683
+ readonly sponsor?: Signer;
684
+ }) => Effect.Effect<Executed, TransportError | SimulationFailed | ExecutionFailed | SubmissionUnknown | NotApplied | SigningError | BuildError | PolicyDenied | JournalError, Sui>;
685
+ readonly reconcileAll: () => Effect.Effect<readonly Reconciled[], TransportError | JournalError, Sui>;
686
+ };
687
+ //# sourceMappingURL=Tx.d.ts.map