@layerzerolabs/gated-transaction 0.0.29 → 0.0.31
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/.turbo/turbo-build.log +34 -34
- package/.turbo/turbo-test.log +4 -4
- package/dist/{AYIRG6WY.cjs → 3SOQJCDG.cjs} +16 -4
- package/dist/3SOQJCDG.cjs.map +1 -0
- package/dist/{QGZD4SJ4.cjs → 422FLJZW.cjs} +5 -5
- package/dist/422FLJZW.cjs.map +1 -0
- package/dist/{6NWNACVT.cjs → 4ND4S3IS.cjs} +23 -24
- package/dist/4ND4S3IS.cjs.map +1 -0
- package/dist/{CG43CWKE.js → BCFOKBQQ.js} +105 -51
- package/dist/BCFOKBQQ.js.map +1 -0
- package/dist/{GMAAYDJ4.js → PGJAXI5M.js} +23 -25
- package/dist/PGJAXI5M.js.map +1 -0
- package/dist/{DBJG544E.js → TLPNG7S6.js} +3 -3
- package/dist/TLPNG7S6.js.map +1 -0
- package/dist/{XYULD3ZM.cjs → TYY6L3E5.cjs} +109 -55
- package/dist/TYY6L3E5.cjs.map +1 -0
- package/dist/WWHK47IY.js +25 -0
- package/dist/WWHK47IY.js.map +1 -0
- package/dist/gatedTransactionSignalLock.cjs +5 -5
- package/dist/gatedTransactionSignalLock.d.ts +2 -4
- package/dist/gatedTransactionSignalLock.d.ts.map +1 -1
- package/dist/gatedTransactionSignalLock.js +2 -2
- package/dist/gatedTx.cjs +7 -3
- package/dist/gatedTx.d.ts +28 -5
- package/dist/gatedTx.d.ts.map +1 -1
- package/dist/gatedTx.js +1 -1
- package/dist/index.cjs +25 -17
- package/dist/index.js +4 -4
- package/dist/resolver.cjs +5 -5
- package/dist/resolver.d.ts +6 -10
- package/dist/resolver.d.ts.map +1 -1
- package/dist/resolver.js +3 -3
- package/dist/types.cjs +11 -7
- package/dist/types.d.ts +52 -72
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -1
- package/package.json +9 -8
- package/src/gatedTransactionSignalLock.ts +3 -6
- package/src/gatedTx.ts +53 -6
- package/src/resolver.ts +150 -57
- package/src/types.ts +134 -76
- package/test/resolver.test.ts +151 -6
- package/dist/5INFRBMB.js +0 -14
- package/dist/5INFRBMB.js.map +0 -1
- package/dist/6NWNACVT.cjs.map +0 -1
- package/dist/AYIRG6WY.cjs.map +0 -1
- package/dist/CG43CWKE.js.map +0 -1
- package/dist/DBJG544E.js.map +0 -1
- package/dist/GMAAYDJ4.js.map +0 -1
- package/dist/QGZD4SJ4.cjs.map +0 -1
- package/dist/XYULD3ZM.cjs.map +0 -1
package/src/resolver.ts
CHANGED
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
import isEqual from 'lodash.isequal';
|
|
2
2
|
|
|
3
3
|
import type { ActivityRegistry } from '@layerzerolabs/common-activities';
|
|
4
|
-
import type {
|
|
4
|
+
import type {
|
|
5
|
+
Transaction,
|
|
6
|
+
TransactionResult,
|
|
7
|
+
TransactionWithResult,
|
|
8
|
+
} from '@layerzerolabs/common-chain-model';
|
|
5
9
|
import type { WorkflowFunctions } from '@layerzerolabs/common-workflow';
|
|
6
10
|
|
|
7
11
|
import { getIdForGatedTransaction } from './gatedTx';
|
|
8
12
|
import type {
|
|
13
|
+
BaseGatedTransactionFor,
|
|
9
14
|
GatedTransaction,
|
|
10
15
|
GatedTransactionId,
|
|
11
|
-
GatedTransactionResult,
|
|
12
16
|
IGatedTransactionCache,
|
|
13
17
|
InferOnChainDataTypeFromGatedTransaction,
|
|
18
|
+
ResolvedGatedTransaction,
|
|
19
|
+
ResolvedGatedTransactionDependencies,
|
|
14
20
|
UserInteractionCallbacks,
|
|
15
21
|
} from './types';
|
|
16
22
|
import { GatedTransactionStatus } from './types';
|
|
@@ -20,16 +26,19 @@ type OnChainCheckResult<DataType = any> = {
|
|
|
20
26
|
onChainData: DataType;
|
|
21
27
|
};
|
|
22
28
|
|
|
23
|
-
const checkGatedTransaction = async <
|
|
29
|
+
const checkGatedTransaction = async <
|
|
30
|
+
GatedTx extends GatedTransaction,
|
|
31
|
+
TxWithResult extends TransactionWithResult,
|
|
32
|
+
>({
|
|
24
33
|
registry,
|
|
25
34
|
gatedTransaction,
|
|
26
35
|
cachedCheckResult,
|
|
27
|
-
|
|
36
|
+
submittedTransaction,
|
|
28
37
|
}: {
|
|
29
38
|
registry: ActivityRegistry;
|
|
30
39
|
gatedTransaction: GatedTx;
|
|
31
40
|
cachedCheckResult?: InferOnChainDataTypeFromGatedTransaction<GatedTx>;
|
|
32
|
-
|
|
41
|
+
submittedTransaction?: TxWithResult;
|
|
33
42
|
}): Promise<OnChainCheckResult<InferOnChainDataTypeFromGatedTransaction<GatedTx>>> => {
|
|
34
43
|
let onChainData: InferOnChainDataTypeFromGatedTransaction<GatedTx>;
|
|
35
44
|
if (cachedCheckResult !== undefined) {
|
|
@@ -37,8 +46,8 @@ const checkGatedTransaction = async <GatedTx extends GatedTransaction>({
|
|
|
37
46
|
} else {
|
|
38
47
|
// Always inject the processed transaction as the last parameter when available
|
|
39
48
|
let params = gatedTransaction.check.params;
|
|
40
|
-
if (
|
|
41
|
-
params = [...gatedTransaction.check.params,
|
|
49
|
+
if (submittedTransaction !== undefined) {
|
|
50
|
+
params = [...gatedTransaction.check.params, submittedTransaction];
|
|
42
51
|
}
|
|
43
52
|
|
|
44
53
|
onChainData = await registry.callByPointer(gatedTransaction.check.functionPointer, params);
|
|
@@ -91,15 +100,33 @@ const checkGatedTransaction = async <GatedTx extends GatedTransaction>({
|
|
|
91
100
|
};
|
|
92
101
|
};
|
|
93
102
|
|
|
103
|
+
const extractGatedTransactionUnderlyingTransaction = async <
|
|
104
|
+
GatedTx extends GatedTransaction,
|
|
105
|
+
TxType extends Transaction,
|
|
106
|
+
>({
|
|
107
|
+
registry,
|
|
108
|
+
gatedTransaction,
|
|
109
|
+
deps,
|
|
110
|
+
}: {
|
|
111
|
+
registry: ActivityRegistry;
|
|
112
|
+
gatedTransaction: GatedTx;
|
|
113
|
+
deps: ResolvedGatedTransactionDependencies<GatedTx>;
|
|
114
|
+
}): Promise<TxType> => {
|
|
115
|
+
if (gatedTransaction.transactionType === 'literal') {
|
|
116
|
+
return gatedTransaction.transaction as TxType;
|
|
117
|
+
} else {
|
|
118
|
+
return await registry.callByPointer(gatedTransaction.getTransactionPointer, [deps]);
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
|
|
94
122
|
const resolveGatedTransaction = async <
|
|
95
123
|
TxType extends Transaction,
|
|
96
|
-
ProcessedTxType extends Transaction,
|
|
97
124
|
GatedTx extends GatedTransaction<string, TxType, any>,
|
|
98
|
-
ProcessTx extends (transaction: TxType) => Promise<
|
|
125
|
+
ProcessTx extends (transaction: TxType) => Promise<TransactionResult>,
|
|
99
126
|
>({
|
|
100
127
|
activityRegistry,
|
|
101
128
|
gatedTx,
|
|
102
|
-
|
|
129
|
+
getTransactionResult,
|
|
103
130
|
processTx,
|
|
104
131
|
confirmationCallback,
|
|
105
132
|
fn,
|
|
@@ -108,27 +135,49 @@ const resolveGatedTransaction = async <
|
|
|
108
135
|
activityRegistry: ActivityRegistry;
|
|
109
136
|
gatedTx: GatedTx;
|
|
110
137
|
processTx: ProcessTx;
|
|
111
|
-
|
|
138
|
+
getTransactionResult: (gtxId: GatedTransactionId) =>
|
|
139
|
+
| {
|
|
140
|
+
resolved?: ResolvedGatedTransaction;
|
|
141
|
+
checkResult: { onChainData?: any; expectationMet: boolean };
|
|
142
|
+
}
|
|
143
|
+
| undefined;
|
|
112
144
|
confirmationCallback: NonNullable<UserInteractionCallbacks['confirmationCallback']>;
|
|
113
145
|
fn: WorkflowFunctions;
|
|
114
146
|
cache?: IGatedTransactionCache;
|
|
115
|
-
}): Promise<
|
|
147
|
+
}): Promise<{
|
|
148
|
+
resolvedGatedTransaction: ResolvedGatedTransaction<GatedTx>;
|
|
149
|
+
lastCheckResult: OnChainCheckResult | null;
|
|
150
|
+
}> => {
|
|
151
|
+
const baseGatedTx = {
|
|
152
|
+
name: gatedTx.name,
|
|
153
|
+
chainName: gatedTx.chainName,
|
|
154
|
+
bundleName: gatedTx.bundleName,
|
|
155
|
+
check: gatedTx.check,
|
|
156
|
+
dependencies: gatedTx.dependencies,
|
|
157
|
+
cacheable: gatedTx.cacheable,
|
|
158
|
+
uniqueIdKeys: gatedTx.uniqueIdKeys,
|
|
159
|
+
} as BaseGatedTransactionFor<GatedTx>;
|
|
160
|
+
|
|
116
161
|
const dependencyIds = (gatedTx.dependencies ?? []).map((tx) => getIdForGatedTransaction(tx));
|
|
117
162
|
|
|
118
|
-
const dependenciesAreAllProcessed = () =>
|
|
119
|
-
dependencyIds.every((id) => isTransactionSuccessful(id) != null);
|
|
163
|
+
const dependenciesAreAllProcessed = () => dependencyIds.every((id) => getTransactionResult(id));
|
|
120
164
|
|
|
121
165
|
await fn.condition(dependenciesAreAllProcessed);
|
|
122
166
|
|
|
123
167
|
//check that the dependencies succeeded
|
|
124
|
-
const dependenciesWereSuccessful = dependencyIds.every(
|
|
168
|
+
const dependenciesWereSuccessful = dependencyIds.every(
|
|
169
|
+
(id) => getTransactionResult(id)?.checkResult.expectationMet,
|
|
170
|
+
);
|
|
125
171
|
|
|
126
172
|
if (!dependenciesWereSuccessful) {
|
|
127
173
|
return {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
174
|
+
resolvedGatedTransaction: {
|
|
175
|
+
...baseGatedTx,
|
|
176
|
+
result: {
|
|
177
|
+
status: GatedTransactionStatus.DEPENDENCY_FAILED,
|
|
178
|
+
},
|
|
131
179
|
},
|
|
180
|
+
lastCheckResult: null,
|
|
132
181
|
};
|
|
133
182
|
}
|
|
134
183
|
|
|
@@ -143,10 +192,13 @@ const resolveGatedTransaction = async <
|
|
|
143
192
|
if (initialCheckResult.expectationMet) {
|
|
144
193
|
//already met
|
|
145
194
|
return {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
195
|
+
resolvedGatedTransaction: {
|
|
196
|
+
...baseGatedTx,
|
|
197
|
+
result: {
|
|
198
|
+
status: GatedTransactionStatus.NO_OP,
|
|
199
|
+
},
|
|
149
200
|
},
|
|
201
|
+
lastCheckResult: initialCheckResult,
|
|
150
202
|
};
|
|
151
203
|
}
|
|
152
204
|
|
|
@@ -154,20 +206,33 @@ const resolveGatedTransaction = async <
|
|
|
154
206
|
const confirmation = await confirmationCallback(gatedTx);
|
|
155
207
|
if (!confirmation) {
|
|
156
208
|
return {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
209
|
+
resolvedGatedTransaction: {
|
|
210
|
+
...baseGatedTx,
|
|
211
|
+
result: {
|
|
212
|
+
status: GatedTransactionStatus.DENIED,
|
|
213
|
+
},
|
|
160
214
|
},
|
|
215
|
+
lastCheckResult: initialCheckResult,
|
|
161
216
|
};
|
|
162
217
|
}
|
|
163
218
|
|
|
164
219
|
//send the tx
|
|
165
220
|
try {
|
|
166
|
-
const
|
|
221
|
+
const depsResults = gatedTx.dependencies.map(
|
|
222
|
+
(dep) => getTransactionResult(getIdForGatedTransaction(dep))!.resolved!,
|
|
223
|
+
) as ResolvedGatedTransactionDependencies<GatedTx>;
|
|
224
|
+
// get the underlying calldata
|
|
225
|
+
const underlying = await extractGatedTransactionUnderlyingTransaction<GatedTx, TxType>({
|
|
226
|
+
registry: activityRegistry,
|
|
227
|
+
gatedTransaction: gatedTx,
|
|
228
|
+
deps: depsResults,
|
|
229
|
+
});
|
|
230
|
+
const processResult = await processTx(underlying);
|
|
231
|
+
const submittedTransaction = { ...underlying, result: processResult };
|
|
167
232
|
const finalCheckResult = await checkGatedTransaction({
|
|
168
233
|
registry: activityRegistry,
|
|
169
234
|
gatedTransaction: gatedTx,
|
|
170
|
-
|
|
235
|
+
submittedTransaction,
|
|
171
236
|
});
|
|
172
237
|
|
|
173
238
|
await cache?.cacheSuccessfulTxCheckData?.(gatedTx, finalCheckResult.onChainData);
|
|
@@ -175,11 +240,14 @@ const resolveGatedTransaction = async <
|
|
|
175
240
|
if (finalCheckResult.expectationMet) {
|
|
176
241
|
//sent and successful
|
|
177
242
|
return {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
243
|
+
resolvedGatedTransaction: {
|
|
244
|
+
...baseGatedTx,
|
|
245
|
+
result: {
|
|
246
|
+
status: GatedTransactionStatus.SUCCESS,
|
|
247
|
+
submittedTransaction,
|
|
248
|
+
},
|
|
182
249
|
},
|
|
250
|
+
lastCheckResult: finalCheckResult,
|
|
183
251
|
};
|
|
184
252
|
} else {
|
|
185
253
|
//sent and unsuccessful
|
|
@@ -189,31 +257,36 @@ const resolveGatedTransaction = async <
|
|
|
189
257
|
`Gated transaction ${gatedTx.name} final check failed:\nExpected result ${stringify(gatedTx.check.expectedResult.comparisonValue)}, but got:\n${stringify(finalCheckResult.onChainData)}`,
|
|
190
258
|
);
|
|
191
259
|
return {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
260
|
+
resolvedGatedTransaction: {
|
|
261
|
+
...baseGatedTx,
|
|
262
|
+
result: {
|
|
263
|
+
status: GatedTransactionStatus.FINAL_CHECK_FAILED,
|
|
264
|
+
submittedTransaction,
|
|
265
|
+
finalOnChainState: finalCheckResult.onChainData,
|
|
266
|
+
},
|
|
197
267
|
},
|
|
268
|
+
lastCheckResult: finalCheckResult,
|
|
198
269
|
};
|
|
199
270
|
}
|
|
200
271
|
} catch (e) {
|
|
201
272
|
//sent and failed
|
|
202
273
|
return {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
274
|
+
resolvedGatedTransaction: {
|
|
275
|
+
...baseGatedTx,
|
|
276
|
+
result: {
|
|
277
|
+
status: GatedTransactionStatus.TRANSACTION_FAILED,
|
|
278
|
+
transactionError: e,
|
|
279
|
+
},
|
|
207
280
|
},
|
|
281
|
+
lastCheckResult: initialCheckResult,
|
|
208
282
|
};
|
|
209
283
|
}
|
|
210
284
|
};
|
|
211
285
|
|
|
212
286
|
export const resolveGatedTransactions = async <
|
|
213
287
|
TxType extends Transaction,
|
|
214
|
-
ProcessedTxType extends Transaction,
|
|
215
288
|
GatedTx extends GatedTransaction<string, TxType, any>,
|
|
216
|
-
ProcessTx extends (transaction: TxType) => Promise<
|
|
289
|
+
ProcessTx extends (transaction: TxType) => Promise<TransactionResult>,
|
|
217
290
|
>({
|
|
218
291
|
activityRegistry,
|
|
219
292
|
gatedTxes,
|
|
@@ -228,7 +301,7 @@ export const resolveGatedTransactions = async <
|
|
|
228
301
|
fn: WorkflowFunctions;
|
|
229
302
|
cache?: IGatedTransactionCache;
|
|
230
303
|
userInteractionCallbacks?: UserInteractionCallbacks;
|
|
231
|
-
}): Promise<
|
|
304
|
+
}): Promise<ResolvedGatedTransaction[]> => {
|
|
232
305
|
//compute deps
|
|
233
306
|
const allInternalIds = gatedTxes.map((tx) => getIdForGatedTransaction(tx));
|
|
234
307
|
const allDeps = gatedTxes.flatMap((tx) => tx.dependencies ?? []);
|
|
@@ -238,8 +311,13 @@ export const resolveGatedTransactions = async <
|
|
|
238
311
|
|
|
239
312
|
//prepopulate results for external dependencies
|
|
240
313
|
//this map is only used for internal status tracking
|
|
241
|
-
|
|
242
|
-
|
|
314
|
+
const results: Record<
|
|
315
|
+
GatedTransactionId,
|
|
316
|
+
{
|
|
317
|
+
resolved?: ResolvedGatedTransaction;
|
|
318
|
+
checkResult: { onChainData?: any; expectationMet: boolean };
|
|
319
|
+
}
|
|
320
|
+
> = Object.fromEntries(
|
|
243
321
|
await Promise.all(
|
|
244
322
|
allExternalDeps.map(async (tx) => {
|
|
245
323
|
const checkResult = await checkGatedTransaction({
|
|
@@ -248,18 +326,27 @@ export const resolveGatedTransactions = async <
|
|
|
248
326
|
cachedCheckResult: await cache?.getCachedTxCheckData?.(tx),
|
|
249
327
|
});
|
|
250
328
|
|
|
251
|
-
return [
|
|
329
|
+
return [
|
|
330
|
+
getIdForGatedTransaction(tx),
|
|
331
|
+
{
|
|
332
|
+
checkResult,
|
|
333
|
+
},
|
|
334
|
+
];
|
|
252
335
|
}),
|
|
253
336
|
),
|
|
254
337
|
);
|
|
255
338
|
|
|
256
|
-
const
|
|
339
|
+
const getTransactionResult = (gtxId: GatedTransactionId) => results[gtxId];
|
|
257
340
|
|
|
258
341
|
const txFunctions = gatedTxes.map((tx) => async () => {
|
|
259
|
-
const
|
|
342
|
+
const { resolvedGatedTransaction, lastCheckResult } = await resolveGatedTransaction<
|
|
343
|
+
TxType,
|
|
344
|
+
GatedTx,
|
|
345
|
+
ProcessTx
|
|
346
|
+
>({
|
|
260
347
|
gatedTx: tx,
|
|
261
348
|
activityRegistry,
|
|
262
|
-
|
|
349
|
+
getTransactionResult,
|
|
263
350
|
processTx,
|
|
264
351
|
confirmationCallback:
|
|
265
352
|
userInteractionCallbacks?.confirmationCallback ?? (async () => true),
|
|
@@ -267,13 +354,20 @@ export const resolveGatedTransactions = async <
|
|
|
267
354
|
cache,
|
|
268
355
|
});
|
|
269
356
|
|
|
270
|
-
const resId = getIdForGatedTransaction(
|
|
271
|
-
results[resId] =
|
|
272
|
-
|
|
273
|
-
|
|
357
|
+
const resId = getIdForGatedTransaction(resolvedGatedTransaction);
|
|
358
|
+
results[resId] = {
|
|
359
|
+
resolved: resolvedGatedTransaction,
|
|
360
|
+
checkResult: {
|
|
361
|
+
expectationMet: [
|
|
362
|
+
GatedTransactionStatus.SUCCESS,
|
|
363
|
+
GatedTransactionStatus.NO_OP,
|
|
364
|
+
].includes(resolvedGatedTransaction.result.status),
|
|
365
|
+
onChainData: lastCheckResult?.onChainData ?? undefined,
|
|
366
|
+
},
|
|
367
|
+
};
|
|
274
368
|
|
|
275
|
-
userInteractionCallbacks?.onResultCallback?.(
|
|
276
|
-
return
|
|
369
|
+
userInteractionCallbacks?.onResultCallback?.(resolvedGatedTransaction);
|
|
370
|
+
return resolvedGatedTransaction;
|
|
277
371
|
});
|
|
278
372
|
|
|
279
373
|
return await Promise.all(txFunctions.map((func) => func()));
|
|
@@ -281,9 +375,8 @@ export const resolveGatedTransactions = async <
|
|
|
281
375
|
|
|
282
376
|
export const resolveSequencedGatedTransactions = async <
|
|
283
377
|
TxType extends Transaction,
|
|
284
|
-
ProcessedTxType extends Transaction,
|
|
285
378
|
GatedTx extends GatedTransaction<string, TxType, any>,
|
|
286
|
-
ProcessTx extends (transaction: TxType) => Promise<
|
|
379
|
+
ProcessTx extends (transaction: TxType) => Promise<TransactionResult>,
|
|
287
380
|
>({
|
|
288
381
|
activityRegistry,
|
|
289
382
|
gatedTxes,
|
|
@@ -301,7 +394,7 @@ export const resolveSequencedGatedTransactions = async <
|
|
|
301
394
|
}) => {
|
|
302
395
|
const results = [];
|
|
303
396
|
for (const seq of gatedTxes) {
|
|
304
|
-
const result = await resolveGatedTransactions<TxType,
|
|
397
|
+
const result = await resolveGatedTransactions<TxType, GatedTx, ProcessTx>({
|
|
305
398
|
gatedTxes: seq,
|
|
306
399
|
activityRegistry,
|
|
307
400
|
processTx,
|
package/src/types.ts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import z from 'zod/v4';
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
Transaction,
|
|
5
|
-
transactionSchema as _transactionSchema,
|
|
3
|
+
import {
|
|
4
|
+
type Transaction,
|
|
5
|
+
type transactionSchema as _transactionSchema,
|
|
6
|
+
type TransactionWithResultFor,
|
|
7
|
+
type transactionWithResultSchema as _transactionWithResultSchema,
|
|
6
8
|
} from '@layerzerolabs/common-chain-model';
|
|
7
9
|
import type { FunctionPointer } from '@layerzerolabs/common-utils';
|
|
8
|
-
import {
|
|
10
|
+
import type { BuildTuple } from '@layerzerolabs/typescript-utils';
|
|
11
|
+
import { customSchema, functionSchema } from '@layerzerolabs/zod-utils';
|
|
9
12
|
|
|
10
13
|
export type OnChainDataComparisonOperator<OnChainDataType> = OnChainDataType extends number
|
|
11
14
|
? '<' | '<=' | '=' | '!=' | '>' | '>='
|
|
@@ -17,39 +20,19 @@ export type OnChainDataComparison<OnChainDataType> = {
|
|
|
17
20
|
};
|
|
18
21
|
|
|
19
22
|
export type GatedTransactionCheck<
|
|
20
|
-
Method extends (...args: any[]) => any = (...args: any[]) => unknown
|
|
23
|
+
Method extends (...args: any[]) => Promise<any> = (...args: any[]) => Promise<unknown>,
|
|
21
24
|
> = {
|
|
22
25
|
functionPointer: FunctionPointer<Method>;
|
|
23
|
-
params:
|
|
26
|
+
params: Parameters<Method>;
|
|
24
27
|
expectedResult: OnChainDataComparison<Awaited<ReturnType<Method>>>;
|
|
25
28
|
};
|
|
26
29
|
|
|
27
|
-
export const gatedTransactionSchema = <TransactionSchema extends typeof _transactionSchema>({
|
|
28
|
-
transactionSchema,
|
|
29
|
-
name,
|
|
30
|
-
}: {
|
|
31
|
-
transactionSchema: TransactionSchema;
|
|
32
|
-
name: z.ZodString | z.ZodLiteral<string>;
|
|
33
|
-
}) =>
|
|
34
|
-
z.object({
|
|
35
|
-
name,
|
|
36
|
-
transaction: transactionSchema,
|
|
37
|
-
check: z.object({
|
|
38
|
-
functionPointer: z.any(),
|
|
39
|
-
params: z.array(z.any()),
|
|
40
|
-
expectedResult: z.object({
|
|
41
|
-
operator: z.custom<OnChainDataComparisonOperator<any>>(),
|
|
42
|
-
comparisonValue: z.any(),
|
|
43
|
-
}),
|
|
44
|
-
}),
|
|
45
|
-
});
|
|
46
|
-
|
|
47
30
|
// Schema for gated transaction results
|
|
48
31
|
export const gatedTransactionResultSchema = <
|
|
49
|
-
|
|
32
|
+
TxWithResultSchema extends typeof _transactionWithResultSchema,
|
|
50
33
|
OnchainDataSchema extends z.ZodType,
|
|
51
34
|
>(
|
|
52
|
-
|
|
35
|
+
txWithResultSchema: TxWithResultSchema,
|
|
53
36
|
onchainDataSchema: OnchainDataSchema,
|
|
54
37
|
) =>
|
|
55
38
|
z.union([
|
|
@@ -58,7 +41,7 @@ export const gatedTransactionResultSchema = <
|
|
|
58
41
|
}),
|
|
59
42
|
z.object({
|
|
60
43
|
status: z.literal(GatedTransactionStatus.SUCCESS),
|
|
61
|
-
submittedTransaction:
|
|
44
|
+
submittedTransaction: txWithResultSchema,
|
|
62
45
|
}),
|
|
63
46
|
z.object({
|
|
64
47
|
status: z.literal(GatedTransactionStatus.TRANSACTION_FAILED),
|
|
@@ -66,7 +49,7 @@ export const gatedTransactionResultSchema = <
|
|
|
66
49
|
}),
|
|
67
50
|
z.object({
|
|
68
51
|
status: z.literal(GatedTransactionStatus.FINAL_CHECK_FAILED),
|
|
69
|
-
submittedTransaction:
|
|
52
|
+
submittedTransaction: txWithResultSchema,
|
|
70
53
|
finalOnChainState: onchainDataSchema,
|
|
71
54
|
}),
|
|
72
55
|
z.object({
|
|
@@ -77,55 +60,62 @@ export const gatedTransactionResultSchema = <
|
|
|
77
60
|
}),
|
|
78
61
|
]);
|
|
79
62
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
transactionSchema,
|
|
86
|
-
onchainDataSchema,
|
|
87
|
-
name,
|
|
88
|
-
}: {
|
|
89
|
-
transactionSchema: TransactionSchema;
|
|
90
|
-
onchainDataSchema: OnchainDataSchema;
|
|
91
|
-
name: z.ZodString | z.ZodLiteral<string>;
|
|
92
|
-
}) =>
|
|
93
|
-
gatedTransactionSchema({
|
|
94
|
-
transactionSchema,
|
|
95
|
-
name,
|
|
96
|
-
}).and(
|
|
97
|
-
z.object({
|
|
98
|
-
result: gatedTransactionResultSchema(transactionSchema, onchainDataSchema),
|
|
99
|
-
}),
|
|
100
|
-
);
|
|
101
|
-
|
|
102
|
-
type GatedTransactionDependencies = GatedTransaction[];
|
|
63
|
+
export type InferOnChainDataTypeFromCheck<Check> = Check extends (...args: any[]) => infer Ret
|
|
64
|
+
? Awaited<Ret>
|
|
65
|
+
: unknown;
|
|
66
|
+
export type InferOnChainDataTypeFromGatedTransaction<GatedTx extends GatedTransaction> =
|
|
67
|
+
InferOnChainDataTypeFromCheck<GatedTx['check']>;
|
|
103
68
|
|
|
104
|
-
export type GatedTransaction
|
|
69
|
+
export type GatedTransactionDependencies = GatedTransaction[];
|
|
70
|
+
export type BaseGatedTransaction<
|
|
105
71
|
Name extends string = string,
|
|
106
|
-
TxType extends Transaction = Transaction,
|
|
107
72
|
CheckMethod extends (...args: any[]) => any = (...args: any[]) => any,
|
|
108
|
-
|
|
73
|
+
_Dependencies extends GatedTransactionDependencies = GatedTransactionDependencies,
|
|
109
74
|
> = {
|
|
110
|
-
bundleName?: string;
|
|
111
75
|
name: Name;
|
|
112
|
-
|
|
76
|
+
bundleName?: string;
|
|
77
|
+
chainName: string;
|
|
113
78
|
check: GatedTransactionCheck<CheckMethod>;
|
|
79
|
+
dependencies: _Dependencies;
|
|
114
80
|
cacheable?: boolean;
|
|
115
81
|
uniqueIdKeys?: Record<string, string | number | boolean>;
|
|
116
|
-
dependencies?: Dependencies;
|
|
117
82
|
};
|
|
118
83
|
|
|
119
|
-
export type
|
|
84
|
+
export type LiteralGatedTransaction<
|
|
120
85
|
Name extends string = string,
|
|
121
86
|
TxType extends Transaction = Transaction,
|
|
122
87
|
CheckMethod extends (...args: any[]) => any = (...args: any[]) => any,
|
|
123
|
-
|
|
124
|
-
|
|
88
|
+
_Dependencies extends GatedTransactionDependencies = GatedTransactionDependencies,
|
|
89
|
+
> = BaseGatedTransaction<Name, CheckMethod, _Dependencies> & {
|
|
90
|
+
transactionType: 'literal';
|
|
91
|
+
transaction: TxType;
|
|
125
92
|
};
|
|
126
93
|
|
|
127
|
-
export type
|
|
128
|
-
|
|
94
|
+
export type FunctionalGatedTransaction<
|
|
95
|
+
Name extends string = string,
|
|
96
|
+
TxType extends Transaction = Transaction,
|
|
97
|
+
CheckMethod extends (...args: any[]) => any = (...args: any[]) => any,
|
|
98
|
+
DepMethod extends (txs: any) => Promise<TxType> = (txs: any) => Promise<any>,
|
|
99
|
+
_Dependencies extends GatedTransactionDependencies = GatedTransactionDependencies,
|
|
100
|
+
> = BaseGatedTransaction<Name, CheckMethod, _Dependencies> & {
|
|
101
|
+
transactionType: 'functional';
|
|
102
|
+
getTransactionPointer: FunctionPointer<DepMethod>;
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
export type GatedTransaction<
|
|
106
|
+
Name extends string = string,
|
|
107
|
+
TxType extends Transaction = Transaction,
|
|
108
|
+
CheckMethod extends (...args: any[]) => any = (...args: any[]) => any,
|
|
109
|
+
DepMethod extends (txs: any) => Promise<TxType> = (txs: any) => Promise<any>,
|
|
110
|
+
_Dependencies extends GatedTransactionDependencies = GatedTransactionDependencies,
|
|
111
|
+
> =
|
|
112
|
+
| LiteralGatedTransaction<Name, TxType, CheckMethod, _Dependencies>
|
|
113
|
+
| FunctionalGatedTransaction<Name, TxType, CheckMethod, DepMethod, _Dependencies>;
|
|
114
|
+
|
|
115
|
+
export type BaseGatedTransactionFor<GatedTx extends GatedTransaction> =
|
|
116
|
+
GatedTx extends GatedTransaction<infer Name, any, infer CheckMethod, any, infer _Dependencies>
|
|
117
|
+
? BaseGatedTransaction<Name, CheckMethod, _Dependencies>
|
|
118
|
+
: never;
|
|
129
119
|
|
|
130
120
|
export enum GatedTransactionStatus {
|
|
131
121
|
NO_OP = 'no_op',
|
|
@@ -140,9 +130,9 @@ type NoOpGatedTransaction = {
|
|
|
140
130
|
status: GatedTransactionStatus.NO_OP;
|
|
141
131
|
};
|
|
142
132
|
|
|
143
|
-
type SuccessfulGatedTransaction<
|
|
133
|
+
type SuccessfulGatedTransaction<TxType extends Transaction> = {
|
|
144
134
|
status: GatedTransactionStatus.SUCCESS;
|
|
145
|
-
submittedTransaction:
|
|
135
|
+
submittedTransaction: TransactionWithResultFor<TxType>;
|
|
146
136
|
};
|
|
147
137
|
|
|
148
138
|
type TxFailedGatedTransaction = {
|
|
@@ -150,10 +140,10 @@ type TxFailedGatedTransaction = {
|
|
|
150
140
|
transactionError: any;
|
|
151
141
|
};
|
|
152
142
|
|
|
153
|
-
type CheckFailedGatedTransaction<
|
|
143
|
+
type CheckFailedGatedTransaction<GatedTx extends GatedTransaction, TxType extends Transaction> = {
|
|
154
144
|
status: GatedTransactionStatus.FINAL_CHECK_FAILED;
|
|
155
|
-
submittedTransaction:
|
|
156
|
-
finalOnChainState:
|
|
145
|
+
submittedTransaction: TransactionWithResultFor<TxType>;
|
|
146
|
+
finalOnChainState: InferOnChainDataTypeFromGatedTransaction<GatedTx>;
|
|
157
147
|
};
|
|
158
148
|
|
|
159
149
|
type DependencyFailedGatedTransaction = {
|
|
@@ -166,15 +156,12 @@ type DeniedGatedTransaction = {
|
|
|
166
156
|
|
|
167
157
|
export type GatedTransactionResult<
|
|
168
158
|
GatedTx extends GatedTransaction = GatedTransaction,
|
|
169
|
-
|
|
159
|
+
TxType extends Transaction = Transaction,
|
|
170
160
|
> =
|
|
171
161
|
| NoOpGatedTransaction
|
|
172
|
-
| SuccessfulGatedTransaction<
|
|
162
|
+
| SuccessfulGatedTransaction<TxType>
|
|
173
163
|
| TxFailedGatedTransaction
|
|
174
|
-
| CheckFailedGatedTransaction<
|
|
175
|
-
ProcessedTxType,
|
|
176
|
-
InferOnChainDataTypeFromGatedTransaction<GatedTx>
|
|
177
|
-
>
|
|
164
|
+
| CheckFailedGatedTransaction<GatedTx, TxType>
|
|
178
165
|
| DependencyFailedGatedTransaction
|
|
179
166
|
| DeniedGatedTransaction;
|
|
180
167
|
|
|
@@ -207,7 +194,78 @@ export type IGatedTransactionCache = z.infer<typeof gatedTransactionCacheSchema>
|
|
|
207
194
|
*/
|
|
208
195
|
export type GatedTransactionId = `${string}-${string}-${string}`;
|
|
209
196
|
|
|
197
|
+
export type ResolvedGatedTransaction<
|
|
198
|
+
GatedTx extends GatedTransaction = GatedTransaction,
|
|
199
|
+
TxType extends Transaction = Transaction,
|
|
200
|
+
> = BaseGatedTransactionFor<GatedTx> & {
|
|
201
|
+
result: GatedTransactionResult<GatedTx, TxType>;
|
|
202
|
+
};
|
|
203
|
+
|
|
210
204
|
export type UserInteractionCallbacks = {
|
|
211
205
|
confirmationCallback?: (gtx: GatedTransaction) => Promise<boolean>;
|
|
212
|
-
onResultCallback?: (result:
|
|
206
|
+
onResultCallback?: (result: ResolvedGatedTransaction) => void;
|
|
213
207
|
};
|
|
208
|
+
|
|
209
|
+
export const gatedTransactionSchema = <
|
|
210
|
+
Name extends z.ZodString | z.ZodLiteral<string> = z.ZodString,
|
|
211
|
+
TransactionSchema extends typeof _transactionSchema = typeof _transactionSchema,
|
|
212
|
+
>(_?: {
|
|
213
|
+
name?: Name;
|
|
214
|
+
transactionSchema?: TransactionSchema;
|
|
215
|
+
}) => customSchema<GatedTransaction<z.infer<Name>, z.infer<TransactionSchema>>>();
|
|
216
|
+
|
|
217
|
+
export const resolvedGatedTransactionSchema = <
|
|
218
|
+
Name extends z.ZodString | z.ZodLiteral<string> = z.ZodString,
|
|
219
|
+
TransactionSchema extends typeof _transactionSchema = typeof _transactionSchema,
|
|
220
|
+
>(_?: {
|
|
221
|
+
name?: Name;
|
|
222
|
+
transactionSchema?: TransactionSchema;
|
|
223
|
+
}) =>
|
|
224
|
+
customSchema<
|
|
225
|
+
ResolvedGatedTransaction<
|
|
226
|
+
GatedTransaction<z.infer<Name>, z.infer<TransactionSchema>>,
|
|
227
|
+
z.infer<TransactionSchema>
|
|
228
|
+
>
|
|
229
|
+
>();
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Builds a schema for an activity that builds a transaction based on the results of other transactions
|
|
233
|
+
* @param transactionSchema The schema for the transaction to be built
|
|
234
|
+
* @param transactionWithResultSchema The schema for the results of the transactions you're building off of
|
|
235
|
+
* @param txNumber The number of transactions you're building off of
|
|
236
|
+
* @returns A schema for the activity that builds the transaction
|
|
237
|
+
*/
|
|
238
|
+
export const createTxDependentActivitySchema = <
|
|
239
|
+
TransactionSchema extends typeof _transactionSchema = typeof _transactionSchema,
|
|
240
|
+
const TxNumber extends number = 1,
|
|
241
|
+
>(
|
|
242
|
+
transactionSchema: TransactionSchema,
|
|
243
|
+
txNumber: TxNumber,
|
|
244
|
+
) => {
|
|
245
|
+
const txs = Array.from({ length: txNumber }, () =>
|
|
246
|
+
resolvedGatedTransactionSchema({
|
|
247
|
+
name: z.string(),
|
|
248
|
+
transactionSchema: transactionSchema,
|
|
249
|
+
}),
|
|
250
|
+
);
|
|
251
|
+
return functionSchema({
|
|
252
|
+
input: z.tuple([z.tuple(txs as any)]),
|
|
253
|
+
output: z.promise(transactionSchema),
|
|
254
|
+
}) as z.ZodType<
|
|
255
|
+
(
|
|
256
|
+
txs: BuildTuple<
|
|
257
|
+
ResolvedGatedTransaction<
|
|
258
|
+
GatedTransaction<string, z.infer<TransactionSchema>, any, any, any>
|
|
259
|
+
>,
|
|
260
|
+
TxNumber
|
|
261
|
+
>,
|
|
262
|
+
) => Promise<z.infer<TransactionSchema>>
|
|
263
|
+
>;
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
export type ResolvedGatedTransactionDependencies<GatedTx extends GatedTransaction> =
|
|
267
|
+
GatedTx extends GatedTransaction<any, any, any, any, infer _Dependencies>
|
|
268
|
+
? {
|
|
269
|
+
[K in keyof _Dependencies]?: ResolvedGatedTransaction<_Dependencies[K]>;
|
|
270
|
+
}
|
|
271
|
+
: never;
|