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 privateKey,
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 : privateKey: privateKey,
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 && _stateMutability != StateMutability.view) {
87 0 : throw ArgumentError('Function is not view or pure');
88 : }
89 :
90 0 : final _outputs = outputs ?? function.outputTypes;
91 :
92 0 : if (_outputs == null || _outputs.isEmpty) {
93 0 : throw ArgumentError('Outputs must be provided');
94 : }
95 :
96 0 : final data = function.buildDataField();
97 :
98 0 : final String result = await rpc.call(contractAddress: contractAddress, data: data);
99 :
100 0 : final resultBuffer = result.hexToBytesWithPrefix;
101 :
102 0 : return ExternalContractFunctionWithValuesAndOutputs.decode(
103 : data: resultBuffer,
104 : function: function,
105 : outputs: _outputs,
106 : stateMutability: stateMutability,
107 : );
108 : }
109 :
110 3 : Future<LocalContractFunctionWithValuesAndOutputs> readSafe({
111 : required LocalContractFunctionWithValues function,
112 : BlockNum? atBlock,
113 : }) async {
114 6 : if (function.stateMutability != StateMutability.pure &&
115 6 : function.stateMutability != StateMutability.view) {
116 0 : throw ArgumentError('Function is not view or pure');
117 : }
118 :
119 3 : final data = function.buildDataField();
120 :
121 9 : final String result = await rpc.call(contractAddress: contractAddress, data: data);
122 :
123 3 : final resultBuffer = result.hexToBytesWithPrefix;
124 :
125 3 : return LocalContractFunctionWithValuesAndOutputs.decode(
126 : data: resultBuffer,
127 : function: function,
128 : );
129 : }
130 : }
|