@unconfirmed/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 +147 -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
|
@@ -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, "@unconfirmed/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 "@unconfirmed/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":"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"}
|
|
@@ -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 "@unconfirmed/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()("@unconfirmed/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
|