@@ -6,9 +6,10 @@ import {
66 type Account ,
77 type Hex ,
88 type WalletActions ,
9+ type Client ,
10+ type PublicActions ,
11+ type WriteContractParameters ,
912 type EncodeFunctionDataParameters ,
10- Client ,
11- PublicActions ,
1213} from "viem" ;
1314import { getAction , encodeFunctionData } from "viem/utils" ;
1415import { readContract , writeContract as viem_writeContract } from "viem/actions" ;
@@ -21,6 +22,7 @@ import {
2122 encodeKey ,
2223} from "@latticexyz/protocol-parser/internal" ;
2324import worldConfig from "../../mud.config" ;
25+ import { worldCallAbi } from "../worldCallAbi" ;
2426
2527type CallFromParameters = {
2628 worldAddress : Hex ;
@@ -46,7 +48,6 @@ export function callFrom(
4648 client : Client < Transport , chain , account > ,
4749) => Pick < WalletActions < chain , account > , "writeContract" > {
4850 return ( client ) => ( {
49- // Applies to: `client.writeContract`, `getContract(client, ...).write`
5051 async writeContract ( writeArgs ) {
5152 const _writeContract = getAction ( client , viem_writeContract , "writeContract" ) ;
5253
@@ -55,11 +56,28 @@ export function callFrom(
5556 writeArgs . address !== params . worldAddress ||
5657 writeArgs . functionName === "call" ||
5758 writeArgs . functionName === "callFrom" ||
59+ writeArgs . functionName === "batchCallFrom" ||
5860 writeArgs . functionName === "callWithSignature"
5961 ) {
6062 return _writeContract ( writeArgs ) ;
6163 }
6264
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+
6381 // Encode the World's calldata (which includes the World's function selector).
6482 const worldCalldata = encodeFunctionData ( {
6583 abi : writeArgs . abi ,
@@ -81,15 +99,12 @@ export function callFrom(
8199 // Use `readHex` instead of `slice` to prevent out-of-bounds errors with calldata that has no args.
82100 const systemCalldata = concat ( [ systemFunctionSelector , readHex ( worldCalldata , 4 ) ] ) ;
83101
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" > ) ,
87105 functionName : "callFrom" ,
88106 args : [ params . delegatorAddress , systemId , systemCalldata ] ,
89- } ;
90-
91- // Call `writeContract` with the new args.
92- return _writeContract ( callFromArgs ) ;
107+ } ) ;
93108 } ,
94109 } ) ;
95110}
0 commit comments