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,227 @@
1
+ /**
2
+ * `SuiCore`: a hand-written 1:1 Effect wrap of `ClientWithCoreApi` from
3
+ * `@mysten/sui/client`.
4
+ *
5
+ * Every method of `SuiClientTypes.TransportMethods` is here, none of them
6
+ * optional, with the SDK's `Include` generics preserved so an unrequested field
7
+ * is still statically `undefined`. Every call forwards the Effect's
8
+ * `AbortSignal` into the SDK's `signal` option, so `Effect.timeout` and
9
+ * interruption cancel the request. Every method carries a span named after it.
10
+ *
11
+ * @since 0.1.0
12
+ */
13
+ import type { ClientWithCoreApi, SuiClientTypes } from "@mysten/sui/client";
14
+ import type { TransactionPlugin } from "@mysten/sui/transactions";
15
+ import { Config, Context, Effect, Layer, Schedule } from "effect";
16
+ import { ObjectDeleted, ObjectNotFound, ObjectUnavailable, SimulationFailed, TransactionNotFound, TransportError } from "../domain/errors.ts";
17
+ export { RETRYABLE_GRPC_STATUSES } from "../domain/errors.ts";
18
+ export { executionReasonOf } from "../domain/schemas.ts";
19
+ /** Every failure `mapSdkError` can produce. */
20
+ export type SuiCoreError = TransportError | ObjectNotFound | ObjectDeleted | ObjectUnavailable | TransactionNotFound | SimulationFailed;
21
+ /** The failures of an object lookup. */
22
+ export type ObjectLookupError = ObjectNotFound | ObjectDeleted | ObjectUnavailable | TransportError;
23
+ /** The failures of a transaction lookup. */
24
+ export type TransactionLookupError = TransactionNotFound | TransportError;
25
+ /** The failures of a simulation. */
26
+ export type SimulationLookupError = SimulationFailed | TransportError;
27
+ /**
28
+ * A thrown value carrying this symbol is a bug in the caller or in a test
29
+ * double, not a transport failure. `mapSdkError` re-throws it so it surfaces as
30
+ * a defect instead of being classified as a `TransportError`.
31
+ */
32
+ export declare const DefectMarker: unique symbol;
33
+ /**
34
+ * The one place an SDK failure becomes a sui-effect failure.
35
+ *
36
+ * `ObjectError` maps by its transport-neutral `reason`, `TransactionError` to
37
+ * `TransactionNotFound`, `SimulationError` to `SimulationFailed` with its
38
+ * `executionError` decoded into an `ExecutionReason`, and everything else
39
+ * (gRPC `RpcError`, `SuiHTTPStatusError`, `JsonRpcError`, `Cause.TimeoutError`,
40
+ * any thrown value at all) to a `TransportError` whose `retryable` says whether
41
+ * a read may try again.
42
+ *
43
+ * Total on every value a transport can throw. The one exception is a value
44
+ * carrying {@link DefectMarker}, which is a bug in the caller or in a test
45
+ * double rather than a transport failure: that is re-thrown so it surfaces as a
46
+ * defect instead of being mislabelled a `TransportError`.
47
+ */
48
+ export declare const mapSdkError: (method: string, cause: unknown) => SuiCoreError;
49
+ /**
50
+ * The read retry policy from the spec: jittered exponential backoff capped at a
51
+ * ten second gap, at most five attempts, and only while the failure is a
52
+ * retryable `TransportError`.
53
+ */
54
+ export declare const readSchedule: Schedule.Schedule<import("effect/Duration").Duration, unknown, never, never>;
55
+ type ObjectInclude = SuiClientTypes.ObjectInclude;
56
+ type TransactionInclude = SuiClientTypes.TransactionInclude;
57
+ type SimulateInclude = SuiClientTypes.SimulateTransactionInclude;
58
+ /**
59
+ * What a versioned object read found: the object as it was at that exact
60
+ * version, with the digest of the transaction that produced it, or nothing at
61
+ * all with a reason a log can print.
62
+ */
63
+ export type VersionedObject = {
64
+ readonly _tag: "Found";
65
+ readonly objectId: string;
66
+ readonly version: string;
67
+ readonly previousTransaction: string | undefined;
68
+ } | {
69
+ readonly _tag: "Absent";
70
+ readonly reason: string;
71
+ };
72
+ /**
73
+ * The mechanical tier: one member per `SuiClientTypes.TransportMethods` key,
74
+ * plus the four concrete conveniences `CoreClient` adds and the `use` hatch.
75
+ */
76
+ export interface SuiCoreService {
77
+ /** The network the underlying client was constructed for. */
78
+ readonly network: SuiClientTypes.Network;
79
+ /** Reads a batch of objects. Per-item failures are `Error` values in the result. Fails with: `TransportError`. */
80
+ readonly getObjects: <Include extends ObjectInclude = {}>(options: SuiClientTypes.GetObjectsOptions<Include>) => Effect.Effect<SuiClientTypes.GetObjectsResponse<Include>, TransportError>;
81
+ /** Reads one object. Fails with: `ObjectNotFound`, `ObjectDeleted`, `ObjectUnavailable`, `TransportError`. */
82
+ readonly getObject: <Include extends ObjectInclude = {}>(options: SuiClientTypes.GetObjectOptions<Include>) => Effect.Effect<SuiClientTypes.GetObjectResponse<Include>, ObjectLookupError>;
83
+ /** One page of the objects an address owns. Fails with: `TransportError`. */
84
+ readonly listOwnedObjects: <Include extends ObjectInclude = {}>(options: SuiClientTypes.ListOwnedObjectsOptions<Include>) => Effect.Effect<SuiClientTypes.ListOwnedObjectsResponse<Include>, TransportError>;
85
+ /** One page of the coins an address owns. Fails with: `TransportError`. */
86
+ readonly listCoins: (options: SuiClientTypes.ListCoinsOptions) => Effect.Effect<SuiClientTypes.ListCoinsResponse, TransportError>;
87
+ /** One page of a parent object's dynamic fields. Fails with: `TransportError`. */
88
+ readonly listDynamicFields: (options: SuiClientTypes.ListDynamicFieldsOptions) => Effect.Effect<SuiClientTypes.ListDynamicFieldsResponse, TransportError>;
89
+ /** Reads one dynamic field. Fails with: `ObjectNotFound`, `ObjectDeleted`, `ObjectUnavailable`, `TransportError`. */
90
+ readonly getDynamicField: (options: SuiClientTypes.GetDynamicFieldOptions) => Effect.Effect<SuiClientTypes.GetDynamicFieldResponse, ObjectLookupError>;
91
+ /** Reads one dynamic object field. Fails with: `ObjectNotFound`, `ObjectDeleted`, `ObjectUnavailable`, `TransportError`. */
92
+ readonly getDynamicObjectField: <Include extends ObjectInclude = {}>(options: SuiClientTypes.GetDynamicObjectFieldOptions<Include>) => Effect.Effect<SuiClientTypes.GetDynamicObjectFieldResponse<Include>, ObjectLookupError>;
93
+ /** The balance of one coin type for one owner. Fails with: `TransportError`. */
94
+ readonly getBalance: (options: SuiClientTypes.GetBalanceOptions) => Effect.Effect<SuiClientTypes.GetBalanceResponse, TransportError>;
95
+ /** One page of every balance an owner holds. Fails with: `TransportError`. */
96
+ readonly listBalances: (options: SuiClientTypes.ListBalancesOptions) => Effect.Effect<SuiClientTypes.ListBalancesResponse, TransportError>;
97
+ /** Coin metadata for a coin type. Fails with: `TransportError`. */
98
+ readonly getCoinMetadata: (options: SuiClientTypes.GetCoinMetadataOptions) => Effect.Effect<SuiClientTypes.GetCoinMetadataResponse, TransportError>;
99
+ /** Reads an executed transaction by digest. Fails with: `TransactionNotFound`, `TransportError`. */
100
+ readonly getTransaction: <Include extends TransactionInclude = {}>(options: SuiClientTypes.GetTransactionOptions<Include>) => Effect.Effect<SuiClientTypes.TransactionResult<Include>, TransactionLookupError>;
101
+ /** Submits signed bytes. Never retried at this tier. Fails with: `TransportError`. */
102
+ readonly executeTransaction: <Include extends TransactionInclude = {}>(options: SuiClientTypes.ExecuteTransactionOptions<Include>) => Effect.Effect<SuiClientTypes.TransactionResult<Include>, TransportError>;
103
+ /** Signs and submits in one call. Never retried at this tier. Fails with: `TransportError`. */
104
+ readonly signAndExecuteTransaction: <Include extends TransactionInclude = {}>(options: SuiClientTypes.SignAndExecuteTransactionOptions<Include>) => Effect.Effect<SuiClientTypes.TransactionResult<Include>, TransportError>;
105
+ /**
106
+ * Reads one object **at a specific version**, for the one question the
107
+ * live-object read cannot answer: which transaction consumed the version a
108
+ * set of bytes pinned.
109
+ *
110
+ * `previousTransaction` on the *current* object names the latest mutation,
111
+ * which is not necessarily the consumer of an older version: T can consume
112
+ * version 3 and U version 4, and the live object then names U. Sui assigns
113
+ * outputs the transaction's Lamport version, so the consumer of version `v`
114
+ * is *not* generally the object at `v + 1`; `Tx.reconcile` identifies it by
115
+ * walking the live object's `previousTransaction` and its effects'
116
+ * `inputVersion` instead. This read stays public as a primitive for callers
117
+ * that know a specific historical version exists.
118
+ *
119
+ * The SDK's `GetObjectOptions` carries no version, so this is not a wrap of a
120
+ * Core method: it reaches the transport's own historical read — the gRPC
121
+ * `LedgerService.GetObject` with a `version`, or JSON-RPC
122
+ * `sui_tryGetPastObject` — and answers `Absent` on any transport that has
123
+ * neither, on a version that was pruned, and on an object that never had it.
124
+ * `Absent` is never evidence of anything; a caller that needs proof treats it
125
+ * as "unknown".
126
+ *
127
+ * Fails with: `TransportError`.
128
+ */
129
+ readonly getObjectAtVersion: (options: {
130
+ readonly objectId: string;
131
+ readonly version: string | bigint;
132
+ }) => Effect.Effect<VersionedObject, TransportError>;
133
+ /** Polls until a digest is visible. Fails with: `TransactionNotFound`, `TransportError`. */
134
+ readonly waitForTransaction: <Include extends TransactionInclude = {}>(options: SuiClientTypes.WaitForTransactionOptions<Include>) => Effect.Effect<SuiClientTypes.TransactionResult<Include>, TransactionLookupError>;
135
+ /** Simulates a transaction. Fails with: `SimulationFailed`, `TransportError`. */
136
+ readonly simulateTransaction: <Include extends SimulateInclude = {}>(options: SuiClientTypes.SimulateTransactionOptions<Include>) => Effect.Effect<SuiClientTypes.SimulateTransactionResult<Include>, SimulationLookupError>;
137
+ /** One page of transaction history. Fails with: `TransportError`. */
138
+ readonly listTransactions: <Include extends TransactionInclude = {}>(options: SuiClientTypes.ListTransactionsOptions<Include>) => Effect.Effect<SuiClientTypes.ListTransactionsResponse<Include>, TransportError>;
139
+ /** One page of events. Fails with: `TransportError`. */
140
+ readonly listEvents: (options: SuiClientTypes.ListEventsOptions) => Effect.Effect<SuiClientTypes.ListEventsResponse, TransportError>;
141
+ /** The current reference gas price. Fails with: `TransportError`. */
142
+ readonly getReferenceGasPrice: (options?: SuiClientTypes.GetReferenceGasPriceOptions) => Effect.Effect<SuiClientTypes.GetReferenceGasPriceResponse, TransportError>;
143
+ /** The current system state. Fails with: `TransportError`. */
144
+ readonly getCurrentSystemState: (options?: SuiClientTypes.GetCurrentSystemStateOptions) => Effect.Effect<SuiClientTypes.GetCurrentSystemStateResponse, TransportError>;
145
+ /** The protocol config. Fails with: `TransportError`. */
146
+ readonly getProtocolConfig: (options?: SuiClientTypes.GetProtocolConfigOptions) => Effect.Effect<SuiClientTypes.GetProtocolConfigResponse, TransportError>;
147
+ /** The genesis checkpoint digest identifying the network. Fails with: `TransportError`. */
148
+ readonly getChainIdentifier: (options?: SuiClientTypes.GetChainIdentifierOptions) => Effect.Effect<SuiClientTypes.GetChainIdentifierResponse, TransportError>;
149
+ /** Move function metadata. Fails with: `TransportError`. */
150
+ readonly getMoveFunction: (options: SuiClientTypes.GetMoveFunctionOptions) => Effect.Effect<SuiClientTypes.GetMoveFunctionResponse, TransportError>;
151
+ /** Verifies a zkLogin signature. Fails with: `TransportError`. */
152
+ readonly verifyZkLoginSignature: (options: SuiClientTypes.VerifyZkLoginSignatureOptions) => Effect.Effect<SuiClientTypes.ZkLoginVerifyResponse, TransportError>;
153
+ /** Resolves a SuiNS name to an address. Fails with: `TransportError`. */
154
+ readonly resolveNameServiceAddress: (options: SuiClientTypes.ResolveNameServiceAddressOptions) => Effect.Effect<SuiClientTypes.ResolveNameServiceAddressResponse, TransportError>;
155
+ /** The default SuiNS name of an address. Fails with: `TransportError`. */
156
+ readonly defaultNameServiceName: (options: SuiClientTypes.DefaultNameServiceNameOptions) => Effect.Effect<SuiClientTypes.DefaultNameServiceNameResponse, TransportError>;
157
+ /** Move Registry resolution. Each member fails with: `TransportError`. */
158
+ readonly mvr: {
159
+ readonly resolvePackage: (options: SuiClientTypes.MvrResolvePackageOptions) => Effect.Effect<SuiClientTypes.MvrResolvePackageResponse, TransportError>;
160
+ readonly resolveType: (options: SuiClientTypes.MvrResolveTypeOptions) => Effect.Effect<SuiClientTypes.MvrResolveTypeResponse, TransportError>;
161
+ readonly resolve: (options: SuiClientTypes.MvrResolveOptions) => Effect.Effect<SuiClientTypes.MvrResolveResponse, TransportError>;
162
+ };
163
+ /**
164
+ * The transport's build plugin, which the transaction builder needs to
165
+ * resolve inputs. A pure value constructor, wrapped in an Effect only so the
166
+ * fake can refuse it. Never fails.
167
+ */
168
+ readonly resolveTransactionPlugin: () => Effect.Effect<TransactionPlugin>;
169
+ /**
170
+ * The low-level hatch: run one call against the SDK client object with the
171
+ * Effect's `AbortSignal` already forwarded.
172
+ *
173
+ * Fails with the full `mapSdkError` union: `TransportError`, `ObjectNotFound`,
174
+ * `ObjectDeleted`, `ObjectUnavailable`, `TransactionNotFound`,
175
+ * `SimulationFailed`.
176
+ */
177
+ readonly use: <A>(run: (client: ClientWithCoreApi, signal: AbortSignal) => Promise<A>) => Effect.Effect<A, SuiCoreError>;
178
+ }
179
+ declare const SuiCore_base: Context.ServiceClass<SuiCore, "sui-effect/SuiCore", SuiCoreService>;
180
+ /**
181
+ * The mechanical tier over `@mysten/sui`.
182
+ *
183
+ * @example
184
+ * ```ts
185
+ * import { Effect } from "effect"
186
+ * import { SuiCore } from "sui-effect"
187
+ *
188
+ * const chainId = Effect.gen(function*() {
189
+ * const core = yield* SuiCore
190
+ * const { chainIdentifier } = yield* core.getChainIdentifier()
191
+ * return chainIdentifier
192
+ * })
193
+ * ```
194
+ */
195
+ export declare class SuiCore extends SuiCore_base {
196
+ /** Wraps a client the caller already built and configured. */
197
+ static readonly layerFromClient: (client: ClientWithCoreApi) => Layer.Layer<SuiCore>;
198
+ /** Builds a `SuiGrpcClient` and wraps it. */
199
+ static readonly layerGrpc: (options: SuiGrpcLayerOptions) => Layer.Layer<SuiCore>;
200
+ /**
201
+ * Reads `SUI_NETWORK` (required, no default) and `SUI_RPC_URL` (optional,
202
+ * defaulted from {@link defaultGrpcUrl} for the four known networks).
203
+ *
204
+ * The layer fails with `ConfigError` when `SUI_NETWORK` is missing, or when
205
+ * it names a network with no built-in URL and `SUI_RPC_URL` is not set.
206
+ */
207
+ static readonly layerConfig: Layer.Layer<SuiCore, Config.ConfigError>;
208
+ }
209
+ /** Options for {@link SuiCore.layerGrpc}, mirroring `SuiGrpcClientOptions`. */
210
+ export interface SuiGrpcLayerOptions {
211
+ readonly network: SuiClientTypes.Network;
212
+ readonly baseUrl: string;
213
+ readonly timeout?: number;
214
+ readonly mvr?: SuiClientTypes.MvrOptions;
215
+ }
216
+ /**
217
+ * The gRPC endpoint sui-effect uses when `SUI_RPC_URL` is not set. The SDK
218
+ * ships no such table; these are the URLs its own documentation uses.
219
+ * Returns `undefined` for any other network. Never fails.
220
+ */
221
+ export declare const defaultGrpcUrl: (network: string) => string | undefined;
222
+ /**
223
+ * Wraps a client object into the service. Exported so `SuiExtension.fromService`
224
+ * and tests can build the same implementation over any `ClientWithCoreApi`.
225
+ */
226
+ export declare const makeFromClient: (client: ClientWithCoreApi) => SuiCoreService;
227
+ //# sourceMappingURL=SuiCore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SuiCore.d.ts","sourceRoot":"","sources":["../../src/services/SuiCore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAG3E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AACjE,OAAO,EAAE,MAAM,EAAkB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAU,MAAM,QAAQ,CAAA;AACzF,OAAO,EACL,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,EACnB,cAAc,EACf,MAAM,qBAAqB,CAAA;AAK5B,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAA;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAIxD,+CAA+C;AAC/C,MAAM,MAAM,YAAY,GACpB,cAAc,GACd,cAAc,GACd,aAAa,GACb,iBAAiB,GACjB,mBAAmB,GACnB,gBAAgB,CAAA;AAEpB,wCAAwC;AACxC,MAAM,MAAM,iBAAiB,GAAG,cAAc,GAAG,aAAa,GAAG,iBAAiB,GAAG,cAAc,CAAA;AAEnG,4CAA4C;AAC5C,MAAM,MAAM,sBAAsB,GAAG,mBAAmB,GAAG,cAAc,CAAA;AAEzE,oCAAoC;AACpC,MAAM,MAAM,qBAAqB,GAAG,gBAAgB,GAAG,cAAc,CAAA;AAgBrE;;;;GAIG;AACH,eAAO,MAAM,YAAY,EAAE,OAAO,MAA8C,CAAA;AAWhF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,WAAW,GAAI,QAAQ,MAAM,EAAE,OAAO,OAAO,KAAG,YA0C5D,CAAA;AAyDD;;;;GAIG;AACH,eAAO,MAAM,YAAY,8EAGC,CAAA;AAc1B,KAAK,aAAa,GAAG,cAAc,CAAC,aAAa,CAAA;AACjD,KAAK,kBAAkB,GAAG,cAAc,CAAC,kBAAkB,CAAA;AAC3D,KAAK,eAAe,GAAG,cAAc,CAAC,0BAA0B,CAAA;AAEhE;;;;GAIG;AACH,MAAM,MAAM,eAAe,GACvB;IACA,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,mBAAmB,EAAE,MAAM,GAAG,SAAS,CAAA;CACjD,GACC;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AAExD;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,6DAA6D;IAC7D,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC,OAAO,CAAA;IAExC,kHAAkH;IAClH,QAAQ,CAAC,UAAU,EAAE,CAAC,OAAO,SAAS,aAAa,GAAG,EAAE,EACtD,OAAO,EAAE,cAAc,CAAC,iBAAiB,CAAC,OAAO,CAAC,KAC/C,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,cAAc,CAAC,CAAA;IAE9E,8GAA8G;IAC9G,QAAQ,CAAC,SAAS,EAAE,CAAC,OAAO,SAAS,aAAa,GAAG,EAAE,EACrD,OAAO,EAAE,cAAc,CAAC,gBAAgB,CAAC,OAAO,CAAC,KAC9C,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,iBAAiB,CAAC,OAAO,CAAC,EAAE,iBAAiB,CAAC,CAAA;IAEhF,6EAA6E;IAC7E,QAAQ,CAAC,gBAAgB,EAAE,CAAC,OAAO,SAAS,aAAa,GAAG,EAAE,EAC5D,OAAO,EAAE,cAAc,CAAC,uBAAuB,CAAC,OAAO,CAAC,KACrD,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,wBAAwB,CAAC,OAAO,CAAC,EAAE,cAAc,CAAC,CAAA;IAEpF,2EAA2E;IAC3E,QAAQ,CAAC,SAAS,EAAE,CAClB,OAAO,EAAE,cAAc,CAAC,gBAAgB,KACrC,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAAA;IAEpE,kFAAkF;IAClF,QAAQ,CAAC,iBAAiB,EAAE,CAC1B,OAAO,EAAE,cAAc,CAAC,wBAAwB,KAC7C,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,yBAAyB,EAAE,cAAc,CAAC,CAAA;IAE5E,qHAAqH;IACrH,QAAQ,CAAC,eAAe,EAAE,CACxB,OAAO,EAAE,cAAc,CAAC,sBAAsB,KAC3C,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,uBAAuB,EAAE,iBAAiB,CAAC,CAAA;IAE7E,4HAA4H;IAC5H,QAAQ,CAAC,qBAAqB,EAAE,CAAC,OAAO,SAAS,aAAa,GAAG,EAAE,EACjE,OAAO,EAAE,cAAc,CAAC,4BAA4B,CAAC,OAAO,CAAC,KAC1D,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,6BAA6B,CAAC,OAAO,CAAC,EAAE,iBAAiB,CAAC,CAAA;IAE5F,gFAAgF;IAChF,QAAQ,CAAC,UAAU,EAAE,CACnB,OAAO,EAAE,cAAc,CAAC,iBAAiB,KACtC,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,kBAAkB,EAAE,cAAc,CAAC,CAAA;IAErE,8EAA8E;IAC9E,QAAQ,CAAC,YAAY,EAAE,CACrB,OAAO,EAAE,cAAc,CAAC,mBAAmB,KACxC,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,oBAAoB,EAAE,cAAc,CAAC,CAAA;IAEvE,mEAAmE;IACnE,QAAQ,CAAC,eAAe,EAAE,CACxB,OAAO,EAAE,cAAc,CAAC,sBAAsB,KAC3C,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,uBAAuB,EAAE,cAAc,CAAC,CAAA;IAE1E,oGAAoG;IACpG,QAAQ,CAAC,cAAc,EAAE,CAAC,OAAO,SAAS,kBAAkB,GAAG,EAAE,EAC/D,OAAO,EAAE,cAAc,CAAC,qBAAqB,CAAC,OAAO,CAAC,KACnD,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,iBAAiB,CAAC,OAAO,CAAC,EAAE,sBAAsB,CAAC,CAAA;IAErF,sFAAsF;IACtF,QAAQ,CAAC,kBAAkB,EAAE,CAAC,OAAO,SAAS,kBAAkB,GAAG,EAAE,EACnE,OAAO,EAAE,cAAc,CAAC,yBAAyB,CAAC,OAAO,CAAC,KACvD,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,iBAAiB,CAAC,OAAO,CAAC,EAAE,cAAc,CAAC,CAAA;IAE7E,+FAA+F;IAC/F,QAAQ,CAAC,yBAAyB,EAAE,CAAC,OAAO,SAAS,kBAAkB,GAAG,EAAE,EAC1E,OAAO,EAAE,cAAc,CAAC,gCAAgC,CAAC,OAAO,CAAC,KAC9D,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,iBAAiB,CAAC,OAAO,CAAC,EAAE,cAAc,CAAC,CAAA;IAE7E;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,QAAQ,CAAC,kBAAkB,EAAE,CAC3B,OAAO,EAAE;QAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,KACtE,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE,cAAc,CAAC,CAAA;IAEnD,4FAA4F;IAC5F,QAAQ,CAAC,kBAAkB,EAAE,CAAC,OAAO,SAAS,kBAAkB,GAAG,EAAE,EACnE,OAAO,EAAE,cAAc,CAAC,yBAAyB,CAAC,OAAO,CAAC,KACvD,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,iBAAiB,CAAC,OAAO,CAAC,EAAE,sBAAsB,CAAC,CAAA;IAErF,iFAAiF;IACjF,QAAQ,CAAC,mBAAmB,EAAE,CAAC,OAAO,SAAS,eAAe,GAAG,EAAE,EACjE,OAAO,EAAE,cAAc,CAAC,0BAA0B,CAAC,OAAO,CAAC,KACxD,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,yBAAyB,CAAC,OAAO,CAAC,EAAE,qBAAqB,CAAC,CAAA;IAE5F,qEAAqE;IACrE,QAAQ,CAAC,gBAAgB,EAAE,CAAC,OAAO,SAAS,kBAAkB,GAAG,EAAE,EACjE,OAAO,EAAE,cAAc,CAAC,uBAAuB,CAAC,OAAO,CAAC,KACrD,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,wBAAwB,CAAC,OAAO,CAAC,EAAE,cAAc,CAAC,CAAA;IAEpF,wDAAwD;IACxD,QAAQ,CAAC,UAAU,EAAE,CACnB,OAAO,EAAE,cAAc,CAAC,iBAAiB,KACtC,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,kBAAkB,EAAE,cAAc,CAAC,CAAA;IAErE,qEAAqE;IACrE,QAAQ,CAAC,oBAAoB,EAAE,CAC7B,OAAO,CAAC,EAAE,cAAc,CAAC,2BAA2B,KACjD,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,4BAA4B,EAAE,cAAc,CAAC,CAAA;IAE/E,8DAA8D;IAC9D,QAAQ,CAAC,qBAAqB,EAAE,CAC9B,OAAO,CAAC,EAAE,cAAc,CAAC,4BAA4B,KAClD,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,6BAA6B,EAAE,cAAc,CAAC,CAAA;IAEhF,yDAAyD;IACzD,QAAQ,CAAC,iBAAiB,EAAE,CAC1B,OAAO,CAAC,EAAE,cAAc,CAAC,wBAAwB,KAC9C,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,yBAAyB,EAAE,cAAc,CAAC,CAAA;IAE5E,2FAA2F;IAC3F,QAAQ,CAAC,kBAAkB,EAAE,CAC3B,OAAO,CAAC,EAAE,cAAc,CAAC,yBAAyB,KAC/C,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,0BAA0B,EAAE,cAAc,CAAC,CAAA;IAE7E,4DAA4D;IAC5D,QAAQ,CAAC,eAAe,EAAE,CACxB,OAAO,EAAE,cAAc,CAAC,sBAAsB,KAC3C,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,uBAAuB,EAAE,cAAc,CAAC,CAAA;IAE1E,kEAAkE;IAClE,QAAQ,CAAC,sBAAsB,EAAE,CAC/B,OAAO,EAAE,cAAc,CAAC,6BAA6B,KAClD,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,qBAAqB,EAAE,cAAc,CAAC,CAAA;IAExE,yEAAyE;IACzE,QAAQ,CAAC,yBAAyB,EAAE,CAClC,OAAO,EAAE,cAAc,CAAC,gCAAgC,KACrD,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,iCAAiC,EAAE,cAAc,CAAC,CAAA;IAEpF,0EAA0E;IAC1E,QAAQ,CAAC,sBAAsB,EAAE,CAC/B,OAAO,EAAE,cAAc,CAAC,6BAA6B,KAClD,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,8BAA8B,EAAE,cAAc,CAAC,CAAA;IAEjF,0EAA0E;IAC1E,QAAQ,CAAC,GAAG,EAAE;QACZ,QAAQ,CAAC,cAAc,EAAE,CACvB,OAAO,EAAE,cAAc,CAAC,wBAAwB,KAC7C,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,yBAAyB,EAAE,cAAc,CAAC,CAAA;QAC5E,QAAQ,CAAC,WAAW,EAAE,CACpB,OAAO,EAAE,cAAc,CAAC,qBAAqB,KAC1C,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,sBAAsB,EAAE,cAAc,CAAC,CAAA;QACzE,QAAQ,CAAC,OAAO,EAAE,CAChB,OAAO,EAAE,cAAc,CAAC,iBAAiB,KACtC,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,kBAAkB,EAAE,cAAc,CAAC,CAAA;KACtE,CAAA;IAED;;;;OAIG;IACH,QAAQ,CAAC,wBAAwB,EAAE,MAAM,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAA;IAEzE;;;;;;;OAOG;IACH,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,EACd,GAAG,EAAE,CAAC,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,KAChE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,YAAY,CAAC,CAAA;CACpC;;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,OAAQ,SAAQ,YAAgE;IAC3F,8DAA8D;IAC9D,MAAM,CAAC,QAAQ,CAAC,eAAe,GAAI,QAAQ,iBAAiB,KAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CACnC;IAEhD,6CAA6C;IAC7C,MAAM,CAAC,QAAQ,CAAC,SAAS,GAAI,SAAS,mBAAmB,KAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CACZ;IAEpE;;;;;;OAMG;IACH,MAAM,CAAC,QAAQ,CAAC,WAAW,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,CAkBpE;CACF;AAED,+EAA+E;AAC/E,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC,OAAO,CAAA;IACxC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,GAAG,CAAC,EAAE,cAAc,CAAC,UAAU,CAAA;CACzC;AAED;;;;GAIG;AACH,eAAO,MAAM,cAAc,GAAI,SAAS,MAAM,KAAG,MAAM,GAAG,SAazD,CAAA;AAqGD;;;GAGG;AACH,eAAO,MAAM,cAAc,GAAI,QAAQ,iBAAiB,KAAG,cA4S1D,CAAA"}
@@ -0,0 +1,400 @@
1
+ import { ObjectError, SimulationError, TransactionError } from "@mysten/sui/client";
2
+ import { isSuiGrpcClient, SuiGrpcClient } from "@mysten/sui/grpc";
3
+ import { Config, ConfigProvider, Context, Effect, Layer, Schedule, Schema } from "effect";
4
+ import { ObjectDeleted, ObjectNotFound, ObjectUnavailable, SimulationFailed, TransactionNotFound, TransportError } from "../domain/errors.js";
5
+ import { classifyTransportCause } from "../domain/errors.js";
6
+ import { Digest, executionReasonOf, ExecutionReason, KnownNetwork, ObjectId } from "../domain/schemas.js";
7
+ export { RETRYABLE_GRPC_STATUSES } from "../domain/errors.js";
8
+ export { executionReasonOf } from "../domain/schemas.js";
9
+ const UNKNOWN_REASON = ExecutionReason.cases.Unknown.make({ $kind: "Unknown" });
10
+ const ZERO_OBJECT_ID = ObjectId.make(`0x${"0".repeat(64)}`);
11
+ const ZERO_DIGEST = Digest.make("1".repeat(32));
12
+ const asObjectId = (value) => {
13
+ if (value === undefined)
14
+ return ZERO_OBJECT_ID;
15
+ const decoded = Schema.decodeUnknownOption(ObjectId)(value);
16
+ return decoded._tag === "Some" ? decoded.value : ZERO_OBJECT_ID;
17
+ };
18
+ const asDigest = (value) => {
19
+ const decoded = Schema.decodeUnknownOption(Digest)(value);
20
+ return decoded._tag === "Some" ? decoded.value : ZERO_DIGEST;
21
+ };
22
+ /**
23
+ * A thrown value carrying this symbol is a bug in the caller or in a test
24
+ * double, not a transport failure. `mapSdkError` re-throws it so it surfaces as
25
+ * a defect instead of being classified as a `TransportError`.
26
+ */
27
+ export const DefectMarker = Symbol.for("sui-effect/DefectMarker");
28
+ const rethrowDefects = (cause) => {
29
+ if (typeof cause === "object" && cause !== null && DefectMarker in cause)
30
+ throw cause;
31
+ };
32
+ const transportError = (method, cause) => {
33
+ rethrowDefects(cause);
34
+ return TransportError.fromUnknown(method, cause);
35
+ };
36
+ /**
37
+ * The one place an SDK failure becomes a sui-effect failure.
38
+ *
39
+ * `ObjectError` maps by its transport-neutral `reason`, `TransactionError` to
40
+ * `TransactionNotFound`, `SimulationError` to `SimulationFailed` with its
41
+ * `executionError` decoded into an `ExecutionReason`, and everything else
42
+ * (gRPC `RpcError`, `SuiHTTPStatusError`, `JsonRpcError`, `Cause.TimeoutError`,
43
+ * any thrown value at all) to a `TransportError` whose `retryable` says whether
44
+ * a read may try again.
45
+ *
46
+ * Total on every value a transport can throw. The one exception is a value
47
+ * carrying {@link DefectMarker}, which is a bug in the caller or in a test
48
+ * double rather than a transport failure: that is re-thrown so it surfaces as a
49
+ * defect instead of being mislabelled a `TransportError`.
50
+ */
51
+ export const mapSdkError = (method, cause) => {
52
+ rethrowDefects(cause);
53
+ if (cause instanceof ObjectError) {
54
+ const objectId = asObjectId(cause.objectId);
55
+ switch (cause.reason) {
56
+ case "notFound":
57
+ return new ObjectNotFound({ objectId });
58
+ case "deleted":
59
+ return new ObjectDeleted({ objectId });
60
+ default:
61
+ return new ObjectUnavailable({ objectId });
62
+ }
63
+ }
64
+ if (cause instanceof TransactionError) {
65
+ return new TransactionNotFound({ digest: asDigest(cause.digest) });
66
+ }
67
+ if (cause instanceof SimulationError) {
68
+ // The SDK's resolve plugin simulates to choose a gas budget and wraps
69
+ // *whatever went wrong* in a `SimulationError`, transport failures
70
+ // included: a rejected fetch, a gRPC `UNAVAILABLE`, an HTTP 503. Only a
71
+ // wrapper carrying an `executionError` describes a transaction that would
72
+ // abort on chain; the rest are the node being unreachable, and calling
73
+ // those `SimulationFailed` loses both the status and the retryability a
74
+ // caller needs.
75
+ if (cause.executionError === undefined) {
76
+ const transport = transportCauseOf(cause);
77
+ if (transport !== undefined) {
78
+ return new TransportError({
79
+ method,
80
+ retryable: transport.retryable,
81
+ ...(transport.status === undefined ? {} : { status: transport.status }),
82
+ cause: cause.cause ?? cause
83
+ });
84
+ }
85
+ }
86
+ return new SimulationFailed({
87
+ reason: cause.executionError === undefined ? UNKNOWN_REASON : executionReasonOf(cause.executionError),
88
+ message: cause.message
89
+ });
90
+ }
91
+ return transportError(method, cause);
92
+ };
93
+ /**
94
+ * The transport failure a `SimulationError` is carrying, if it is carrying one.
95
+ *
96
+ * `classifyTransportCause` recognises a gRPC `RpcError` by its `code`, an HTTP
97
+ * status error by its numeric `status`, and an abort or timeout by its `name`.
98
+ * A cause it does not recognise — a plain `Error` the resolver threw itself —
99
+ * is not a transport failure and the wrapper stays `SimulationFailed`. The
100
+ * chain is walked one level at a time because grpc-web wraps a rejected fetch
101
+ * once more on its way out. Never fails.
102
+ */
103
+ const transportCauseOf = (error) => {
104
+ let current = error.cause;
105
+ for (let depth = 0; depth < 4 && current !== undefined && current !== null; depth += 1) {
106
+ const classified = classifyTransportCause(current);
107
+ if (classified.status !== undefined)
108
+ return classified;
109
+ if (current instanceof TypeError) {
110
+ // A rejected `fetch` is a bare `TypeError` with no status of any kind;
111
+ // it is still the network, and still worth retrying.
112
+ return { retryable: true };
113
+ }
114
+ current = current.cause;
115
+ }
116
+ return undefined;
117
+ };
118
+ /** Narrows `mapSdkError` to the union an object lookup declares. */
119
+ const objectError = (method) => (cause) => {
120
+ const error = mapSdkError(method, cause);
121
+ return error._tag === "TransactionNotFound" || error._tag === "SimulationFailed"
122
+ ? transportError(method, cause)
123
+ : error;
124
+ };
125
+ /** Narrows `mapSdkError` to the union a transaction lookup declares. */
126
+ const transactionError = (method) => (cause) => {
127
+ const error = mapSdkError(method, cause);
128
+ return error._tag === "TransactionNotFound" || error._tag === "TransportError"
129
+ ? error
130
+ : transportError(method, cause);
131
+ };
132
+ /** Narrows `mapSdkError` to the union a simulation declares. */
133
+ const simulationError = (method) => (cause) => {
134
+ const error = mapSdkError(method, cause);
135
+ return error._tag === "SimulationFailed" || error._tag === "TransportError"
136
+ ? error
137
+ : transportError(method, cause);
138
+ };
139
+ /** Everything else: any failure at all becomes a `TransportError`. */
140
+ const onlyTransportError = (method) => (cause) => transportError(method, cause);
141
+ /**
142
+ * The read retry policy from the spec: jittered exponential backoff capped at a
143
+ * ten second gap, at most five attempts, and only while the failure is a
144
+ * retryable `TransportError`.
145
+ */
146
+ export const readSchedule = Schedule.min([
147
+ Schedule.exponential("250 millis"),
148
+ Schedule.spaced("10 seconds")
149
+ ]).pipe(Schedule.jittered);
150
+ const MAX_READ_ATTEMPTS = 5;
151
+ const retryReads = (effect) => Effect.retry(effect, {
152
+ schedule: readSchedule,
153
+ times: MAX_READ_ATTEMPTS - 1,
154
+ while: (error) => error._tag === "TransportError" && error.retryable
155
+ });
156
+ /**
157
+ * The mechanical tier over `@mysten/sui`.
158
+ *
159
+ * @example
160
+ * ```ts
161
+ * import { Effect } from "effect"
162
+ * import { SuiCore } from "sui-effect"
163
+ *
164
+ * const chainId = Effect.gen(function*() {
165
+ * const core = yield* SuiCore
166
+ * const { chainIdentifier } = yield* core.getChainIdentifier()
167
+ * return chainIdentifier
168
+ * })
169
+ * ```
170
+ */
171
+ export class SuiCore extends Context.Service()("sui-effect/SuiCore") {
172
+ /** Wraps a client the caller already built and configured. */
173
+ static layerFromClient = (client) => Layer.succeed(SuiCore, makeFromClient(client));
174
+ /** Builds a `SuiGrpcClient` and wraps it. */
175
+ static layerGrpc = (options) => Layer.sync(SuiCore, () => makeFromClient(makeGrpcClient(options)));
176
+ /**
177
+ * Reads `SUI_NETWORK` (required, no default) and `SUI_RPC_URL` (optional,
178
+ * defaulted from {@link defaultGrpcUrl} for the four known networks).
179
+ *
180
+ * The layer fails with `ConfigError` when `SUI_NETWORK` is missing, or when
181
+ * it names a network with no built-in URL and `SUI_RPC_URL` is not set.
182
+ */
183
+ static layerConfig = Layer.effect(SuiCore, Effect.gen(function* () {
184
+ const network = yield* Config.nonEmptyString("SUI_NETWORK");
185
+ const baseUrl = yield* Config.nonEmptyString("SUI_RPC_URL").pipe(Config.orElse(() => {
186
+ const fallback = defaultGrpcUrl(network);
187
+ return fallback === undefined
188
+ ? Config.fail(new ConfigProvider.SourceError({
189
+ message: `SUI_RPC_URL is required: no built-in gRPC endpoint for network "${network}"`
190
+ })).pipe(Config.map(String))
191
+ : Config.succeed(fallback);
192
+ }));
193
+ return makeFromClient(makeGrpcClient({ network, baseUrl }));
194
+ }));
195
+ }
196
+ /**
197
+ * The gRPC endpoint sui-effect uses when `SUI_RPC_URL` is not set. The SDK
198
+ * ships no such table; these are the URLs its own documentation uses.
199
+ * Returns `undefined` for any other network. Never fails.
200
+ */
201
+ export const defaultGrpcUrl = (network) => {
202
+ const decoded = Schema.decodeUnknownOption(KnownNetwork)(network);
203
+ if (decoded._tag !== "Some")
204
+ return undefined;
205
+ switch (decoded.value) {
206
+ case "mainnet":
207
+ return "https://fullnode.mainnet.sui.io:443";
208
+ case "testnet":
209
+ return "https://fullnode.testnet.sui.io:443";
210
+ case "devnet":
211
+ return "https://fullnode.devnet.sui.io:443";
212
+ case "localnet":
213
+ return "http://127.0.0.1:9000";
214
+ }
215
+ };
216
+ const makeGrpcClient = (options) => new SuiGrpcClient({
217
+ network: options.network,
218
+ baseUrl: options.baseUrl,
219
+ ...(options.timeout === undefined ? {} : { timeout: options.timeout }),
220
+ ...(options.mvr === undefined ? {} : { mvr: options.mvr })
221
+ });
222
+ const hasPastObject = (client) => typeof client.tryGetPastObject === "function";
223
+ const NOT_FOUND_STATUSES = new Set(["NOT_FOUND", "5"]);
224
+ /**
225
+ * One historical object read, on whichever transport the client is.
226
+ *
227
+ * gRPC's `LedgerService.GetObject` takes a `version` and a read mask; JSON-RPC
228
+ * has `sui_tryGetPastObject`. Everything else — a hand-written client, a test
229
+ * double with neither — answers `Absent`, because a transport that cannot read
230
+ * history must not be allowed to look like a transport that read history and
231
+ * found nothing.
232
+ */
233
+ const readObjectAtVersion = async (client, objectId, version, signal) => {
234
+ if (isSuiGrpcClient(client)) {
235
+ try {
236
+ const { response } = await client.ledgerService.getObject({
237
+ objectId,
238
+ version,
239
+ readMask: { paths: ["object_id", "version", "previous_transaction"] }
240
+ }, { abort: signal });
241
+ const object = response.object;
242
+ if (object === undefined || object.version === undefined) {
243
+ return { _tag: "Absent", reason: `the node served no object ${objectId} at version ${version}` };
244
+ }
245
+ return {
246
+ _tag: "Found",
247
+ objectId,
248
+ version: object.version.toString(),
249
+ previousTransaction: object.previousTransaction ?? undefined
250
+ };
251
+ }
252
+ catch (cause) {
253
+ const code = cause.code;
254
+ if (typeof code === "string" && NOT_FOUND_STATUSES.has(code)) {
255
+ return { _tag: "Absent", reason: `version ${version} of ${objectId} is not served (pruned or never existed)` };
256
+ }
257
+ throw cause;
258
+ }
259
+ }
260
+ if (hasPastObject(client)) {
261
+ const read = await client.tryGetPastObject({
262
+ id: objectId,
263
+ version: Number(version),
264
+ options: { showPreviousTransaction: true },
265
+ signal
266
+ });
267
+ if (read.status !== "VersionFound") {
268
+ return { _tag: "Absent", reason: `sui_tryGetPastObject answered ${read.status} for ${objectId} at version ${version}` };
269
+ }
270
+ const details = read.details;
271
+ return {
272
+ _tag: "Found",
273
+ objectId,
274
+ version: String(details.version),
275
+ previousTransaction: details.previousTransaction ?? undefined
276
+ };
277
+ }
278
+ return {
279
+ _tag: "Absent",
280
+ reason: "this transport cannot read an object at a past version"
281
+ };
282
+ };
283
+ /**
284
+ * Wraps a client object into the service. Exported so `SuiExtension.fromService`
285
+ * and tests can build the same implementation over any `ClientWithCoreApi`.
286
+ */
287
+ export const makeFromClient = (client) => {
288
+ // Every member below is an `Effect.fn("SuiCore.<method>")`, so the span is
289
+ // named after the method and `call` does not add one of its own.
290
+ const call = (_method, run, onError) => Effect.tryPromise({
291
+ try: (signal) => run(client.core, signal),
292
+ catch: onError
293
+ });
294
+ const read = (method, run, onError) => retryReads(call(method, run, onError));
295
+ return {
296
+ network: client.network,
297
+ getObjects: Effect.fn("SuiCore.getObjects")(function* (options) {
298
+ return yield* read("getObjects", (core, signal) => core.getObjects({ ...options, signal }), onlyTransportError("getObjects"));
299
+ }),
300
+ getObject: Effect.fn("SuiCore.getObject")(function* (options) {
301
+ return yield* read("getObject", (core, signal) => core.getObject({ ...options, signal }), objectError("getObject"));
302
+ }),
303
+ listOwnedObjects: Effect.fn("SuiCore.listOwnedObjects")(function* (options) {
304
+ return yield* read("listOwnedObjects", (core, signal) => core.listOwnedObjects({ ...options, signal }), onlyTransportError("listOwnedObjects"));
305
+ }),
306
+ listCoins: Effect.fn("SuiCore.listCoins")(function* (options) {
307
+ return yield* read("listCoins", (core, signal) => core.listCoins({ ...options, signal }), onlyTransportError("listCoins"));
308
+ }),
309
+ listDynamicFields: Effect.fn("SuiCore.listDynamicFields")(function* (options) {
310
+ return yield* read("listDynamicFields", (core, signal) => core.listDynamicFields({ ...options, signal }), onlyTransportError("listDynamicFields"));
311
+ }),
312
+ getDynamicField: Effect.fn("SuiCore.getDynamicField")(function* (options) {
313
+ return yield* read("getDynamicField", (core, signal) => core.getDynamicField({ ...options, signal }), objectError("getDynamicField"));
314
+ }),
315
+ getDynamicObjectField: Effect.fn("SuiCore.getDynamicObjectField")(function* (options) {
316
+ return yield* read("getDynamicObjectField", (core, signal) => core.getDynamicObjectField({ ...options, signal }), objectError("getDynamicObjectField"));
317
+ }),
318
+ getBalance: Effect.fn("SuiCore.getBalance")(function* (options) {
319
+ return yield* read("getBalance", (core, signal) => core.getBalance({ ...options, signal }), onlyTransportError("getBalance"));
320
+ }),
321
+ listBalances: Effect.fn("SuiCore.listBalances")(function* (options) {
322
+ return yield* read("listBalances", (core, signal) => core.listBalances({ ...options, signal }), onlyTransportError("listBalances"));
323
+ }),
324
+ getCoinMetadata: Effect.fn("SuiCore.getCoinMetadata")(function* (options) {
325
+ return yield* read("getCoinMetadata", (core, signal) => core.getCoinMetadata({ ...options, signal }), onlyTransportError("getCoinMetadata"));
326
+ }),
327
+ getTransaction: Effect.fn("SuiCore.getTransaction")(function* (options) {
328
+ return yield* read("getTransaction", (core, signal) => core.getTransaction({ ...options, signal }), transactionError("getTransaction"));
329
+ }),
330
+ executeTransaction: Effect.fn("SuiCore.executeTransaction")(function* (options) {
331
+ return yield* call("executeTransaction", (core, signal) => core.executeTransaction({ ...options, signal }), onlyTransportError("executeTransaction"));
332
+ }),
333
+ signAndExecuteTransaction: Effect.fn("SuiCore.signAndExecuteTransaction")(function* (options) {
334
+ return yield* call("signAndExecuteTransaction", (core, signal) => core.signAndExecuteTransaction({ ...options, signal }), onlyTransportError("signAndExecuteTransaction"));
335
+ }),
336
+ getObjectAtVersion: Effect.fn("SuiCore.getObjectAtVersion")(function* (options) {
337
+ return yield* retryReads(Effect.tryPromise({
338
+ try: (signal) => readObjectAtVersion(client, options.objectId, BigInt(options.version), signal),
339
+ catch: onlyTransportError("getObjectAtVersion")
340
+ }));
341
+ }),
342
+ waitForTransaction: Effect.fn("SuiCore.waitForTransaction")(function* (options) {
343
+ return yield* read("waitForTransaction", (core, signal) => core.waitForTransaction({ ...options, signal }), transactionError("waitForTransaction"));
344
+ }),
345
+ simulateTransaction: Effect.fn("SuiCore.simulateTransaction")(function* (options) {
346
+ return yield* read("simulateTransaction", (core, signal) => core.simulateTransaction({ ...options, signal }), simulationError("simulateTransaction"));
347
+ }),
348
+ listTransactions: Effect.fn("SuiCore.listTransactions")(function* (options) {
349
+ return yield* read("listTransactions", (core, signal) => core.listTransactions({ ...options, signal }), onlyTransportError("listTransactions"));
350
+ }),
351
+ listEvents: Effect.fn("SuiCore.listEvents")(function* (options) {
352
+ return yield* read("listEvents", (core, signal) => core.listEvents({ ...options, signal }), onlyTransportError("listEvents"));
353
+ }),
354
+ getReferenceGasPrice: Effect.fn("SuiCore.getReferenceGasPrice")(function* (options) {
355
+ return yield* read("getReferenceGasPrice", (core, signal) => core.getReferenceGasPrice({ ...options, signal }), onlyTransportError("getReferenceGasPrice"));
356
+ }),
357
+ getCurrentSystemState: Effect.fn("SuiCore.getCurrentSystemState")(function* (options) {
358
+ return yield* read("getCurrentSystemState", (core, signal) => core.getCurrentSystemState({ ...options, signal }), onlyTransportError("getCurrentSystemState"));
359
+ }),
360
+ getProtocolConfig: Effect.fn("SuiCore.getProtocolConfig")(function* (options) {
361
+ return yield* read("getProtocolConfig", (core, signal) => core.getProtocolConfig({ ...options, signal }), onlyTransportError("getProtocolConfig"));
362
+ }),
363
+ getChainIdentifier: Effect.fn("SuiCore.getChainIdentifier")(function* (options) {
364
+ return yield* read("getChainIdentifier", (core, signal) => core.getChainIdentifier({ ...options, signal }), onlyTransportError("getChainIdentifier"));
365
+ }),
366
+ getMoveFunction: Effect.fn("SuiCore.getMoveFunction")(function* (options) {
367
+ return yield* read("getMoveFunction", (core, signal) => core.getMoveFunction({ ...options, signal }), onlyTransportError("getMoveFunction"));
368
+ }),
369
+ verifyZkLoginSignature: Effect.fn("SuiCore.verifyZkLoginSignature")(function* (options) {
370
+ return yield* read("verifyZkLoginSignature", (core, signal) => core.verifyZkLoginSignature({ ...options, signal }), onlyTransportError("verifyZkLoginSignature"));
371
+ }),
372
+ resolveNameServiceAddress: Effect.fn("SuiCore.resolveNameServiceAddress")(function* (options) {
373
+ return yield* read("resolveNameServiceAddress", (core, signal) => core.resolveNameServiceAddress({ ...options, signal }), onlyTransportError("resolveNameServiceAddress"));
374
+ }),
375
+ defaultNameServiceName: Effect.fn("SuiCore.defaultNameServiceName")(function* (options) {
376
+ return yield* read("defaultNameServiceName", (core, signal) => core.defaultNameServiceName({ ...options, signal }), onlyTransportError("defaultNameServiceName"));
377
+ }),
378
+ mvr: {
379
+ resolvePackage: Effect.fn("SuiCore.mvr.resolvePackage")(function* (options) {
380
+ return yield* read("mvr.resolvePackage", (core, signal) => core.mvr.resolvePackage({ ...options, signal }), onlyTransportError("mvr.resolvePackage"));
381
+ }),
382
+ resolveType: Effect.fn("SuiCore.mvr.resolveType")(function* (options) {
383
+ return yield* read("mvr.resolveType", (core, signal) => core.mvr.resolveType({ ...options, signal }), onlyTransportError("mvr.resolveType"));
384
+ }),
385
+ resolve: Effect.fn("SuiCore.mvr.resolve")(function* (options) {
386
+ return yield* read("mvr.resolve", (core, signal) => core.mvr.resolve({ ...options, signal }), onlyTransportError("mvr.resolve"));
387
+ })
388
+ },
389
+ resolveTransactionPlugin: Effect.fn("SuiCore.resolveTransactionPlugin")(function* () {
390
+ return yield* Effect.sync(() => client.core.resolveTransactionPlugin());
391
+ }),
392
+ use: Effect.fn("SuiCore.use")(function* (run) {
393
+ return yield* Effect.tryPromise({
394
+ try: (signal) => run(client, signal),
395
+ catch: (cause) => mapSdkError("use", cause)
396
+ });
397
+ })
398
+ };
399
+ };
400
+ //# sourceMappingURL=SuiCore.js.map