Skip to content

Commit

Permalink
fix(write): add dry run - sync state - abortSignal - update interface
Browse files Browse the repository at this point in the history
  • Loading branch information
Atticus committed Mar 22, 2024
1 parent 6dfc969 commit 970bdef
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 24 deletions.
15 changes: 11 additions & 4 deletions src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,14 @@ export type EvaluationParameters<T = NonNullable<unknown>> = {
evaluationOptions?: EvaluationOptions | Record<string, never> | undefined;
} & T;

export type WriteParameters<Input> = {
dryRun?: boolean;
syncState?: boolean;
abortSignal?: AbortSignal;
functionName: string;
inputs: Input;
};

export interface BaseContract<T> {
getState(params: EvaluationParameters): Promise<T>;
connect(signer: ContractSigner): this;
Expand All @@ -94,10 +102,9 @@ export interface WriteContract {
functionName,
inputs,
evaluationOptions,
}: EvaluationParameters<{
functionName: string;
inputs: Input;
}>): Promise<Transaction | DataItem>;
}: EvaluationParameters<WriteParameters<Input>>): Promise<
Transaction | DataItem
>;
}

export interface SmartWeaveContract<T> {
Expand Down
62 changes: 42 additions & 20 deletions src/common/contracts/warp-contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
EvaluationParameters,
ReadContract,
WriteContract,
WriteParameters,
} from '../../types.js';
import { isDataItem, isTransaction } from '../../utils/arweave.js';
import { FailedRequestError, WriteInteractionError } from '../error.js';
Expand Down Expand Up @@ -136,28 +137,49 @@ export class WarpContract<T>
async writeInteraction<Input>({
functionName,
inputs,
}: EvaluationParameters<{
functionName: string;
inputs: Input;
}>): Promise<Transaction | DataItem> {
// Sync state before writing
await this.syncState();
const { interactionTx } =
(await this.contract.writeInteraction<Input>({
function: functionName,
...inputs,
})) ?? {};

if (!interactionTx) {
throw new WriteInteractionError(
`Failed to write contract interaction ${functionName}`,
);
syncState = true,
dryRun = true,
abortSignal,
}: EvaluationParameters<WriteParameters<Input>>): Promise<
Transaction | DataItem
> {
let writeResult: unknown;

while (!abortSignal || !abortSignal.aborted) {
// Sync state before writing
if (syncState) await this.syncState();

if (dryRun) {
const { errorMessage, type } = await this.contract.dryWrite<Input>({
function: functionName,
...inputs,
});
// type is ok, error, exception
if (type !== 'ok') {
throw new WriteInteractionError(
`Failed to dry run contract interaction ${functionName} with error: ${errorMessage}`,
);
}
}
const { interactionTx } =
(await this.contract.writeInteraction<Input>({
function: functionName,
...inputs,
})) ?? {};

if (!interactionTx) {
throw new WriteInteractionError(
`Failed to write contract interaction ${functionName}`,
);
}
writeResult = interactionTx;
}

// Flexible way to return information on the transaction, aids in caching and redoployment if desired by simply refetching tx anchor and resigning.
if (isTransaction(interactionTx)) {
return interactionTx as Transaction;
} else if (isDataItem(interactionTx)) {
return interactionTx as DataItem;
if (isTransaction(writeResult)) {
return writeResult as Transaction;
} else if (isDataItem(writeResult)) {
return writeResult as DataItem;
}

throw new WriteInteractionError(
Expand Down

0 comments on commit 970bdef

Please sign in to comment.