-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
invocation-results.ts
97 lines (86 loc) · 3.17 KB
/
invocation-results.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable max-classes-per-file */
import type { CallResult, TransactionResponse, TransactionResult } from '@fuel-ts/providers';
import type { ReceiptScriptResult } from '@fuel-ts/transactions';
import { ReceiptType } from '@fuel-ts/transactions';
import { contractCallScript } from '../../scripts';
import type { InvocationScopeLike } from '../../types';
function getGasUsage(callResult: CallResult) {
const scriptResult = callResult.receipts.find((r) => r.type === ReceiptType.ScriptResult) as
| ReceiptScriptResult
| undefined;
return scriptResult?.gasUsed || 0n;
}
class InvocationResult<T = any> {
readonly functionScopes: Array<InvocationScopeLike>;
readonly isMultiCall: boolean;
readonly gasUsed: bigint;
readonly value: T;
constructor(
funcScopes: InvocationScopeLike | Array<InvocationScopeLike>,
callResult: CallResult,
isMultiCall: boolean
) {
this.functionScopes = Array.isArray(funcScopes) ? funcScopes : [funcScopes];
this.isMultiCall = isMultiCall;
this.value = this.getDecodedValue(callResult);
this.gasUsed = getGasUsage(callResult);
}
protected getDecodedValue(callResult: CallResult) {
const encodedResults = contractCallScript.decodeCallResult(callResult);
const returnValues = encodedResults.map((encodedResult, i) => {
const { contract, func } = this.functionScopes[i].getCallConfig();
return contract.interface.decodeFunctionResult(func, encodedResult)?.[0];
});
return (this.isMultiCall ? returnValues : returnValues?.[0]) as T;
}
}
export class FunctionInvocationResult<T = any> extends InvocationResult<T> {
readonly transactionId: string;
readonly transactionResponse: TransactionResponse;
readonly transactionResult: TransactionResult<any>;
constructor(
funcScopes: InvocationScopeLike | Array<InvocationScopeLike>,
transactionResponse: TransactionResponse,
transactionResult: TransactionResult<any>,
isMultiCall: boolean
) {
super(funcScopes, transactionResult, isMultiCall);
this.transactionResponse = transactionResponse;
this.transactionResult = transactionResult;
this.transactionId = this.transactionResponse.id;
}
static async build<T>(
funcScope: InvocationScopeLike | Array<InvocationScopeLike>,
transactionResponse: TransactionResponse,
isMultiCall: boolean
) {
const txResult = await transactionResponse.waitForResult();
const fnResult = new FunctionInvocationResult<T>(
funcScope,
transactionResponse,
txResult,
isMultiCall
);
return fnResult;
}
}
export class InvocationCallResult<T = any> extends InvocationResult<T> {
readonly callResult: CallResult;
constructor(
funcScopes: InvocationScopeLike | Array<InvocationScopeLike>,
callResult: CallResult,
isMultiCall: boolean
) {
super(funcScopes, callResult, isMultiCall);
this.callResult = callResult;
}
static async build<T>(
funcScopes: InvocationScopeLike | Array<InvocationScopeLike>,
callResult: CallResult,
isMultiCall: boolean
) {
const fnResult = new InvocationCallResult<T>(funcScopes, callResult, isMultiCall);
return fnResult;
}
}