Line data Source code
1 : import 'dart:typed_data';
2 : import 'package:walletkit_dart/src/crypto/evm/entities/block_number.dart';
3 : import 'package:walletkit_dart/walletkit_dart.dart';
4 :
5 : abstract class InternalContract {
6 : final ContractABI abi;
7 : final String contractAddress;
8 : final EvmRpcInterface rpc;
9 :
10 3 : const InternalContract({
11 : required this.abi,
12 : required this.contractAddress,
13 : required this.rpc,
14 : });
15 :
16 0 : Future<String> interact({
17 : required ContractFunctionWithValues function,
18 : required Uint8List seed,
19 : required String sender,
20 : EvmFeeInformation? feeInfo,
21 : BigInt? value,
22 : List<AccessListItem>? accessList,
23 : }) async {
24 0 : final functionData = function.buildDataField();
25 :
26 : if (value != null) {
27 : assert(
28 0 : function.stateMutability == StateMutability.payable,
29 : 'Function is not payable and cannot accept a value',
30 : );
31 : } else {
32 : assert(
33 0 : function.stateMutability == StateMutability.nonpayable,
34 : 'Function is payable and requires a value to be sent',
35 : );
36 : }
37 :
38 0 : return await rpc.buildAndBroadcastTransaction(
39 : sender: sender,
40 0 : recipient: contractAddress,
41 : seed: seed,
42 : feeInfo: feeInfo,
43 : data: functionData,
44 0 : value: value ?? BigInt.zero,
45 : accessList: accessList,
46 : );
47 : }
48 :
49 0 : Future<RawEvmTransaction> buildTransactionForFunction({
50 : required ContractFunctionWithValues function,
51 : required String sender,
52 : EvmFeeInformation? feeInfo,
53 : BigInt? value,
54 : }) async {
55 0 : final functionData = function.buildDataField();
56 :
57 : if (value != null) {
58 : assert(
59 0 : function.stateMutability == StateMutability.payable,
60 : 'Function is not payable and cannot accept a value',
61 : );
62 : } else {
63 : assert(
64 0 : function.stateMutability == StateMutability.nonpayable,
65 : 'Function is payable and requires a value to be sent',
66 : );
67 : }
68 :
69 0 : return await rpc.buildUnsignedTransaction(
70 : sender: sender,
71 0 : recipient: contractAddress,
72 : feeInfo: feeInfo,
73 : data: functionData,
74 0 : value: value ?? BigInt.zero,
75 : );
76 : }
77 :
78 0 : Future<ExternalContractFunctionWithValuesAndOutputs> read({
79 : required ExternalContractFunctionWithValues function,
80 : BlockNum? atBlock,
81 : required List<FunctionParam>? outputs,
82 : StateMutability? stateMutability,
83 : }) async {
84 0 : final _stateMutability = stateMutability ?? function.stateMutability;
85 :
86 0 : if (_stateMutability != StateMutability.pure &&
87 0 : _stateMutability != StateMutability.view) {
88 0 : throw ArgumentError('Function is not view or pure');
89 : }
90 :
91 0 : final _outputs = outputs ?? function.outputTypes;
92 :
93 0 : if (_outputs == null || _outputs.isEmpty) {
94 0 : throw ArgumentError('Outputs must be provided');
95 : }
96 :
97 0 : final data = function.buildDataField();
98 :
99 : final String result =
100 0 : await rpc.call(contractAddress: contractAddress, data: data);
101 :
102 0 : final resultBuffer = result.hexToBytesWithPrefix;
103 :
104 0 : return ExternalContractFunctionWithValuesAndOutputs.decode(
105 : data: resultBuffer,
106 : function: function,
107 : outputs: _outputs,
108 : stateMutability: stateMutability,
109 : );
110 : }
111 :
112 3 : Future<LocalContractFunctionWithValuesAndOutputs> readSafe({
113 : required LocalContractFunctionWithValues function,
114 : BlockNum? atBlock,
115 : }) async {
116 6 : if (function.stateMutability != StateMutability.pure &&
117 6 : function.stateMutability != StateMutability.view) {
118 0 : throw ArgumentError('Function is not view or pure');
119 : }
120 :
121 3 : final data = function.buildDataField();
122 :
123 : final String result =
124 9 : await rpc.call(contractAddress: contractAddress, data: data);
125 :
126 3 : final resultBuffer = result.hexToBytesWithPrefix;
127 :
128 3 : return LocalContractFunctionWithValuesAndOutputs.decode(
129 : data: resultBuffer,
130 : function: function,
131 : );
132 : }
133 : }
|