refactor: final touches for the new client api
This commit is contained in:
@@ -47,7 +47,7 @@ async function main() {
|
|||||||
const txs = loadTxFromFile();
|
const txs = loadTxFromFile();
|
||||||
|
|
||||||
const resumeFromContractTxId = 'YLVpmhSq5JmLltfg6R-5fL04rIRPrlSU22f6RQ6VyYE';
|
const resumeFromContractTxId = 'YLVpmhSq5JmLltfg6R-5fL04rIRPrlSU22f6RQ6VyYE';
|
||||||
let resumeFrom = true;
|
let resumeFrom = false;
|
||||||
|
|
||||||
logger.info(`Checking ${txs.length} contracts`);
|
logger.info(`Checking ${txs.length} contracts`);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "redstone-smartweave",
|
"name": "redstone-smartweave",
|
||||||
"version": "0.1.0-alpha.1",
|
"version": "0.2.0-alpha.1",
|
||||||
"description": "An implementation of the SmartWeave SDK.",
|
"description": "An implementation of the SmartWeave SDK.",
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"types": "lib/index.d.ts",
|
"types": "lib/index.d.ts",
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
"preversion": "yarn lint && yarn build",
|
"preversion": "yarn lint && yarn build",
|
||||||
"version": "yarn format && git add -A src",
|
"version": "yarn format && git add -A src",
|
||||||
"postversion": "git push && git push --tags",
|
"postversion": "git push && git push --tags",
|
||||||
|
"yalc:publish": "yarn build && yalc publish --push",
|
||||||
"test": "jest"
|
"test": "jest"
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
@@ -80,17 +80,21 @@ export class HandlerBasedContract<State> implements Contract<State> {
|
|||||||
|
|
||||||
const evalStateResult = await stateEvaluator.eval(executionContext, []);
|
const evalStateResult = await stateEvaluator.eval(executionContext, []);
|
||||||
|
|
||||||
|
logger.debug('Creating new intraction for view state');
|
||||||
|
|
||||||
const interaction: ContractInteraction<Input> = {
|
const interaction: ContractInteraction<Input> = {
|
||||||
input,
|
input,
|
||||||
caller: executionContext.caller
|
caller: executionContext.caller
|
||||||
};
|
};
|
||||||
|
|
||||||
|
logger.trace('interaction', interaction);
|
||||||
|
|
||||||
const handler = (await this.smartweave.executorFactory.create(
|
const handler = (await this.smartweave.executorFactory.create(
|
||||||
executionContext.contractDefinition
|
executionContext.contractDefinition
|
||||||
)) as HandlerApi<State>;
|
)) as HandlerApi<State>;
|
||||||
|
|
||||||
// TODO: what is the best way to create a transaction in this case?
|
// TODO: what is the best way to create a transaction in this case?
|
||||||
return await handler.handle<Input, View>(
|
const handleResult = await handler.handle<Input, View>(
|
||||||
executionContext,
|
executionContext,
|
||||||
evalStateResult.state,
|
evalStateResult.state,
|
||||||
interaction,
|
interaction,
|
||||||
@@ -107,6 +111,15 @@ export class HandlerBasedContract<State> implements Contract<State> {
|
|||||||
},
|
},
|
||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (handleResult.type !== 'ok') {
|
||||||
|
logger.fatal('Error while interacting with contract', {
|
||||||
|
type: handleResult.type,
|
||||||
|
error: handleResult.errorMessage
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return handleResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
async viewStateForTx<Input, View>(
|
async viewStateForTx<Input, View>(
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export class SmartWeaveNodeFactory extends SmartWeaveWebFactory {
|
|||||||
* Returns a {@link SmartWeave} that is using file-based cache for {@link StateEvaluator} layer
|
* Returns a {@link SmartWeave} that is using file-based cache for {@link StateEvaluator} layer
|
||||||
* and mem cache for the rest.
|
* and mem cache for the rest.
|
||||||
*/
|
*/
|
||||||
static fileCacheClient(arweave: Arweave, cacheBasePath?: string): SmartWeave {
|
static fileCached(arweave: Arweave, cacheBasePath?: string): SmartWeave {
|
||||||
const definitionLoader = new ContractDefinitionLoader(arweave, new MemCache());
|
const definitionLoader = new ContractDefinitionLoader(arweave, new MemCache());
|
||||||
|
|
||||||
const interactionsLoader = new CacheableContractInteractionsLoader(
|
const interactionsLoader = new CacheableContractInteractionsLoader(
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import { BsonFileBlockHeightSwCache, MemBlockHeightSwCache, MemCache } from '@sm
|
|||||||
/**
|
/**
|
||||||
* A factory that simplifies the process of creating different versions of {@link SmartWeave}.
|
* A factory that simplifies the process of creating different versions of {@link SmartWeave}.
|
||||||
* All versions use the {@link Evolve} plugin.
|
* All versions use the {@link Evolve} plugin.
|
||||||
|
* SmartWeave instances created by this factory can be safely used in a web environment.
|
||||||
*/
|
*/
|
||||||
export class SmartWeaveWebFactory {
|
export class SmartWeaveWebFactory {
|
||||||
/**
|
/**
|
||||||
@@ -52,9 +53,9 @@ export class SmartWeaveWebFactory {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a {@link SmartWeave} that (yup, you've guessed it!) does not use any caches.
|
* Returns a {@link SmartWeave} that (yup, you've guessed it!) does not use any caches.
|
||||||
* This one is gonna be slooow...
|
* This one is gonna be slooow!
|
||||||
*/
|
*/
|
||||||
static noCacheClient(arweave: Arweave): SmartWeave {
|
static nonCached(arweave: Arweave): SmartWeave {
|
||||||
const definitionLoader = new ContractDefinitionLoader(arweave);
|
const definitionLoader = new ContractDefinitionLoader(arweave);
|
||||||
const interactionsLoader = new ContractInteractionsLoader(arweave);
|
const interactionsLoader = new ContractInteractionsLoader(arweave);
|
||||||
const executorFactory = new HandlerExecutorFactory(arweave);
|
const executorFactory = new HandlerExecutorFactory(arweave);
|
||||||
|
|||||||
@@ -59,14 +59,14 @@ export class DefaultStateEvaluator implements StateEvaluator {
|
|||||||
executionContext.contractDefinition
|
executionContext.contractDefinition
|
||||||
)) as HandlerApi<State>;
|
)) as HandlerApi<State>;
|
||||||
|
|
||||||
logger.debug(
|
logger.trace(
|
||||||
'missingInteractions',
|
'missingInteractions',
|
||||||
missingInteractions.map((int) => {
|
missingInteractions.map((int) => {
|
||||||
return int.node.id;
|
return int.node.id;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
logger.debug('Init state', JSON.stringify(baseState.state));
|
logger.trace('Init state', JSON.stringify(baseState.state));
|
||||||
|
|
||||||
for (const missingInteraction of missingInteractions) {
|
for (const missingInteraction of missingInteractions) {
|
||||||
logger.debug(
|
logger.debug(
|
||||||
@@ -125,11 +125,11 @@ export class DefaultStateEvaluator implements StateEvaluator {
|
|||||||
|
|
||||||
private logResult<State>(result: InteractionResult<State, unknown>, currentTx: GQLNodeInterface) {
|
private logResult<State>(result: InteractionResult<State, unknown>, currentTx: GQLNodeInterface) {
|
||||||
if (result.type === 'exception') {
|
if (result.type === 'exception') {
|
||||||
logger.error(`${result.result}`);
|
logger.error(`${result.errorMessage}`);
|
||||||
logger.error(`Executing of interaction: ${currentTx.id} threw exception.`);
|
logger.error(`Executing of interaction: ${currentTx.id} threw exception.`);
|
||||||
}
|
}
|
||||||
if (result.type === 'error') {
|
if (result.type === 'error') {
|
||||||
logger.error(`${result.result}`);
|
logger.error(`${result.errorMessage}`);
|
||||||
logger.error(`Executing of interaction: ${currentTx.id} returned error.`);
|
logger.error(`Executing of interaction: ${currentTx.id} returned error.`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ export class HandlerExecutorFactory implements ExecutorFactory<HandlerApi<unknow
|
|||||||
const handler = contractFunction(swGlobal, BigNumber, clarity) as HandlerFunction<State, Input, Result>;
|
const handler = contractFunction(swGlobal, BigNumber, clarity) as HandlerFunction<State, Input, Result>;
|
||||||
const stateCopy = JSON.parse(JSON.stringify(state));
|
const stateCopy = JSON.parse(JSON.stringify(state));
|
||||||
swGlobal._activeTx = interactionTx;
|
swGlobal._activeTx = interactionTx;
|
||||||
logger.debug(`SmartWeave.contract.id: ${swGlobal.contract.id}`, swGlobal.contract.id);
|
logger.debug(`SmartWeave.contract.id:`, swGlobal.contract.id);
|
||||||
|
|
||||||
self.assignReadContractState<Input, State>(swGlobal, contractDefinition, executionContext, currentTx);
|
self.assignReadContractState<Input, State>(swGlobal, contractDefinition, executionContext, currentTx);
|
||||||
self.assignViewContractState<Input, State>(swGlobal, contractDefinition, executionContext);
|
self.assignViewContractState<Input, State>(swGlobal, contractDefinition, executionContext);
|
||||||
@@ -80,14 +80,20 @@ export class HandlerExecutorFactory implements ExecutorFactory<HandlerApi<unknow
|
|||||||
case 'ContractError':
|
case 'ContractError':
|
||||||
return {
|
return {
|
||||||
type: 'error',
|
type: 'error',
|
||||||
result: err.message,
|
errorMessage: err.message,
|
||||||
state
|
state,
|
||||||
|
// note: previous version was writing error message to a "result" field,
|
||||||
|
// which fucks-up the HandlerResult type definition -
|
||||||
|
// HandlerResult.result had to be declared as 'Result | string' - and that led to a poor dev exp.
|
||||||
|
// TODO: this might be breaking change!
|
||||||
|
result: null
|
||||||
};
|
};
|
||||||
default:
|
default:
|
||||||
return {
|
return {
|
||||||
type: 'exception',
|
type: 'exception',
|
||||||
result: `${(err && err.stack) || (err && err.message)}`,
|
errorMessage: `${(err && err.stack) || (err && err.message)}`,
|
||||||
state
|
state,
|
||||||
|
result: null
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -180,12 +186,13 @@ export type HandlerFunction<State, Input, Result> = (
|
|||||||
|
|
||||||
// TODO: change to XOR between result and state?
|
// TODO: change to XOR between result and state?
|
||||||
export type HandlerResult<State, Result> = {
|
export type HandlerResult<State, Result> = {
|
||||||
result: string | Result; // this really sucks, but has to be declared this way to be backwards compatbile
|
result: Result;
|
||||||
state: State;
|
state: State;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type InteractionResult<State, Result> = HandlerResult<State, Result> & {
|
export type InteractionResult<State, Result> = HandlerResult<State, Result> & {
|
||||||
type: 'ok' | 'error' | 'exception';
|
type: 'ok' | 'error' | 'exception';
|
||||||
|
errorMessage?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ContractInteraction<Input> = {
|
export type ContractInteraction<Input> = {
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import { LogLevel, RedStoneLogger } from '../RedStoneLogger';
|
|||||||
|
|
||||||
export const defaultLoggerOptions: ISettingsParam = {
|
export const defaultLoggerOptions: ISettingsParam = {
|
||||||
displayFunctionName: false,
|
displayFunctionName: false,
|
||||||
displayFilePath: 'hideNodeModulesOnly',
|
displayFilePath: 'hidden',
|
||||||
displayLoggerName: false,
|
displayLoggerName: true,
|
||||||
dateTimeTimezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
dateTimeTimezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||||
minLevel: 'debug'
|
minLevel: 'debug'
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user