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