Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| eb32dcfe55 |
@ -81,7 +81,7 @@ export default tseslint.config(
|
||||
caughtErrorsIgnorePattern: '^_',
|
||||
},
|
||||
],
|
||||
'@typescript-eslint/no-explicit-any': 'error',
|
||||
'@typescript-eslint/no-explicit-any': ['error', { ignoreRestArgs: true }],
|
||||
'@typescript-eslint/ban-ts-comment': 'off',
|
||||
'@typescript-eslint/no-misused-promises': ['error', { checksVoidReturn: false }],
|
||||
'@typescript-eslint/no-empty-object-type': 'off',
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { constructClaim } from '@coinweb/contract-kit';
|
||||
import { readOp, storeOp, cwait } from 'cwait';
|
||||
import { readOp, storeOp, cwait, queue } from 'cwait';
|
||||
|
||||
import { TypedClaim } from '../../../lib/dist/shared/types';
|
||||
import { AddWordArgs, createWordKey, WordClaimBody } from '../offchain/shared';
|
||||
@ -26,6 +26,16 @@ export const addWord = cwait(async (...[word]: AddWordArgs) => {
|
||||
console.log('await storeOp');
|
||||
await storeOp(constructClaim(createWordKey(id), { word }, '0x0'));
|
||||
|
||||
await queue(async () => {
|
||||
console.log('await readOp');
|
||||
const res = await readOp<TypedClaim<WordClaimBody>>(createWordKey(id));
|
||||
|
||||
console.log('await storeOp2');
|
||||
await storeOp(
|
||||
constructClaim(createWordKey(id + id), { word: (res?.body.word ?? '') + (res?.body.word ?? '') }, '0x0')
|
||||
);
|
||||
});
|
||||
|
||||
console.log('await extraLogic');
|
||||
const wordClaim = await extraLogic(id);
|
||||
|
||||
|
||||
@ -1,25 +1,9 @@
|
||||
import { SELF_REGISTER_HANDLER_NAME } from '@coinweb/contract-kit';
|
||||
import { selfRegisterHandler } from '@coinweb/self-register';
|
||||
import { addMethodHandler, ContractHandlers, executeHandler, executor } from 'cwait';
|
||||
import { constructCwebMain } from 'cwait';
|
||||
|
||||
import { PUBLIC_METHODS } from '../offchain/shared';
|
||||
|
||||
import { addWord } from './addWord';
|
||||
|
||||
const createModule = (): ContractHandlers => {
|
||||
const module: ContractHandlers = { handlers: {} };
|
||||
|
||||
addMethodHandler(module, PUBLIC_METHODS.ADD_WORD, executor(addWord));
|
||||
|
||||
addMethodHandler(module, SELF_REGISTER_HANDLER_NAME, selfRegisterHandler);
|
||||
|
||||
return module;
|
||||
};
|
||||
|
||||
export const cwebMain = () => {
|
||||
return (async () => {
|
||||
const module = createModule();
|
||||
|
||||
await executeHandler(module);
|
||||
})();
|
||||
};
|
||||
export const cwebMain = constructCwebMain({
|
||||
[PUBLIC_METHODS.ADD_WORD]: addWord,
|
||||
});
|
||||
|
||||
@ -92,4 +92,7 @@ export const context = {
|
||||
get needSaveResult() {
|
||||
return getMethodArgs()[6] ?? false;
|
||||
},
|
||||
get isQueue() {
|
||||
return getMethodArgs()[8] ?? false;
|
||||
},
|
||||
};
|
||||
|
||||
22
packages/cwait/src/onchain/createContract.ts
Normal file
22
packages/cwait/src/onchain/createContract.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import { ContractHandlers as ContractHandlersOrig, SELF_REGISTER_HANDLER_NAME } from '@coinweb/contract-kit';
|
||||
import { selfRegisterHandler } from '@coinweb/self-register';
|
||||
import { queue } from 'lib/onchain';
|
||||
|
||||
import { addMethodHandler, ContractHandlers, executeHandler } from '../contract-kit';
|
||||
|
||||
import { executor } from './executor';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export const constructCwebMain = (methods: Record<string, (...args: any[]) => Promise<void>>) => async () => {
|
||||
const module: ContractHandlers = { handlers: {} };
|
||||
|
||||
Object.entries(methods).forEach(([name, handler]) => {
|
||||
addMethodHandler(module, name, executor(handler));
|
||||
});
|
||||
|
||||
addMethodHandler(module, SELF_REGISTER_HANDLER_NAME, selfRegisterHandler);
|
||||
|
||||
queue.applyQueue(module as ContractHandlersOrig, []);
|
||||
|
||||
await executeHandler(module);
|
||||
};
|
||||
@ -1,18 +1,15 @@
|
||||
import { constructStore } from '@coinweb/contract-kit/dist/esm/operations/store';
|
||||
|
||||
import { constructResultClaim } from '../claims/result';
|
||||
import { context } from '../context';
|
||||
import { stopExecution } from '../executor';
|
||||
import { opMarker } from '../global';
|
||||
import { isResolvedChildOp, isResolvedExecOp, isResolvedSlotOp } from '../utils';
|
||||
import { uuid } from '../utils';
|
||||
|
||||
import { getAwaitedTasks, pushAwaitedTask } from './awaited';
|
||||
import { getUsedOps, saveUsedOps, shiftResolvedOp } from './resolved';
|
||||
import { constructResultClaim } from './claims';
|
||||
import { context } from './context';
|
||||
import { stopExecution } from './executor';
|
||||
import { opMarker } from './global';
|
||||
import { getAwaitedTasks, pushAwaitedTask } from './promisifiedOps/awaited';
|
||||
import { getUsedOps, saveUsedOps, shiftResolvedOp } from './promisifiedOps/resolved';
|
||||
import { isResolvedChildOp, isResolvedExecOp, isResolvedSlotOp, uuid } from './utils';
|
||||
|
||||
let isRootDetected = false;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export const cwait = <TAsyncCallback extends (...args: any[]) => Promise<unknown>>(asyncCallback: TAsyncCallback) => {
|
||||
console.log('cwait: ', asyncCallback.name);
|
||||
let isRoot = false;
|
||||
@ -1,3 +1,6 @@
|
||||
export * from './context';
|
||||
export * from './executor';
|
||||
export * from './promisifiedOps';
|
||||
export * from './createContract';
|
||||
export * from './cwait';
|
||||
export * from './queue';
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
export * from './awaited';
|
||||
export * from './cwait';
|
||||
export * from './ops';
|
||||
export * from './resolved';
|
||||
|
||||
@ -1,2 +0,0 @@
|
||||
export * from './jumpTx';
|
||||
export * from './tx';
|
||||
@ -1 +0,0 @@
|
||||
export const jumpTx = () => null;
|
||||
@ -1 +0,0 @@
|
||||
export const tx = () => null;
|
||||
1
packages/cwait/src/onchain/queue/index.ts
Normal file
1
packages/cwait/src/onchain/queue/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './queue';
|
||||
21
packages/cwait/src/onchain/queue/queue.ts
Normal file
21
packages/cwait/src/onchain/queue/queue.ts
Normal file
@ -0,0 +1,21 @@
|
||||
const queues = new Set<number>();
|
||||
|
||||
let queueId = 0;
|
||||
|
||||
export const queue = <TCallback extends () => Promise<void>>(callback: TCallback) => {
|
||||
const id = queueId++;
|
||||
queues.add(id);
|
||||
|
||||
const promise = new Promise<void>((resolve) => {
|
||||
callback().finally(() => {
|
||||
queues.delete(id);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
return promise;
|
||||
};
|
||||
|
||||
export const isQueueLocked = () => {
|
||||
return queues.size > 0;
|
||||
};
|
||||
@ -5,16 +5,20 @@ import {
|
||||
FullCallInfo,
|
||||
NewTx,
|
||||
passCwebFrom,
|
||||
PreparedCallInfo,
|
||||
PreparedOperation,
|
||||
prepareQueueCall,
|
||||
sendCwebInterface,
|
||||
} from '@coinweb/contract-kit';
|
||||
import { CwebBlock } from '@coinweb/contract-kit/dist/esm/operations/block';
|
||||
import { GBlock } from '@coinweb/contract-kit/dist/types/operations/generics';
|
||||
import { queue, queueCostFee, queueUnlockFee } from 'lib/onchain';
|
||||
|
||||
import { ExecutorMethodArgs, ResolvedOp, ResolvedSlotOp, Task } from '../../../types';
|
||||
import { constructFundsClaimRangRead, constructFundsClaimStore } from '../../claims/funds';
|
||||
import { constructResultBlockFilter, constructResultClaimTake, resultKey } from '../../claims/result';
|
||||
import { context, getRawContext } from '../../context';
|
||||
import { isQueueLocked } from '../../queue/queue';
|
||||
import { isPreparedBlockOp, isPreparedExecOp } from '../typeGuards';
|
||||
|
||||
export const prepareInThreadTxs = ({
|
||||
@ -91,6 +95,8 @@ export const prepareInThreadTxs = ({
|
||||
id,
|
||||
context.thisId,
|
||||
true,
|
||||
[],
|
||||
isQueueLocked(),
|
||||
] satisfies ExecutorMethodArgs,
|
||||
},
|
||||
contractInfo: {
|
||||
@ -150,13 +156,20 @@ export const prepareInThreadTxs = ({
|
||||
txFee += 800n + outThreadFee + BigInt(takeOps.length) * 100n;
|
||||
callsPrepared++;
|
||||
|
||||
returnTxs.push(
|
||||
constructContinueTx(
|
||||
getRawContext(),
|
||||
[passCwebFrom(context.issuer, cwebPerCall - outThreadFee), ...takeOps],
|
||||
[
|
||||
{
|
||||
callInfo: {
|
||||
const isNeedToLockQueue = !context.isQueue && isQueueLocked();
|
||||
const isNeedToUnlockQueue = context.isQueue && !isQueueLocked();
|
||||
|
||||
if (isNeedToLockQueue) {
|
||||
console.log('isNeedToLockQueue');
|
||||
txFee += queueCostFee;
|
||||
}
|
||||
|
||||
if (isNeedToUnlockQueue) {
|
||||
console.log('isNeedToUnlockQueue');
|
||||
txFee += queueUnlockFee;
|
||||
}
|
||||
|
||||
let callInfo: PreparedCallInfo = {
|
||||
ref: constructContractRef(context.issuer, []),
|
||||
methodInfo: {
|
||||
methodName: context.methodName,
|
||||
@ -168,6 +181,7 @@ export const prepareInThreadTxs = ({
|
||||
context.parentId,
|
||||
context.needSaveResult,
|
||||
takeOps.map((op) => (op.TakeOp.key.second_part as [string])[0]),
|
||||
isQueueLocked(),
|
||||
] satisfies ExecutorMethodArgs,
|
||||
},
|
||||
contractInfo: {
|
||||
@ -175,7 +189,19 @@ export const prepareInThreadTxs = ({
|
||||
authenticated: null,
|
||||
},
|
||||
contractArgs: [constructFundsClaimRangRead(context.thisId), ...callArgs],
|
||||
},
|
||||
};
|
||||
|
||||
if (isNeedToLockQueue) {
|
||||
callInfo = prepareQueueCall(context.issuer, callInfo);
|
||||
}
|
||||
|
||||
returnTxs.push(
|
||||
constructContinueTx(
|
||||
getRawContext(),
|
||||
[passCwebFrom(context.issuer, cwebPerCall - outThreadFee), ...takeOps],
|
||||
[
|
||||
{
|
||||
callInfo,
|
||||
},
|
||||
]
|
||||
)
|
||||
@ -184,6 +210,10 @@ export const prepareInThreadTxs = ({
|
||||
if (childCalls.length) {
|
||||
returnTxs.push(constructContinueTx(getRawContext(), childBlocks, childCalls));
|
||||
}
|
||||
|
||||
if (isNeedToUnlockQueue) {
|
||||
returnTxs.push(...queue.gateway.unlock(getRawContext()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@ import {
|
||||
|
||||
import { ExecutorMethodArgs, Task } from '../../../types';
|
||||
import { context, getRawContext } from '../../context';
|
||||
import { isQueueLocked } from '../../queue/queue';
|
||||
import { isPreparedExecOp } from '../typeGuards';
|
||||
|
||||
export const prepareOutThreadTxs = ({
|
||||
@ -51,6 +52,8 @@ export const prepareOutThreadTxs = ({
|
||||
id,
|
||||
context.parentId ?? context.thisId,
|
||||
false,
|
||||
[],
|
||||
isQueueLocked(),
|
||||
] satisfies ExecutorMethodArgs,
|
||||
},
|
||||
contractInfo: {
|
||||
|
||||
@ -45,4 +45,5 @@ export type ExecutorMethodArgs = [
|
||||
parentId?: string,
|
||||
saveResult?: boolean,
|
||||
takenFundsIds?: string[],
|
||||
isQueue?: boolean,
|
||||
];
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import { Queue } from '@coinweb/contract-kit';
|
||||
|
||||
export const queue = new Queue({ name: 'queue', executionDepth: 2 });
|
||||
export const queue = new Queue({ name: 'queue', executionDepth: 4 });
|
||||
|
||||
export const queueUnlockFee = 3000n;
|
||||
|
||||
export const queueCostFee = Queue.queueCostFee();
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
VITE_API_URL='https://api-cloud.coinweb.io/wallet'
|
||||
VITE_EXPLORER_URL='https://explorer.coinweb.io'
|
||||
|
||||
VITE_CONTRACT_ADDRESS="0x8c89cb42634cfe892290845d907af8ec2d482cead42afaef3ccc3cea4446fce5"
|
||||
VITE_CONTRACT_ADDRESS="0xa1bd5281d39b1182db65565d90919aff15adf65ac8ba43d984048485df5a6d8d"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user