@exodus/sui-api 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/README.md +20 -0
- package/package.json +53 -0
- package/src/api.js +198 -0
- package/src/balances.js +22 -0
- package/src/basic-account-state.js +11 -0
- package/src/create-unsigned-tx.js +60 -0
- package/src/get-fee-async.js +62 -0
- package/src/get-fee.js +10 -0
- package/src/index.js +9 -0
- package/src/sui-no-history-monitor.js +277 -0
- package/src/transform-tx.js +100 -0
- package/src/tx-send.js +249 -0
- package/src/vendors/client/client.js +891 -0
- package/src/vendors/client/errors.js +38 -0
- package/src/vendors/client/http-transport.js +108 -0
- package/src/vendors/client/index.js +1 -0
- package/src/vendors/client/rpc-websocket-client.js +178 -0
- package/src/vendors/experimental/cache.js +89 -0
- package/src/vendors/experimental/client.js +27 -0
- package/src/vendors/experimental/core.js +105 -0
- package/src/vendors/experimental/errors.js +32 -0
- package/src/vendors/experimental/index.js +5 -0
- package/src/vendors/experimental/mvr.js +443 -0
- package/src/vendors/experimental/transports/json-rpc-resolver.js +359 -0
- package/src/vendors/experimental/transports/jsonRPC.js +504 -0
- package/src/vendors/experimental/transports/utils.js +90 -0
- package/src/vendors/transactions/Arguments.js +22 -0
- package/src/vendors/transactions/Commands.js +108 -0
- package/src/vendors/transactions/Inputs.js +59 -0
- package/src/vendors/transactions/ObjectCache.js +272 -0
- package/src/vendors/transactions/Transaction.js +843 -0
- package/src/vendors/transactions/TransactionData.js +293 -0
- package/src/vendors/transactions/data/internal.js +218 -0
- package/src/vendors/transactions/data/v1.js +538 -0
- package/src/vendors/transactions/data/v2.js +119 -0
- package/src/vendors/transactions/hash.js +12 -0
- package/src/vendors/transactions/index.js +1 -0
- package/src/vendors/transactions/object.js +22 -0
- package/src/vendors/transactions/plugins/NamedPackagesPlugin.js +49 -0
- package/src/vendors/transactions/pure.js +40 -0
- package/src/vendors/transactions/resolve.js +95 -0
- package/src/vendors/transactions/serializer.js +203 -0
- package/src/vendors/transactions/utils.js +67 -0
- package/src/vendors/valibot.js +7920 -0
|
@@ -0,0 +1,843 @@
|
|
|
1
|
+
/* eslint-disable no-sequences */
|
|
2
|
+
/* eslint-disable camelcase */
|
|
3
|
+
import { vendorLib } from '@exodus/sui-lib'
|
|
4
|
+
|
|
5
|
+
import { is, parse } from '../valibot.js'
|
|
6
|
+
import { Commands } from './Commands.js'
|
|
7
|
+
import { Argument, NormalizedCallArg, ObjectRef, TransactionExpiration } from './data/internal.js'
|
|
8
|
+
import { serializeV1TransactionData } from './data/v1.js'
|
|
9
|
+
import { SerializedTransactionDataV2 } from './data/v2.js'
|
|
10
|
+
import { Inputs } from './Inputs.js'
|
|
11
|
+
import { createObjectMethods } from './object.js'
|
|
12
|
+
import { namedPackagesPlugin } from './plugins/NamedPackagesPlugin.js'
|
|
13
|
+
import { createPure } from './pure.js'
|
|
14
|
+
import { needsTransactionResolution, resolveTransactionPlugin } from './resolve.js'
|
|
15
|
+
import { TransactionDataBuilder } from './TransactionData.js'
|
|
16
|
+
import { getIdFromCallArg } from './utils.js'
|
|
17
|
+
|
|
18
|
+
const { fromBase64, normalizeSuiAddress } = vendorLib.utils
|
|
19
|
+
const { isSerializedBcs } = vendorLib.bcs
|
|
20
|
+
|
|
21
|
+
var __typeError = (msg) => {
|
|
22
|
+
throw new TypeError(msg)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError('Cannot ' + msg)
|
|
26
|
+
var __privateGet = (obj, member, getter) => (
|
|
27
|
+
__accessCheck(obj, member, 'read from private field'), getter ? getter.call(obj) : member.get(obj)
|
|
28
|
+
)
|
|
29
|
+
var __privateAdd = (obj, member, value) =>
|
|
30
|
+
member.has(obj)
|
|
31
|
+
? __typeError('Cannot add the same private member more than once')
|
|
32
|
+
: member instanceof WeakSet
|
|
33
|
+
? member.add(obj)
|
|
34
|
+
: member.set(obj, value)
|
|
35
|
+
var __privateSet = (obj, member, value, setter) => (
|
|
36
|
+
__accessCheck(obj, member, 'write to private field'),
|
|
37
|
+
setter ? setter.call(obj, value) : member.set(obj, value),
|
|
38
|
+
value
|
|
39
|
+
)
|
|
40
|
+
var __privateMethod = (obj, member, method) => (
|
|
41
|
+
__accessCheck(obj, member, 'access private method'), method
|
|
42
|
+
)
|
|
43
|
+
var _serializationPlugins,
|
|
44
|
+
_buildPlugins,
|
|
45
|
+
_intentResolvers,
|
|
46
|
+
_inputSection,
|
|
47
|
+
_commandSection,
|
|
48
|
+
_availableResults,
|
|
49
|
+
_pendingPromises,
|
|
50
|
+
_added,
|
|
51
|
+
_data,
|
|
52
|
+
_Transaction_instances,
|
|
53
|
+
fork_fn,
|
|
54
|
+
addCommand_fn,
|
|
55
|
+
addInput_fn,
|
|
56
|
+
normalizeTransactionArgument_fn,
|
|
57
|
+
resolveArgument_fn,
|
|
58
|
+
prepareBuild_fn,
|
|
59
|
+
runPlugins_fn,
|
|
60
|
+
waitForPendingTasks_fn,
|
|
61
|
+
sortCommandsAndInputs_fn
|
|
62
|
+
|
|
63
|
+
function createTransactionResult(index, length = Infinity) {
|
|
64
|
+
const baseResult = {
|
|
65
|
+
$kind: 'Result',
|
|
66
|
+
get Result() {
|
|
67
|
+
return typeof index === 'function' ? index() : index
|
|
68
|
+
},
|
|
69
|
+
}
|
|
70
|
+
const nestedResults = []
|
|
71
|
+
const nestedResultFor = (resultIndex) =>
|
|
72
|
+
nestedResults[resultIndex] ??
|
|
73
|
+
(nestedResults[resultIndex] = {
|
|
74
|
+
$kind: 'NestedResult',
|
|
75
|
+
get NestedResult() {
|
|
76
|
+
return [typeof index === 'function' ? index() : index, resultIndex]
|
|
77
|
+
},
|
|
78
|
+
})
|
|
79
|
+
return new Proxy(baseResult, {
|
|
80
|
+
set() {
|
|
81
|
+
throw new Error(
|
|
82
|
+
'The transaction result is a proxy, and does not support setting properties directly'
|
|
83
|
+
)
|
|
84
|
+
},
|
|
85
|
+
// TODO: Instead of making this return a concrete argument, we should ideally
|
|
86
|
+
// make it reference-based (so that this gets resolved at build-time), which
|
|
87
|
+
// allows re-ordering transactions.
|
|
88
|
+
get(target, property) {
|
|
89
|
+
if (property in target) {
|
|
90
|
+
return Reflect.get(target, property)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (property === Symbol.iterator) {
|
|
94
|
+
return function* () {
|
|
95
|
+
let i = 0
|
|
96
|
+
while (i < length) {
|
|
97
|
+
yield nestedResultFor(i)
|
|
98
|
+
i++
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (typeof property === 'symbol') return
|
|
104
|
+
const resultIndex = parseInt(property, 10)
|
|
105
|
+
if (Number.isNaN(resultIndex) || resultIndex < 0) return
|
|
106
|
+
return nestedResultFor(resultIndex)
|
|
107
|
+
},
|
|
108
|
+
})
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const TRANSACTION_BRAND = Symbol.for('@mysten/transaction')
|
|
112
|
+
|
|
113
|
+
function isTransaction(obj) {
|
|
114
|
+
return !!obj && typeof obj === 'object' && obj[TRANSACTION_BRAND] === true
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const modulePluginRegistry = {
|
|
118
|
+
buildPlugins: /* @__PURE__ */ new Map(),
|
|
119
|
+
serializationPlugins: /* @__PURE__ */ new Map(),
|
|
120
|
+
}
|
|
121
|
+
const TRANSACTION_REGISTRY_KEY = Symbol.for('@mysten/transaction/registry')
|
|
122
|
+
|
|
123
|
+
function getGlobalPluginRegistry() {
|
|
124
|
+
try {
|
|
125
|
+
const target = globalThis
|
|
126
|
+
if (!target[TRANSACTION_REGISTRY_KEY]) {
|
|
127
|
+
target[TRANSACTION_REGISTRY_KEY] = modulePluginRegistry
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return target[TRANSACTION_REGISTRY_KEY]
|
|
131
|
+
} catch {
|
|
132
|
+
return modulePluginRegistry
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const _Transaction = class _Transaction {
|
|
137
|
+
constructor() {
|
|
138
|
+
__privateAdd(this, _Transaction_instances)
|
|
139
|
+
__privateAdd(this, _serializationPlugins)
|
|
140
|
+
__privateAdd(this, _buildPlugins)
|
|
141
|
+
__privateAdd(this, _intentResolvers, /* @__PURE__ */ new Map())
|
|
142
|
+
__privateAdd(this, _inputSection, [])
|
|
143
|
+
__privateAdd(this, _commandSection, [])
|
|
144
|
+
__privateAdd(this, _availableResults, /* @__PURE__ */ new Set())
|
|
145
|
+
__privateAdd(this, _pendingPromises, /* @__PURE__ */ new Set())
|
|
146
|
+
__privateAdd(this, _added, /* @__PURE__ */ new Map())
|
|
147
|
+
__privateAdd(this, _data)
|
|
148
|
+
/**
|
|
149
|
+
* Add a new object input to the transaction.
|
|
150
|
+
*/
|
|
151
|
+
this.object = createObjectMethods((value) => {
|
|
152
|
+
if (typeof value === 'function') {
|
|
153
|
+
return this.object(this.add(value))
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (typeof value === 'object' && is(Argument, value)) {
|
|
157
|
+
return value
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const id = getIdFromCallArg(value)
|
|
161
|
+
const inserted = __privateGet(this, _data).inputs.find((i) => id === getIdFromCallArg(i))
|
|
162
|
+
if (
|
|
163
|
+
inserted?.Object?.SharedObject &&
|
|
164
|
+
typeof value === 'object' &&
|
|
165
|
+
value.Object?.SharedObject
|
|
166
|
+
) {
|
|
167
|
+
inserted.Object.SharedObject.mutable =
|
|
168
|
+
inserted.Object.SharedObject.mutable || value.Object.SharedObject.mutable
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return inserted
|
|
172
|
+
? {
|
|
173
|
+
$kind: 'Input',
|
|
174
|
+
Input: __privateGet(this, _data).inputs.indexOf(inserted),
|
|
175
|
+
type: 'object',
|
|
176
|
+
}
|
|
177
|
+
: __privateMethod(this, _Transaction_instances, addInput_fn).call(
|
|
178
|
+
this,
|
|
179
|
+
'object',
|
|
180
|
+
typeof value === 'string'
|
|
181
|
+
? {
|
|
182
|
+
$kind: 'UnresolvedObject',
|
|
183
|
+
UnresolvedObject: { objectId: normalizeSuiAddress(value) },
|
|
184
|
+
}
|
|
185
|
+
: value
|
|
186
|
+
)
|
|
187
|
+
})
|
|
188
|
+
const globalPlugins = getGlobalPluginRegistry()
|
|
189
|
+
__privateSet(this, _data, new TransactionDataBuilder())
|
|
190
|
+
__privateSet(this, _buildPlugins, [...globalPlugins.buildPlugins.values()])
|
|
191
|
+
__privateSet(this, _serializationPlugins, [...globalPlugins.serializationPlugins.values()])
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Converts from a serialize transaction kind (built with `build({ onlyTransactionKind: true })`) to a `Transaction` class.
|
|
196
|
+
* Supports either a byte array, or base64-encoded bytes.
|
|
197
|
+
*/
|
|
198
|
+
static fromKind(serialized) {
|
|
199
|
+
const tx = new _Transaction()
|
|
200
|
+
__privateSet(
|
|
201
|
+
tx,
|
|
202
|
+
_data,
|
|
203
|
+
TransactionDataBuilder.fromKindBytes(
|
|
204
|
+
typeof serialized === 'string' ? fromBase64(serialized) : serialized
|
|
205
|
+
)
|
|
206
|
+
)
|
|
207
|
+
__privateSet(tx, _inputSection, [...__privateGet(tx, _data).inputs])
|
|
208
|
+
__privateSet(tx, _commandSection, [...__privateGet(tx, _data).commands])
|
|
209
|
+
__privateSet(tx, _availableResults, new Set(__privateGet(tx, _commandSection).map((_, i) => i)))
|
|
210
|
+
return tx
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Converts from a serialized transaction format to a `Transaction` class.
|
|
215
|
+
* There are two supported serialized formats:
|
|
216
|
+
* - A string returned from `Transaction#serialize`. The serialized format must be compatible, or it will throw an error.
|
|
217
|
+
* - A byte array (or base64-encoded bytes) containing BCS transaction data.
|
|
218
|
+
*/
|
|
219
|
+
static from(transaction) {
|
|
220
|
+
const newTransaction = new _Transaction()
|
|
221
|
+
if (isTransaction(transaction)) {
|
|
222
|
+
__privateSet(newTransaction, _data, new TransactionDataBuilder(transaction.getData()))
|
|
223
|
+
} else if (typeof transaction !== 'string' || !transaction.startsWith('{')) {
|
|
224
|
+
__privateSet(
|
|
225
|
+
newTransaction,
|
|
226
|
+
_data,
|
|
227
|
+
TransactionDataBuilder.fromBytes(
|
|
228
|
+
typeof transaction === 'string' ? fromBase64(transaction) : transaction
|
|
229
|
+
)
|
|
230
|
+
)
|
|
231
|
+
} else {
|
|
232
|
+
__privateSet(newTransaction, _data, TransactionDataBuilder.restore(JSON.parse(transaction)))
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
__privateSet(newTransaction, _inputSection, [...__privateGet(newTransaction, _data).inputs])
|
|
236
|
+
__privateSet(newTransaction, _commandSection, [...__privateGet(newTransaction, _data).commands])
|
|
237
|
+
__privateSet(
|
|
238
|
+
newTransaction,
|
|
239
|
+
_availableResults,
|
|
240
|
+
new Set(__privateGet(newTransaction, _commandSection).map((_, i) => i))
|
|
241
|
+
)
|
|
242
|
+
return newTransaction
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
static registerGlobalSerializationPlugin(stepOrStep, step) {
|
|
246
|
+
getGlobalPluginRegistry().serializationPlugins.set(stepOrStep, step ?? stepOrStep)
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
static unregisterGlobalSerializationPlugin(name) {
|
|
250
|
+
getGlobalPluginRegistry().serializationPlugins.delete(name)
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
static registerGlobalBuildPlugin(stepOrStep, step) {
|
|
254
|
+
getGlobalPluginRegistry().buildPlugins.set(stepOrStep, step ?? stepOrStep)
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
static unregisterGlobalBuildPlugin(name) {
|
|
258
|
+
getGlobalPluginRegistry().buildPlugins.delete(name)
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
addSerializationPlugin(step) {
|
|
262
|
+
__privateGet(this, _serializationPlugins).push(step)
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
addBuildPlugin(step) {
|
|
266
|
+
__privateGet(this, _buildPlugins).push(step)
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
addIntentResolver(intent, resolver) {
|
|
270
|
+
if (
|
|
271
|
+
__privateGet(this, _intentResolvers).has(intent) &&
|
|
272
|
+
__privateGet(this, _intentResolvers).get(intent) !== resolver
|
|
273
|
+
) {
|
|
274
|
+
throw new Error(`Intent resolver for ${intent} already exists`)
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
__privateGet(this, _intentResolvers).set(intent, resolver)
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
setSender(sender) {
|
|
281
|
+
__privateGet(this, _data).sender = sender
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Sets the sender only if it has not already been set.
|
|
286
|
+
* This is useful for sponsored transaction flows where the sender may not be the same as the signer address.
|
|
287
|
+
*/
|
|
288
|
+
setSenderIfNotSet(sender) {
|
|
289
|
+
if (!__privateGet(this, _data).sender) {
|
|
290
|
+
__privateGet(this, _data).sender = sender
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
setExpiration(expiration) {
|
|
295
|
+
__privateGet(this, _data).expiration = expiration
|
|
296
|
+
? parse(TransactionExpiration, expiration)
|
|
297
|
+
: null
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
setGasPrice(price) {
|
|
301
|
+
__privateGet(this, _data).gasConfig.price = String(price)
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
setGasBudget(budget) {
|
|
305
|
+
__privateGet(this, _data).gasConfig.budget = String(budget)
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
setGasBudgetIfNotSet(budget) {
|
|
309
|
+
if (__privateGet(this, _data).gasData.budget == null) {
|
|
310
|
+
__privateGet(this, _data).gasConfig.budget = String(budget)
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
setGasOwner(owner) {
|
|
315
|
+
__privateGet(this, _data).gasConfig.owner = owner
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
setGasPayment(payments) {
|
|
319
|
+
__privateGet(this, _data).gasConfig.payment = payments.map((payment) =>
|
|
320
|
+
parse(ObjectRef, payment)
|
|
321
|
+
)
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/** @deprecated Use `getData()` instead. */
|
|
325
|
+
get blockData() {
|
|
326
|
+
return serializeV1TransactionData(__privateGet(this, _data).snapshot())
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/** Get a snapshot of the transaction data, in JSON form: */
|
|
330
|
+
getData() {
|
|
331
|
+
return __privateGet(this, _data).snapshot()
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// Used to brand transaction classes so that they can be identified, even between multiple copies
|
|
335
|
+
// of the builder.
|
|
336
|
+
get [TRANSACTION_BRAND]() {
|
|
337
|
+
return true
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// Temporary workaround for the wallet interface accidentally serializing transactions via postMessage
|
|
341
|
+
get pure() {
|
|
342
|
+
Object.defineProperty(this, 'pure', {
|
|
343
|
+
enumerable: false,
|
|
344
|
+
value: createPure((value) => {
|
|
345
|
+
if (isSerializedBcs(value)) {
|
|
346
|
+
return __privateMethod(this, _Transaction_instances, addInput_fn).call(this, 'pure', {
|
|
347
|
+
$kind: 'Pure',
|
|
348
|
+
Pure: {
|
|
349
|
+
bytes: value.toBase64(),
|
|
350
|
+
},
|
|
351
|
+
})
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
return __privateMethod(this, _Transaction_instances, addInput_fn).call(
|
|
355
|
+
this,
|
|
356
|
+
'pure',
|
|
357
|
+
is(NormalizedCallArg, value)
|
|
358
|
+
? parse(NormalizedCallArg, value)
|
|
359
|
+
: value instanceof Uint8Array
|
|
360
|
+
? Inputs.Pure(value)
|
|
361
|
+
: { $kind: 'UnresolvedPure', UnresolvedPure: { value } }
|
|
362
|
+
)
|
|
363
|
+
}),
|
|
364
|
+
})
|
|
365
|
+
return this.pure
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/** Returns an argument for the gas coin, to be used in a transaction. */
|
|
369
|
+
get gas() {
|
|
370
|
+
return { $kind: 'GasCoin', GasCoin: true }
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* Add a new object input to the transaction using the fully-resolved object reference.
|
|
375
|
+
* If you only have an object ID, use `builder.object(id)` instead.
|
|
376
|
+
*/
|
|
377
|
+
objectRef(...args) {
|
|
378
|
+
return this.object(Inputs.ObjectRef(...args))
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Add a new receiving input to the transaction using the fully-resolved object reference.
|
|
383
|
+
* If you only have an object ID, use `builder.object(id)` instead.
|
|
384
|
+
*/
|
|
385
|
+
receivingRef(...args) {
|
|
386
|
+
return this.object(Inputs.ReceivingRef(...args))
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
/**
|
|
390
|
+
* Add a new shared object input to the transaction using the fully-resolved shared object reference.
|
|
391
|
+
* If you only have an object ID, use `builder.object(id)` instead.
|
|
392
|
+
*/
|
|
393
|
+
sharedObjectRef(...args) {
|
|
394
|
+
return this.object(Inputs.SharedObjectRef(...args))
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
add(command) {
|
|
398
|
+
if (typeof command === 'function') {
|
|
399
|
+
if (__privateGet(this, _added).has(command)) {
|
|
400
|
+
return __privateGet(this, _added).get(command)
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
const fork = __privateMethod(this, _Transaction_instances, fork_fn).call(this)
|
|
404
|
+
const result = command(fork)
|
|
405
|
+
if (!(result && typeof result === 'object' && 'then' in result)) {
|
|
406
|
+
__privateSet(this, _availableResults, __privateGet(fork, _availableResults))
|
|
407
|
+
__privateGet(this, _added).set(command, result)
|
|
408
|
+
return result
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
const placeholder = __privateMethod(this, _Transaction_instances, addCommand_fn).call(this, {
|
|
412
|
+
$kind: '$Intent',
|
|
413
|
+
$Intent: {
|
|
414
|
+
name: 'AsyncTransactionThunk',
|
|
415
|
+
inputs: Object.create(null),
|
|
416
|
+
data: {
|
|
417
|
+
resultIndex: __privateGet(this, _data).commands.length,
|
|
418
|
+
result: null,
|
|
419
|
+
},
|
|
420
|
+
},
|
|
421
|
+
})
|
|
422
|
+
__privateGet(this, _pendingPromises).add(
|
|
423
|
+
Promise.resolve(result).then((result2) => {
|
|
424
|
+
placeholder.$Intent.data.result = result2
|
|
425
|
+
})
|
|
426
|
+
)
|
|
427
|
+
const txResult = createTransactionResult(() => placeholder.$Intent.data.resultIndex)
|
|
428
|
+
__privateGet(this, _added).set(command, txResult)
|
|
429
|
+
return txResult
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
__privateMethod(this, _Transaction_instances, addCommand_fn).call(this, command)
|
|
433
|
+
|
|
434
|
+
return createTransactionResult(__privateGet(this, _data).commands.length - 1)
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
// Method shorthands:
|
|
438
|
+
splitCoins(coin, amounts) {
|
|
439
|
+
const command = Commands.SplitCoins(
|
|
440
|
+
typeof coin === 'string'
|
|
441
|
+
? this.object(coin)
|
|
442
|
+
: __privateMethod(this, _Transaction_instances, resolveArgument_fn).call(this, coin),
|
|
443
|
+
amounts.map((amount) =>
|
|
444
|
+
typeof amount === 'number' || typeof amount === 'bigint' || typeof amount === 'string'
|
|
445
|
+
? this.pure.u64(amount)
|
|
446
|
+
: __privateMethod(this, _Transaction_instances, normalizeTransactionArgument_fn).call(
|
|
447
|
+
this,
|
|
448
|
+
amount
|
|
449
|
+
)
|
|
450
|
+
)
|
|
451
|
+
)
|
|
452
|
+
__privateMethod(this, _Transaction_instances, addCommand_fn).call(this, command)
|
|
453
|
+
return createTransactionResult(__privateGet(this, _data).commands.length - 1, amounts.length)
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
mergeCoins(destination, sources) {
|
|
457
|
+
return this.add(
|
|
458
|
+
Commands.MergeCoins(
|
|
459
|
+
this.object(destination),
|
|
460
|
+
sources.map((src) => this.object(src))
|
|
461
|
+
)
|
|
462
|
+
)
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
publish({ modules, dependencies }) {
|
|
466
|
+
return this.add(
|
|
467
|
+
Commands.Publish({
|
|
468
|
+
modules,
|
|
469
|
+
dependencies,
|
|
470
|
+
})
|
|
471
|
+
)
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
upgrade({ modules, dependencies, package: packageId, ticket }) {
|
|
475
|
+
return this.add(
|
|
476
|
+
Commands.Upgrade({
|
|
477
|
+
modules,
|
|
478
|
+
dependencies,
|
|
479
|
+
package: packageId,
|
|
480
|
+
ticket: this.object(ticket),
|
|
481
|
+
})
|
|
482
|
+
)
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
moveCall({ arguments: args, ...input }) {
|
|
486
|
+
return this.add(
|
|
487
|
+
Commands.MoveCall({
|
|
488
|
+
...input,
|
|
489
|
+
arguments: args?.map((arg) =>
|
|
490
|
+
__privateMethod(this, _Transaction_instances, normalizeTransactionArgument_fn).call(
|
|
491
|
+
this,
|
|
492
|
+
arg
|
|
493
|
+
)
|
|
494
|
+
),
|
|
495
|
+
})
|
|
496
|
+
)
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
transferObjects(objects, address) {
|
|
500
|
+
return this.add(
|
|
501
|
+
Commands.TransferObjects(
|
|
502
|
+
objects.map((obj) => this.object(obj)),
|
|
503
|
+
typeof address === 'string'
|
|
504
|
+
? this.pure.address(address)
|
|
505
|
+
: __privateMethod(this, _Transaction_instances, normalizeTransactionArgument_fn).call(
|
|
506
|
+
this,
|
|
507
|
+
address
|
|
508
|
+
)
|
|
509
|
+
)
|
|
510
|
+
)
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
makeMoveVec({ type, elements }) {
|
|
514
|
+
return this.add(
|
|
515
|
+
Commands.MakeMoveVec({
|
|
516
|
+
type,
|
|
517
|
+
elements: elements.map((obj) => this.object(obj)),
|
|
518
|
+
})
|
|
519
|
+
)
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
/**
|
|
523
|
+
* @deprecated Use toJSON instead.
|
|
524
|
+
* For synchronous serialization, you can use `getData()`
|
|
525
|
+
*/
|
|
526
|
+
serialize() {
|
|
527
|
+
return JSON.stringify(serializeV1TransactionData(__privateGet(this, _data).snapshot()))
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
async toJSON(options = Object.create(null)) {
|
|
531
|
+
await this.prepareForSerialization(options)
|
|
532
|
+
const fullyResolved = this.isFullyResolved()
|
|
533
|
+
return JSON.stringify(
|
|
534
|
+
parse(
|
|
535
|
+
SerializedTransactionDataV2,
|
|
536
|
+
fullyResolved
|
|
537
|
+
? {
|
|
538
|
+
...__privateGet(this, _data).snapshot(),
|
|
539
|
+
digest: __privateGet(this, _data).getDigest(),
|
|
540
|
+
}
|
|
541
|
+
: __privateGet(this, _data).snapshot()
|
|
542
|
+
),
|
|
543
|
+
(_key, value) => (typeof value === 'bigint' ? value.toString() : value),
|
|
544
|
+
2
|
|
545
|
+
)
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
/** Build the transaction to BCS bytes, and sign it with the provided keypair. */
|
|
549
|
+
async sign(options) {
|
|
550
|
+
const { signer, ...buildOptions } = options
|
|
551
|
+
const bytes = await this.build(buildOptions)
|
|
552
|
+
return signer.signTransaction(bytes)
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
/**
|
|
556
|
+
* Ensures that:
|
|
557
|
+
* - All objects have been fully resolved to a specific version
|
|
558
|
+
* - All pure inputs have been serialized to bytes
|
|
559
|
+
* - All async thunks have been fully resolved
|
|
560
|
+
* - All transaction intents have been resolved
|
|
561
|
+
* - The gas payment, budget, and price have been set
|
|
562
|
+
* - The transaction sender has been set
|
|
563
|
+
*
|
|
564
|
+
* When true, the transaction will always be built to the same bytes and digest (unless the transaction is mutated)
|
|
565
|
+
*/
|
|
566
|
+
isFullyResolved() {
|
|
567
|
+
if (!__privateGet(this, _data).sender) {
|
|
568
|
+
return false
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
if (__privateGet(this, _pendingPromises).size > 0) {
|
|
572
|
+
return false
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
if (__privateGet(this, _data).commands.some((cmd) => cmd.$Intent)) {
|
|
576
|
+
return false
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
// eslint-disable-next-line sonarjs/prefer-single-boolean-return
|
|
580
|
+
if (needsTransactionResolution(__privateGet(this, _data), Object.create(null))) {
|
|
581
|
+
return false
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
return true
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
/** Build the transaction to BCS bytes. */
|
|
588
|
+
async build(options = Object.create(null)) {
|
|
589
|
+
await this.prepareForSerialization(options)
|
|
590
|
+
await __privateMethod(this, _Transaction_instances, prepareBuild_fn).call(this, options)
|
|
591
|
+
return __privateGet(this, _data).build({
|
|
592
|
+
onlyTransactionKind: options.onlyTransactionKind,
|
|
593
|
+
})
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
/** Derive transaction digest */
|
|
597
|
+
async getDigest(options = Object.create(null)) {
|
|
598
|
+
await this.prepareForSerialization(options)
|
|
599
|
+
await __privateMethod(this, _Transaction_instances, prepareBuild_fn).call(this, options)
|
|
600
|
+
return __privateGet(this, _data).getDigest()
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
async prepareForSerialization(options) {
|
|
604
|
+
await __privateMethod(this, _Transaction_instances, waitForPendingTasks_fn).call(this)
|
|
605
|
+
__privateMethod(this, _Transaction_instances, sortCommandsAndInputs_fn).call(this)
|
|
606
|
+
const intents = /* @__PURE__ */ new Set()
|
|
607
|
+
for (const command of __privateGet(this, _data).commands) {
|
|
608
|
+
if (command.$Intent) {
|
|
609
|
+
intents.add(command.$Intent.name)
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
const steps = [...__privateGet(this, _serializationPlugins)]
|
|
614
|
+
for (const intent of intents) {
|
|
615
|
+
if (options.supportedIntents?.includes(intent)) {
|
|
616
|
+
continue
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
if (!__privateGet(this, _intentResolvers).has(intent)) {
|
|
620
|
+
throw new Error(`Missing intent resolver for ${intent}`)
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
steps.push(__privateGet(this, _intentResolvers).get(intent))
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
steps.push(namedPackagesPlugin())
|
|
627
|
+
await __privateMethod(this, _Transaction_instances, runPlugins_fn).call(this, steps, options)
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
_serializationPlugins = new WeakMap()
|
|
631
|
+
_buildPlugins = new WeakMap()
|
|
632
|
+
_intentResolvers = new WeakMap()
|
|
633
|
+
_inputSection = new WeakMap()
|
|
634
|
+
_commandSection = new WeakMap()
|
|
635
|
+
_availableResults = new WeakMap()
|
|
636
|
+
_pendingPromises = new WeakMap()
|
|
637
|
+
_added = new WeakMap()
|
|
638
|
+
_data = new WeakMap()
|
|
639
|
+
_Transaction_instances = new WeakSet()
|
|
640
|
+
fork_fn = function () {
|
|
641
|
+
const fork = new _Transaction()
|
|
642
|
+
__privateSet(fork, _data, __privateGet(this, _data))
|
|
643
|
+
__privateSet(fork, _serializationPlugins, __privateGet(this, _serializationPlugins))
|
|
644
|
+
__privateSet(fork, _buildPlugins, __privateGet(this, _buildPlugins))
|
|
645
|
+
__privateSet(fork, _intentResolvers, __privateGet(this, _intentResolvers))
|
|
646
|
+
__privateSet(fork, _pendingPromises, __privateGet(this, _pendingPromises))
|
|
647
|
+
__privateSet(fork, _availableResults, new Set(__privateGet(this, _availableResults)))
|
|
648
|
+
__privateSet(fork, _added, __privateGet(this, _added))
|
|
649
|
+
__privateGet(this, _inputSection).push(__privateGet(fork, _inputSection))
|
|
650
|
+
__privateGet(this, _commandSection).push(__privateGet(fork, _commandSection))
|
|
651
|
+
return fork
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
addCommand_fn = function (command) {
|
|
655
|
+
const resultIndex = __privateGet(this, _data).commands.length
|
|
656
|
+
__privateGet(this, _commandSection).push(command)
|
|
657
|
+
__privateGet(this, _availableResults).add(resultIndex)
|
|
658
|
+
__privateGet(this, _data).commands.push(command)
|
|
659
|
+
__privateGet(this, _data).mapCommandArguments(resultIndex, (arg) => {
|
|
660
|
+
if (arg.$kind === 'Result' && !__privateGet(this, _availableResults).has(arg.Result)) {
|
|
661
|
+
throw new Error(
|
|
662
|
+
`Result { Result: ${arg.Result} } is not available to use the current transaction`
|
|
663
|
+
)
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
if (
|
|
667
|
+
arg.$kind === 'NestedResult' &&
|
|
668
|
+
!__privateGet(this, _availableResults).has(arg.NestedResult[0])
|
|
669
|
+
) {
|
|
670
|
+
throw new Error(
|
|
671
|
+
`Result { NestedResult: [${arg.NestedResult[0]}, ${arg.NestedResult[1]}] } is not available to use the current transaction`
|
|
672
|
+
)
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
if (arg.$kind === 'Input' && arg.Input >= __privateGet(this, _data).inputs.length) {
|
|
676
|
+
throw new Error(
|
|
677
|
+
`Input { Input: ${arg.Input} } references an input that does not exist in the current transaction`
|
|
678
|
+
)
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
return arg
|
|
682
|
+
})
|
|
683
|
+
return command
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
addInput_fn = function (type, input) {
|
|
687
|
+
__privateGet(this, _inputSection).push(input)
|
|
688
|
+
return __privateGet(this, _data).addInput(type, input)
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
normalizeTransactionArgument_fn = function (arg) {
|
|
692
|
+
if (isSerializedBcs(arg)) {
|
|
693
|
+
return this.pure(arg)
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
return __privateMethod(this, _Transaction_instances, resolveArgument_fn).call(this, arg)
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
resolveArgument_fn = function (arg) {
|
|
700
|
+
if (typeof arg === 'function') {
|
|
701
|
+
const resolved = this.add(arg)
|
|
702
|
+
if (typeof resolved === 'function') {
|
|
703
|
+
return __privateMethod(this, _Transaction_instances, resolveArgument_fn).call(this, resolved)
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
return parse(Argument, resolved)
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
return parse(Argument, arg)
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
prepareBuild_fn = async function (options) {
|
|
713
|
+
if (!options.onlyTransactionKind && !__privateGet(this, _data).sender) {
|
|
714
|
+
throw new Error('Missing transaction sender')
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
await __privateMethod(this, _Transaction_instances, runPlugins_fn).call(
|
|
718
|
+
this,
|
|
719
|
+
[...__privateGet(this, _buildPlugins), resolveTransactionPlugin],
|
|
720
|
+
options
|
|
721
|
+
)
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
runPlugins_fn = async function (plugins, options) {
|
|
725
|
+
const createNext = (i) => {
|
|
726
|
+
if (i >= plugins.length) {
|
|
727
|
+
return () => Object.create(null)
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
const plugin = plugins[i]
|
|
731
|
+
return async () => {
|
|
732
|
+
const next = createNext(i + 1)
|
|
733
|
+
let calledNext = false
|
|
734
|
+
let nextResolved = false
|
|
735
|
+
await plugin(__privateGet(this, _data), options, async () => {
|
|
736
|
+
if (calledNext) {
|
|
737
|
+
throw new Error(`next() was call multiple times in TransactionPlugin ${i}`)
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
calledNext = true
|
|
741
|
+
await next()
|
|
742
|
+
nextResolved = true
|
|
743
|
+
})
|
|
744
|
+
if (!calledNext) {
|
|
745
|
+
throw new Error(`next() was not called in TransactionPlugin ${i}`)
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
if (!nextResolved) {
|
|
749
|
+
throw new Error(`next() was not awaited in TransactionPlugin ${i}`)
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
await createNext(0)()
|
|
755
|
+
__privateSet(this, _inputSection, [...__privateGet(this, _data).inputs])
|
|
756
|
+
__privateSet(this, _commandSection, [...__privateGet(this, _data).commands])
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
waitForPendingTasks_fn = async function () {
|
|
760
|
+
while (__privateGet(this, _pendingPromises).size > 0) {
|
|
761
|
+
const newPromise = Promise.all(__privateGet(this, _pendingPromises))
|
|
762
|
+
__privateGet(this, _pendingPromises).clear()
|
|
763
|
+
__privateGet(this, _pendingPromises).add(newPromise)
|
|
764
|
+
await newPromise
|
|
765
|
+
__privateGet(this, _pendingPromises).delete(newPromise)
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
sortCommandsAndInputs_fn = function () {
|
|
770
|
+
const unorderedCommands = __privateGet(this, _data).commands
|
|
771
|
+
const unorderedInputs = __privateGet(this, _data).inputs
|
|
772
|
+
const orderedCommands = __privateGet(this, _commandSection).flat(Infinity)
|
|
773
|
+
const orderedInputs = __privateGet(this, _inputSection).flat(Infinity)
|
|
774
|
+
if (orderedCommands.length !== unorderedCommands.length) {
|
|
775
|
+
throw new Error('Unexpected number of commands found in transaction data')
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
if (orderedInputs.length !== unorderedInputs.length) {
|
|
779
|
+
throw new Error('Unexpected number of inputs found in transaction data')
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
const filteredCommands = orderedCommands.filter(
|
|
783
|
+
(cmd) => cmd.$Intent?.name !== 'AsyncTransactionThunk'
|
|
784
|
+
)
|
|
785
|
+
__privateGet(this, _data).commands = filteredCommands
|
|
786
|
+
__privateGet(this, _data).inputs = orderedInputs
|
|
787
|
+
__privateSet(this, _commandSection, filteredCommands)
|
|
788
|
+
__privateSet(this, _inputSection, orderedInputs)
|
|
789
|
+
__privateSet(this, _availableResults, new Set(filteredCommands.map((_, i) => i)))
|
|
790
|
+
|
|
791
|
+
function getOriginalIndex(index) {
|
|
792
|
+
const command = unorderedCommands[index]
|
|
793
|
+
if (command.$Intent?.name === 'AsyncTransactionThunk') {
|
|
794
|
+
const result = command.$Intent.data.result
|
|
795
|
+
if (result == null) {
|
|
796
|
+
throw new Error('AsyncTransactionThunk has not been resolved')
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
return getOriginalIndex(result.Result)
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
const updated = filteredCommands.indexOf(command)
|
|
803
|
+
if (updated === -1) {
|
|
804
|
+
throw new Error('Unable to find original index for command')
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
return updated
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
__privateGet(this, _data).mapArguments((arg) => {
|
|
811
|
+
if (arg.$kind === 'Input') {
|
|
812
|
+
const updated = orderedInputs.indexOf(unorderedInputs[arg.Input])
|
|
813
|
+
if (updated === -1) {
|
|
814
|
+
throw new Error('Input has not been resolved')
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
return { ...arg, Input: updated }
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
if (arg.$kind === 'Result') {
|
|
821
|
+
const updated = getOriginalIndex(arg.Result)
|
|
822
|
+
return { ...arg, Result: updated }
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
if (arg.$kind === 'NestedResult') {
|
|
826
|
+
const updated = getOriginalIndex(arg.NestedResult[0])
|
|
827
|
+
return { ...arg, NestedResult: [updated, arg.NestedResult[1]] }
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
return arg
|
|
831
|
+
})
|
|
832
|
+
for (const [i, cmd] of unorderedCommands.entries()) {
|
|
833
|
+
if (cmd.$Intent?.name === 'AsyncTransactionThunk') {
|
|
834
|
+
try {
|
|
835
|
+
cmd.$Intent.data.resultIndex = getOriginalIndex(i)
|
|
836
|
+
} catch {}
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
const Transaction = _Transaction
|
|
842
|
+
export { Transaction, isTransaction }
|
|
843
|
+
// # sourceMappingURL=Transaction.js.map
|