wip
This commit is contained in:
parent
84ff2837eb
commit
e9025efa22
@ -1,14 +1,20 @@
|
|||||||
import { constructClaim } from '@coinweb/contract-kit';
|
import { constructClaim } from '@coinweb/contract-kit';
|
||||||
import { cwait, readOp, storeOp, TypedClaim } from 'cwait';
|
import { cwait, lock, readOp, storeOp, TypedClaim } from 'cwait';
|
||||||
|
|
||||||
import { createWordKey, WordClaimBody } from '../offchain';
|
import { createWordKey, WordClaimBody } from '../offchain';
|
||||||
|
|
||||||
import { extraLogic2 } from './extraLogic2';
|
import { extraLogic2 } from './extraLogic2';
|
||||||
|
|
||||||
export const extraLogic = cwait(async (id: string, i: number) => {
|
export const extraLogic = cwait(async (id: string, i: number) => {
|
||||||
console.log('extraLogic START + ', i);
|
console.log('extraLogic START ++ ', i);
|
||||||
|
|
||||||
|
console.log('extraLogic lock + ', i);
|
||||||
|
const unlock = await lock(createWordKey(id));
|
||||||
|
|
||||||
|
console.log('extraLogic readOp + ', i);
|
||||||
const result = await readOp<TypedClaim<WordClaimBody>>(createWordKey(id));
|
const result = await readOp<TypedClaim<WordClaimBody>>(createWordKey(id));
|
||||||
|
|
||||||
|
console.log('extraLogic storeOp + ', i);
|
||||||
await storeOp(
|
await storeOp(
|
||||||
constructClaim(
|
constructClaim(
|
||||||
createWordKey(id),
|
createWordKey(id),
|
||||||
@ -17,6 +23,9 @@ export const extraLogic = cwait(async (id: string, i: number) => {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
console.log('extraLogic unlock + ', i);
|
||||||
|
await unlock();
|
||||||
|
|
||||||
console.log('extraLogic return extraLogic2 + ', i);
|
console.log('extraLogic return extraLogic2 + ', i);
|
||||||
return extraLogic2(id, i);
|
return extraLogic2(id, i);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -12,7 +12,6 @@ import { getCallParameters, getContractIssuer } from 'lib/onchain';
|
|||||||
|
|
||||||
import { ExecutorMethodArgs, ResolvedOp } from '../../types';
|
import { ExecutorMethodArgs, ResolvedOp } from '../../types';
|
||||||
import { pushAwaitedTask } from '../promisifiedFeatures';
|
import { pushAwaitedTask } from '../promisifiedFeatures';
|
||||||
import { uuid } from '../utils';
|
|
||||||
|
|
||||||
import { extractOps } from './extractOps';
|
import { extractOps } from './extractOps';
|
||||||
|
|
||||||
@ -65,7 +64,9 @@ export const handleContext = (ctx: Context) => {
|
|||||||
] = getMethodArgs();
|
] = getMethodArgs();
|
||||||
|
|
||||||
initialContext.isChild = !!parentId;
|
initialContext.isChild = !!parentId;
|
||||||
initialContext.thisId = thisId ?? uuid();
|
initialContext.thisId =
|
||||||
|
thisId ??
|
||||||
|
(BigInt(`0x${parentId ?? '0'}`) * 3n + BigInt(`0x${getRawContext().call.txid}`)).toString(16).slice(0, 32);
|
||||||
initialContext.parentId = parentId;
|
initialContext.parentId = parentId;
|
||||||
initialContext.methodName = methodName;
|
initialContext.methodName = methodName;
|
||||||
initialContext.initialArgs = initialArgs ?? [];
|
initialContext.initialArgs = initialArgs ?? [];
|
||||||
|
|||||||
@ -3,7 +3,13 @@ import { CwebTake } from '@coinweb/contract-kit/dist/types/operations/take';
|
|||||||
|
|
||||||
import { ResolvedOp, TypedClaim } from '../../types';
|
import { ResolvedOp, TypedClaim } from '../../types';
|
||||||
import { resultKey } from '../claims';
|
import { resultKey } from '../claims';
|
||||||
import { mutexBlockLockKey, mutexBlockUnlockKey, mutexExecOpsKey, MutexExecOpsResult } from '../mutex';
|
import {
|
||||||
|
mutexBlockLockKey,
|
||||||
|
mutexBlockUnlockKey,
|
||||||
|
mutexExecOpsKey,
|
||||||
|
MutexExecOpsResult,
|
||||||
|
MutexNotifyLockState,
|
||||||
|
} from '../mutex';
|
||||||
import { isResolvedBlockOp, isResolvedReadOp, isResolvedTakeOp } from '../utils';
|
import { isResolvedBlockOp, isResolvedReadOp, isResolvedTakeOp } from '../utils';
|
||||||
|
|
||||||
const extractFunds = (fundsOp: GRead<ResolvedRead>, takenFundsIds: string[]) => {
|
const extractFunds = (fundsOp: GRead<ResolvedRead>, takenFundsIds: string[]) => {
|
||||||
@ -92,7 +98,9 @@ export const extractOps = ({
|
|||||||
throw new Error('Wrong mutex lock result');
|
throw new Error('Wrong mutex lock result');
|
||||||
}
|
}
|
||||||
|
|
||||||
extractedOps.push({ SlotOp: { ok: true } });
|
extractedOps.push({
|
||||||
|
LockOp: nextAfterBlock.TakeOp.result.body as MutexNotifyLockState,
|
||||||
|
});
|
||||||
|
|
||||||
i += 2;
|
i += 2;
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@ -1,10 +1,23 @@
|
|||||||
import { ContractIssuer, constructContractRef } from '@coinweb/contract-kit';
|
import { ContractIssuer, constructContractRef } from '@coinweb/contract-kit';
|
||||||
|
|
||||||
import { constructMutexBlockLockClaimTake, constructMutexLockBlock } from '../claims';
|
import { constructMutexBlockLockClaimTake, constructMutexLockBlock, constructMutexLockClaimStore } from '../claims';
|
||||||
import { lockMethodName } from '../methods';
|
import { lockMethodName } from '../methods';
|
||||||
import { lockFee } from '../settings';
|
import { lockFee } from '../settings';
|
||||||
|
import { LockedKey } from '../types';
|
||||||
|
|
||||||
export const constructLockCall = (issuer: ContractIssuer, lockId: string) => {
|
export const constructLockCall = ({
|
||||||
|
issuer,
|
||||||
|
keys,
|
||||||
|
lockId,
|
||||||
|
timestamp,
|
||||||
|
processId,
|
||||||
|
}: {
|
||||||
|
issuer: ContractIssuer;
|
||||||
|
lockId: string;
|
||||||
|
timestamp: number;
|
||||||
|
keys: LockedKey[];
|
||||||
|
processId: string;
|
||||||
|
}) => {
|
||||||
return {
|
return {
|
||||||
callInfo: {
|
callInfo: {
|
||||||
ref: constructContractRef(issuer, []),
|
ref: constructContractRef(issuer, []),
|
||||||
@ -18,7 +31,10 @@ export const constructLockCall = (issuer: ContractIssuer, lockId: string) => {
|
|||||||
},
|
},
|
||||||
contractArgs: [],
|
contractArgs: [],
|
||||||
},
|
},
|
||||||
ops: [constructMutexLockBlock(lockId, issuer), constructMutexBlockLockClaimTake(lockId)] as const,
|
inThreadOps: [constructMutexLockBlock(lockId, issuer), constructMutexBlockLockClaimTake(lockId)] as const,
|
||||||
fee: lockFee + 200n,
|
outThreadOps: [
|
||||||
|
constructMutexLockClaimStore({ fee: lockFee, keys, lockId, timestamp, processId, locked: false }),
|
||||||
|
] as const,
|
||||||
|
fee: lockFee * 2n + 200n,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@ -8,15 +8,17 @@ import {
|
|||||||
ContractIssuer,
|
ContractIssuer,
|
||||||
} from '@coinweb/contract-kit';
|
} from '@coinweb/contract-kit';
|
||||||
|
|
||||||
|
import { MutexNotifyLockState } from '../types';
|
||||||
|
|
||||||
export const mutexBlockLockKey = '_mutex_block_lock';
|
export const mutexBlockLockKey = '_mutex_block_lock';
|
||||||
|
|
||||||
export const constructMutexBlockLockClaimKey = (lockId: string) => constructClaimKey([mutexBlockLockKey], [lockId]);
|
export const constructMutexBlockLockClaimKey = (lockId: string) => constructClaimKey([mutexBlockLockKey], [lockId]);
|
||||||
|
|
||||||
export const constructMutexBlockLockClaim = ({ lockId }: { lockId: string }) =>
|
export const constructMutexBlockLockClaim = ({ lockId, timestamp }: MutexNotifyLockState) =>
|
||||||
constructClaim(constructMutexBlockLockClaimKey(lockId), {}, '0x0');
|
constructClaim(constructMutexBlockLockClaimKey(lockId), { lockId, timestamp } satisfies MutexNotifyLockState, '0x0');
|
||||||
|
|
||||||
export const constructMutexBlockLockClaimStore = ({ lockId }: { lockId: string }) =>
|
export const constructMutexBlockLockClaimStore = ({ lockId, timestamp }: MutexNotifyLockState) =>
|
||||||
constructStore(constructMutexBlockLockClaim({ lockId }));
|
constructStore(constructMutexBlockLockClaim({ lockId, timestamp }));
|
||||||
|
|
||||||
export const constructMutexBlockLockClaimTake = (lockId: string) =>
|
export const constructMutexBlockLockClaimTake = (lockId: string) =>
|
||||||
constructTake(constructMutexBlockLockClaimKey(lockId));
|
constructTake(constructMutexBlockLockClaimKey(lockId));
|
||||||
|
|||||||
@ -43,17 +43,17 @@ export const constructMutexLockClaim = ({
|
|||||||
export const constructMutexLockClaimStore = ({
|
export const constructMutexLockClaimStore = ({
|
||||||
fee,
|
fee,
|
||||||
keys,
|
keys,
|
||||||
locked,
|
|
||||||
lockId,
|
lockId,
|
||||||
timestamp,
|
timestamp,
|
||||||
processId,
|
processId,
|
||||||
|
locked,
|
||||||
}: {
|
}: {
|
||||||
fee: bigint;
|
fee: bigint;
|
||||||
keys: LockedKey[];
|
keys: LockedKey[];
|
||||||
locked: boolean;
|
|
||||||
lockId: string;
|
lockId: string;
|
||||||
timestamp: number;
|
timestamp: number;
|
||||||
processId: string;
|
processId: string;
|
||||||
|
locked: boolean;
|
||||||
}) => constructStore(constructMutexLockClaim({ fee, keys, locked, lockId, timestamp, processId }));
|
}) => constructStore(constructMutexLockClaim({ fee, keys, locked, lockId, timestamp, processId }));
|
||||||
|
|
||||||
export const constructMutexLockClaimRangeRead = (issuer: ContractIssuer): GRead<CwebRead> =>
|
export const constructMutexLockClaimRangeRead = (issuer: ContractIssuer): GRead<CwebRead> =>
|
||||||
|
|||||||
@ -6,6 +6,8 @@ import {
|
|||||||
mutexExecLock,
|
mutexExecLock,
|
||||||
mutexLock,
|
mutexLock,
|
||||||
mutexUnlock,
|
mutexUnlock,
|
||||||
|
notifyLock,
|
||||||
|
notifyLockMethodName,
|
||||||
preReadExecTakeOpsMethodName,
|
preReadExecTakeOpsMethodName,
|
||||||
saveExecOpResult,
|
saveExecOpResult,
|
||||||
saveExecOpResultMethodName,
|
saveExecOpResultMethodName,
|
||||||
@ -27,4 +29,5 @@ export const mutexMethods = {
|
|||||||
[preReadExecTakeOpsMethodName]: preReadExecTakeOps,
|
[preReadExecTakeOpsMethodName]: preReadExecTakeOps,
|
||||||
[saveExecOpResultMethodName]: saveExecOpResult,
|
[saveExecOpResultMethodName]: saveExecOpResult,
|
||||||
[waitMethodName]: wait,
|
[waitMethodName]: wait,
|
||||||
|
[notifyLockMethodName]: notifyLock,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -16,7 +16,7 @@ import { lockFee } from '../settings';
|
|||||||
import { MutexLockState, MutexWaitNotifyArgs } from '../types';
|
import { MutexLockState, MutexWaitNotifyArgs } from '../types';
|
||||||
import { isMatchLockKeys } from '../utils';
|
import { isMatchLockKeys } from '../utils';
|
||||||
|
|
||||||
import { lockMethodName, notifyLockMethodName } from './names';
|
import { waitMethodName } from './names';
|
||||||
|
|
||||||
export const mutexExecLock = (context: Context) => {
|
export const mutexExecLock = (context: Context) => {
|
||||||
const { availableCweb } = getCallParameters(context);
|
const { availableCweb } = getCallParameters(context);
|
||||||
@ -59,25 +59,17 @@ export const mutexExecLock = (context: Context) => {
|
|||||||
callInfo: {
|
callInfo: {
|
||||||
ref: constructContractRef(issuer, []),
|
ref: constructContractRef(issuer, []),
|
||||||
methodInfo: {
|
methodInfo: {
|
||||||
methodName: lockMethodName,
|
methodName: waitMethodName,
|
||||||
methodArgs: [],
|
methodArgs: [
|
||||||
|
0,
|
||||||
|
{
|
||||||
|
timestamp: (lockCandidate.key.second_part as [number, string])[0],
|
||||||
|
lockId: (lockCandidate.key.second_part as [number, string])[1],
|
||||||
|
},
|
||||||
|
] satisfies MutexWaitNotifyArgs,
|
||||||
},
|
},
|
||||||
contractInfo: {
|
contractInfo: {
|
||||||
providedCweb: lockFee,
|
providedCweb: availableCweb + BigInt(lockCandidate.fees_stored) - 1000n,
|
||||||
authenticated: null,
|
|
||||||
},
|
|
||||||
contractArgs: [],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
callInfo: {
|
|
||||||
ref: constructContractRef(issuer, []),
|
|
||||||
methodInfo: {
|
|
||||||
methodName: notifyLockMethodName,
|
|
||||||
methodArgs: [0, (lockCandidate.key.second_part as [number, string])[1]] satisfies MutexWaitNotifyArgs,
|
|
||||||
},
|
|
||||||
contractInfo: {
|
|
||||||
providedCweb: 200n,
|
|
||||||
authenticated: null,
|
authenticated: null,
|
||||||
},
|
},
|
||||||
contractArgs: [],
|
contractArgs: [],
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import { constructMutexBlockLockClaimStore } from '../claims/mutexBlockLock';
|
|||||||
import { MutexNotifyLockArgs } from '../types';
|
import { MutexNotifyLockArgs } from '../types';
|
||||||
|
|
||||||
export const notifyLock = (context: Context) => {
|
export const notifyLock = (context: Context) => {
|
||||||
const [lockId] = getMethodArguments<MutexNotifyLockArgs>(context);
|
const [lockInfo] = getMethodArguments<MutexNotifyLockArgs>(context);
|
||||||
|
|
||||||
return [constructContinueTx(context, [constructMutexBlockLockClaimStore({ lockId })])];
|
return [constructContinueTx(context, [constructMutexBlockLockClaimStore(lockInfo)])];
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,14 +1,15 @@
|
|||||||
import { constructContinueTx, constructContractRef, Context } from '@coinweb/contract-kit';
|
import { constructContinueTx, constructContractRef, Context } from '@coinweb/contract-kit';
|
||||||
import { getContractIssuer, getMethodArguments } from 'lib/onchain';
|
import { getCallParameters, getContractIssuer, getMethodArguments } from 'lib/onchain';
|
||||||
|
|
||||||
import { waitSteps } from '../settings';
|
import { waitSteps } from '../settings';
|
||||||
import { MutexNotifyLockArgs, MutexWaitNotifyArgs } from '../types';
|
import { MutexNotifyLockArgs, MutexWaitNotifyArgs } from '../types';
|
||||||
|
|
||||||
import { notifyLockMethodName } from './names';
|
import { notifyLockMethodName, waitMethodName } from './names';
|
||||||
|
|
||||||
export const wait = (context: Context) => {
|
export const wait = (context: Context) => {
|
||||||
const issuer = getContractIssuer(context);
|
const issuer = getContractIssuer(context);
|
||||||
const [step, lockId] = getMethodArguments<MutexWaitNotifyArgs>(context);
|
const [step, lockInfo] = getMethodArguments<MutexWaitNotifyArgs>(context);
|
||||||
|
const { availableCweb } = getCallParameters(context);
|
||||||
|
|
||||||
//Including the notifyLock method as step
|
//Including the notifyLock method as step
|
||||||
if (step + 1 < waitSteps) {
|
if (step + 1 < waitSteps) {
|
||||||
@ -21,11 +22,11 @@ export const wait = (context: Context) => {
|
|||||||
callInfo: {
|
callInfo: {
|
||||||
ref: constructContractRef(issuer, []),
|
ref: constructContractRef(issuer, []),
|
||||||
methodInfo: {
|
methodInfo: {
|
||||||
methodName: notifyLockMethodName,
|
methodName: waitMethodName,
|
||||||
methodArgs: [step + 1, lockId] satisfies MutexWaitNotifyArgs,
|
methodArgs: [step + 1, lockInfo] satisfies MutexWaitNotifyArgs,
|
||||||
},
|
},
|
||||||
contractInfo: {
|
contractInfo: {
|
||||||
providedCweb: 200n,
|
providedCweb: availableCweb - 800n,
|
||||||
authenticated: null,
|
authenticated: null,
|
||||||
},
|
},
|
||||||
contractArgs: [],
|
contractArgs: [],
|
||||||
@ -46,10 +47,10 @@ export const wait = (context: Context) => {
|
|||||||
ref: constructContractRef(issuer, []),
|
ref: constructContractRef(issuer, []),
|
||||||
methodInfo: {
|
methodInfo: {
|
||||||
methodName: notifyLockMethodName,
|
methodName: notifyLockMethodName,
|
||||||
methodArgs: [lockId] satisfies MutexNotifyLockArgs,
|
methodArgs: [lockInfo] satisfies MutexNotifyLockArgs,
|
||||||
},
|
},
|
||||||
contractInfo: {
|
contractInfo: {
|
||||||
providedCweb: 200n,
|
providedCweb: availableCweb - 800n,
|
||||||
authenticated: null,
|
authenticated: null,
|
||||||
},
|
},
|
||||||
contractArgs: [],
|
contractArgs: [],
|
||||||
|
|||||||
@ -9,6 +9,11 @@ export type MutexLockState = {
|
|||||||
processId: string;
|
processId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type MutexNotifyLockState = {
|
||||||
|
timestamp: number;
|
||||||
|
lockId: string;
|
||||||
|
};
|
||||||
|
|
||||||
export type MutexExecOpsResult = (
|
export type MutexExecOpsResult = (
|
||||||
| {
|
| {
|
||||||
ok: true;
|
ok: true;
|
||||||
@ -24,9 +29,9 @@ export type MutexUnlockArgs = [lockId: string, timestamp: number, notify?: boole
|
|||||||
|
|
||||||
export type MutexExecOpArgs = [ops: (GTake<CwebTake> | GStore<CwebStore>)[], processId: string, execId?: string];
|
export type MutexExecOpArgs = [ops: (GTake<CwebTake> | GStore<CwebStore>)[], processId: string, execId?: string];
|
||||||
|
|
||||||
export type MutexWaitNotifyArgs = [step: number, lockId: string];
|
export type MutexWaitNotifyArgs = [step: number, lockInfo: MutexNotifyLockState];
|
||||||
|
|
||||||
export type MutexNotifyLockArgs = [lockId: string];
|
export type MutexNotifyLockArgs = [lockInfo: MutexNotifyLockState];
|
||||||
|
|
||||||
export type MutexPreReadTakeOpsArgs = [execId: string, unavailableIndexes: number[], ops: PreparedOperation[]];
|
export type MutexPreReadTakeOpsArgs = [execId: string, unavailableIndexes: number[], ops: PreparedOperation[]];
|
||||||
|
|
||||||
|
|||||||
@ -79,6 +79,8 @@ export const prepareInThreadTxs = ({
|
|||||||
//Info for separate child call
|
//Info for separate child call
|
||||||
const childCalls: FullCallInfo[] = [];
|
const childCalls: FullCallInfo[] = [];
|
||||||
|
|
||||||
|
const outThreadOps: PreparedOperation[] = [];
|
||||||
|
|
||||||
ops.forEach((op, i) => {
|
ops.forEach((op, i) => {
|
||||||
switch (true) {
|
switch (true) {
|
||||||
case isPreparedExecOp(op): {
|
case isPreparedExecOp(op): {
|
||||||
@ -136,12 +138,25 @@ export const prepareInThreadTxs = ({
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case isPreparedLockOp(op): {
|
case isPreparedLockOp(op): {
|
||||||
const { callInfo, fee, ops } = constructLockCall(context.issuer, op.LockOp.lockId);
|
const {
|
||||||
|
callInfo,
|
||||||
|
fee,
|
||||||
|
inThreadOps,
|
||||||
|
outThreadOps: outThreadOpsFromLockCall,
|
||||||
|
} = constructLockCall({
|
||||||
|
issuer: context.issuer,
|
||||||
|
lockId: op.LockOp.lockId,
|
||||||
|
timestamp: op.LockOp.timestamp,
|
||||||
|
keys: op.LockOp.keys,
|
||||||
|
processId: context.thisId,
|
||||||
|
});
|
||||||
|
|
||||||
childCalls.push({ callInfo });
|
childCalls.push({ callInfo });
|
||||||
callArgs.push(...ops);
|
callArgs.push(...inThreadOps);
|
||||||
txFee += fee;
|
txFee += fee;
|
||||||
|
|
||||||
|
outThreadOps.push(...outThreadOpsFromLockCall);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case isPreparedUnlockOp(op): {
|
case isPreparedUnlockOp(op): {
|
||||||
@ -252,8 +267,8 @@ export const prepareInThreadTxs = ({
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (childCalls.length) {
|
if (childCalls.length || outThreadOps.length) {
|
||||||
returnTxs.push(constructContinueTx(getRawContext(), [], childCalls));
|
returnTxs.push(constructContinueTx(getRawContext(), outThreadOps, childCalls));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -79,11 +79,19 @@ export const prepareOutThreadTxs = ({
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case isPreparedLockOp(op): {
|
case isPreparedLockOp(op): {
|
||||||
const { callInfo, fee } = constructLockCall(context.issuer, op.LockOp.lockId);
|
const { callInfo, fee, outThreadOps } = constructLockCall({
|
||||||
|
issuer: context.issuer,
|
||||||
|
lockId: op.LockOp.lockId,
|
||||||
|
timestamp: op.LockOp.timestamp,
|
||||||
|
keys: op.LockOp.keys,
|
||||||
|
processId: context.thisId,
|
||||||
|
});
|
||||||
|
|
||||||
preparedCalls.push({ callInfo });
|
preparedCalls.push({ callInfo });
|
||||||
txFee += fee;
|
txFee += fee;
|
||||||
|
|
||||||
|
preparedOps.push(...outThreadOps);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case isPreparedUnlockOp(op): {
|
case isPreparedUnlockOp(op): {
|
||||||
|
|||||||
@ -3,9 +3,8 @@ import { context } from '../context';
|
|||||||
let next = 0n;
|
let next = 0n;
|
||||||
|
|
||||||
export const uuid = () => {
|
export const uuid = () => {
|
||||||
const parentTxId = context.parentTxId;
|
const id = (BigInt(`0x${context.thisId}`) * 3n + BigInt(`0x${context.parentTxId}`) + next).toString(16).slice(-32);
|
||||||
|
|
||||||
const id = `${parentTxId}${next.toString(16)}`;
|
|
||||||
next += 1n;
|
next += 1n;
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
VITE_API_URL='https://api-cloud.coinweb.io/wallet'
|
VITE_API_URL='https://api-cloud.coinweb.io/wallet'
|
||||||
VITE_EXPLORER_URL='https://explorer.coinweb.io'
|
VITE_EXPLORER_URL='https://explorer.coinweb.io'
|
||||||
|
|
||||||
VITE_CONTRACT_ADDRESS="0x5b7c1e53461f5497d467cb9d5c772be5e8c1a61b60e7f2f4ce71c7249d8e768a"
|
VITE_CONTRACT_ADDRESS="0xedca91a29553fa2466e89eef02ac06dc49ab68be5e81fa91d05765cab79ec02a"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user