@@ -6,9 +6,10 @@ import {
6
6
type Account ,
7
7
type Hex ,
8
8
type WalletActions ,
9
+ type Client ,
10
+ type PublicActions ,
11
+ type WriteContractParameters ,
9
12
type EncodeFunctionDataParameters ,
10
- Client ,
11
- PublicActions ,
12
13
} from "viem" ;
13
14
import { getAction , encodeFunctionData } from "viem/utils" ;
14
15
import { readContract , writeContract as viem_writeContract } from "viem/actions" ;
@@ -21,6 +22,7 @@ import {
21
22
encodeKey ,
22
23
} from "@latticexyz/protocol-parser/internal" ;
23
24
import worldConfig from "../../mud.config" ;
25
+ import { worldCallAbi } from "../worldCallAbi" ;
24
26
25
27
type CallFromParameters = {
26
28
worldAddress : Hex ;
@@ -46,7 +48,6 @@ export function callFrom(
46
48
client : Client < Transport , chain , account > ,
47
49
) => Pick < WalletActions < chain , account > , "writeContract" > {
48
50
return ( client ) => ( {
49
- // Applies to: `client.writeContract`, `getContract(client, ...).write`
50
51
async writeContract ( writeArgs ) {
51
52
const _writeContract = getAction ( client , viem_writeContract , "writeContract" ) ;
52
53
@@ -55,11 +56,28 @@ export function callFrom(
55
56
writeArgs . address !== params . worldAddress ||
56
57
writeArgs . functionName === "call" ||
57
58
writeArgs . functionName === "callFrom" ||
59
+ writeArgs . functionName === "batchCallFrom" ||
58
60
writeArgs . functionName === "callWithSignature"
59
61
) {
60
62
return _writeContract ( writeArgs ) ;
61
63
}
62
64
65
+ // Wrap system calls from `batchCall` with delegator for a `batchCallFrom`
66
+ // TODO: remove this specific workaround once https://github.com/latticexyz/mud/pull/3506 lands
67
+ if ( writeArgs . functionName === "batchCall" ) {
68
+ const batchCallArgs = writeArgs as unknown as WriteContractParameters < worldCallAbi , "batchCall" > ;
69
+ const [ systemCalls ] = batchCallArgs . args ;
70
+ if ( ! systemCalls . length ) {
71
+ throw new Error ( "`batchCall` should have at least one system call." ) ;
72
+ }
73
+
74
+ return _writeContract ( {
75
+ ...batchCallArgs ,
76
+ functionName : "batchCallFrom" ,
77
+ args : [ systemCalls . map ( ( systemCall ) => ( { from : params . delegatorAddress , ...systemCall } ) ) ] ,
78
+ } ) ;
79
+ }
80
+
63
81
// Encode the World's calldata (which includes the World's function selector).
64
82
const worldCalldata = encodeFunctionData ( {
65
83
abi : writeArgs . abi ,
@@ -81,15 +99,12 @@ export function callFrom(
81
99
// Use `readHex` instead of `slice` to prevent out-of-bounds errors with calldata that has no args.
82
100
const systemCalldata = concat ( [ systemFunctionSelector , readHex ( worldCalldata , 4 ) ] ) ;
83
101
84
- // Construct args for `callFrom` .
85
- const callFromArgs : typeof writeArgs = {
86
- ...writeArgs ,
102
+ // Call `writeContract` with the new args .
103
+ return _writeContract ( {
104
+ ...( writeArgs as unknown as WriteContractParameters < worldCallAbi , "callFrom" > ) ,
87
105
functionName : "callFrom" ,
88
106
args : [ params . delegatorAddress , systemId , systemCalldata ] ,
89
- } ;
90
-
91
- // Call `writeContract` with the new args.
92
- return _writeContract ( callFromArgs ) ;
107
+ } ) ;
93
108
} ,
94
109
} ) ;
95
110
}
0 commit comments