Skip to content

Commit 803e96e

Browse files
committed
TS Scripted Multisend
1 parent cce2192 commit 803e96e

File tree

8 files changed

+326
-63
lines changed

8 files changed

+326
-63
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
{
2+
"transactions": [
3+
{
4+
"hash": "0x23bfe882d57a8feeb40d999f62daa9cafaa2d3a5c30101c3afe71c196238c2c0",
5+
"transactionType": "CREATE",
6+
"contractName": "EOAMultisend",
7+
"contractAddress": "0xda51ebfbb740d2183e91faf762666b169a1a9a62",
8+
"function": null,
9+
"arguments": null,
10+
"transaction": {
11+
"from": "0xae5a4884d813f334e1b80b26402ec78fadaee7eb",
12+
"gas": "0xc9326",
13+
"value": "0x0",
14+
"input": "0x6080604052348015600e575f5ffd5b50610a8a8061001c5f395ff3fe608060405260043610610042575f3560e01c806309c5eabe146100455780631f6a1eb91461006d5780638d80ff0a14610095578063affed0e0146100b157610043565b5b005b348015610050575f5ffd5b5061006b6004803603810190610066919061072c565b6100db565b005b348015610078575f5ffd5b50610093600480360381019061008e91906107d0565b61014c565b005b6100af60048036038101906100aa919061072c565b610260565b005b3480156100bc575f5ffd5b506100c56102df565b6040516100d29190610861565b60405180910390f35b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610140576040517fded4370e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61014981610260565b50565b5f465f5f81548092919061015f906108a7565b919050558560405160200161017693929190610960565b6040516020818303038152906040528051906020012090505f610198826102e4565b90505f6101e88286868080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050610317565b90503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461024f576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61025886610260565b505050505050565b805160205b818110156102da578083015160f81c6001820184015160601c60158301850151603584018601516055850187015f855f81146102a857600181146102b7576102bb565b5f5f8585888a5af191506102bb565b5f5ffd5b505f81036102c7575f5ffd5b8260550187019650505050505050610265565b505050565b5f5481565b5f7f19457468657265756d205369676e6564204d6573736167653a0a3332000000005f5281601c52603c5f209050919050565b5f5f5f5f6103258686610341565b9250925092506103358282610396565b82935050505092915050565b5f5f5f6041845103610381575f5f5f602087015192506040870151915060608701515f1a9050610373888285856104f8565b95509550955050505061038f565b5f600285515f1b9250925092505b9250925092565b5f60038111156103a9576103a8610998565b5b8260038111156103bc576103bb610998565b5b03156104f457600160038111156103d6576103d5610998565b5b8260038111156103e9576103e8610998565b5b03610420576040517ff645eedf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002600381111561043457610433610998565b5b82600381111561044757610446610998565b5b0361048b57805f1c6040517ffce698f70000000000000000000000000000000000000000000000000000000081526004016104829190610861565b60405180910390fd5b60038081111561049e5761049d610998565b5b8260038111156104b1576104b0610998565b5b036104f357806040517fd78bce0c0000000000000000000000000000000000000000000000000000000081526004016104ea91906109dd565b60405180910390fd5b5b5050565b5f5f5f7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0845f1c1115610534575f6003859250925092506105d5565b5f6001888888886040515f81526020016040526040516105579493929190610a11565b6020604051602081039080840390855afa158015610577573d5f5f3e3d5ffd5b5050506020604051035190505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036105c8575f60015f5f1b935093509350506105d5565b805f5f5f1b935093509350505b9450945094915050565b5f604051905090565b5f5ffd5b5f5ffd5b5f5ffd5b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61063e826105f8565b810181811067ffffffffffffffff8211171561065d5761065c610608565b5b80604052505050565b5f61066f6105df565b905061067b8282610635565b919050565b5f67ffffffffffffffff82111561069a57610699610608565b5b6106a3826105f8565b9050602081019050919050565b828183375f83830152505050565b5f6106d06106cb84610680565b610666565b9050828152602081018484840111156106ec576106eb6105f4565b5b6106f78482856106b0565b509392505050565b5f82601f830112610713576107126105f0565b5b81356107238482602086016106be565b91505092915050565b5f60208284031215610741576107406105e8565b5b5f82013567ffffffffffffffff81111561075e5761075d6105ec565b5b61076a848285016106ff565b91505092915050565b5f5ffd5b5f5ffd5b5f5f83601f8401126107905761078f6105f0565b5b8235905067ffffffffffffffff8111156107ad576107ac610773565b5b6020830191508360018202830111156107c9576107c8610777565b5b9250929050565b5f5f5f604084860312156107e7576107e66105e8565b5b5f84013567ffffffffffffffff811115610804576108036105ec565b5b610810868287016106ff565b935050602084013567ffffffffffffffff811115610831576108306105ec565b5b61083d8682870161077b565b92509250509250925092565b5f819050919050565b61085b81610849565b82525050565b5f6020820190506108745f830184610852565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6108b182610849565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036108e3576108e261087a565b5b600182019050919050565b5f819050919050565b61090861090382610849565b6108ee565b82525050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f61093a8261090e565b6109448185610918565b9350610954818560208601610922565b80840191505092915050565b5f61096b82866108f7565b60208201915061097b82856108f7565b60208201915061098b8284610930565b9150819050949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b5f819050919050565b6109d7816109c5565b82525050565b5f6020820190506109f05f8301846109ce565b92915050565b5f60ff82169050919050565b610a0b816109f6565b82525050565b5f608082019050610a245f8301876109ce565b610a316020830186610a02565b610a3e60408301856109ce565b610a4b60608301846109ce565b9594505050505056fea2646970667358221220b3afe6d2bcb8fd25bdb05b143b2c8d0d4f443504c856fc371db1d3ddf250725664736f6c634300081c0033",
15+
"nonce": "0x39",
16+
"chainId": "0xaa36a7"
17+
},
18+
"additionalContracts": [],
19+
"isFixedGasLimit": false
20+
}
21+
],
22+
"receipts": [
23+
{
24+
"status": "0x1",
25+
"cumulativeGasUsed": "0xf86ab5",
26+
"logs": [],
27+
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
28+
"type": "0x2",
29+
"transactionHash": "0x23bfe882d57a8feeb40d999f62daa9cafaa2d3a5c30101c3afe71c196238c2c0",
30+
"transactionIndex": "0x9c",
31+
"blockHash": "0x8420fccb19cbd1292ac1da1411c867dfa2f2dc2e8b33974fbf87e019fad15496",
32+
"blockNumber": "0x7e95af",
33+
"gasUsed": "0x9ac45",
34+
"effectiveGasPrice": "0xf4251",
35+
"from": "0xae5a4884d813f334e1b80b26402ec78fadaee7eb",
36+
"to": null,
37+
"contractAddress": "0xda51ebfbb740d2183e91faf762666b169a1a9a62"
38+
}
39+
],
40+
"libraries": [],
41+
"pending": [],
42+
"returns": {},
43+
"timestamp": 1746870410,
44+
"chain": 11155111,
45+
"commit": "cce2192"
46+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
{
2+
"transactions": [
3+
{
4+
"hash": "0x23bfe882d57a8feeb40d999f62daa9cafaa2d3a5c30101c3afe71c196238c2c0",
5+
"transactionType": "CREATE",
6+
"contractName": "EOAMultisend",
7+
"contractAddress": "0xda51ebfbb740d2183e91faf762666b169a1a9a62",
8+
"function": null,
9+
"arguments": null,
10+
"transaction": {
11+
"from": "0xae5a4884d813f334e1b80b26402ec78fadaee7eb",
12+
"gas": "0xc9326",
13+
"value": "0x0",
14+
"input": "0x6080604052348015600e575f5ffd5b50610a8a8061001c5f395ff3fe608060405260043610610042575f3560e01c806309c5eabe146100455780631f6a1eb91461006d5780638d80ff0a14610095578063affed0e0146100b157610043565b5b005b348015610050575f5ffd5b5061006b6004803603810190610066919061072c565b6100db565b005b348015610078575f5ffd5b50610093600480360381019061008e91906107d0565b61014c565b005b6100af60048036038101906100aa919061072c565b610260565b005b3480156100bc575f5ffd5b506100c56102df565b6040516100d29190610861565b60405180910390f35b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610140576040517fded4370e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61014981610260565b50565b5f465f5f81548092919061015f906108a7565b919050558560405160200161017693929190610960565b6040516020818303038152906040528051906020012090505f610198826102e4565b90505f6101e88286868080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050610317565b90503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461024f576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61025886610260565b505050505050565b805160205b818110156102da578083015160f81c6001820184015160601c60158301850151603584018601516055850187015f855f81146102a857600181146102b7576102bb565b5f5f8585888a5af191506102bb565b5f5ffd5b505f81036102c7575f5ffd5b8260550187019650505050505050610265565b505050565b5f5481565b5f7f19457468657265756d205369676e6564204d6573736167653a0a3332000000005f5281601c52603c5f209050919050565b5f5f5f5f6103258686610341565b9250925092506103358282610396565b82935050505092915050565b5f5f5f6041845103610381575f5f5f602087015192506040870151915060608701515f1a9050610373888285856104f8565b95509550955050505061038f565b5f600285515f1b9250925092505b9250925092565b5f60038111156103a9576103a8610998565b5b8260038111156103bc576103bb610998565b5b03156104f457600160038111156103d6576103d5610998565b5b8260038111156103e9576103e8610998565b5b03610420576040517ff645eedf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002600381111561043457610433610998565b5b82600381111561044757610446610998565b5b0361048b57805f1c6040517ffce698f70000000000000000000000000000000000000000000000000000000081526004016104829190610861565b60405180910390fd5b60038081111561049e5761049d610998565b5b8260038111156104b1576104b0610998565b5b036104f357806040517fd78bce0c0000000000000000000000000000000000000000000000000000000081526004016104ea91906109dd565b60405180910390fd5b5b5050565b5f5f5f7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0845f1c1115610534575f6003859250925092506105d5565b5f6001888888886040515f81526020016040526040516105579493929190610a11565b6020604051602081039080840390855afa158015610577573d5f5f3e3d5ffd5b5050506020604051035190505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036105c8575f60015f5f1b935093509350506105d5565b805f5f5f1b935093509350505b9450945094915050565b5f604051905090565b5f5ffd5b5f5ffd5b5f5ffd5b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61063e826105f8565b810181811067ffffffffffffffff8211171561065d5761065c610608565b5b80604052505050565b5f61066f6105df565b905061067b8282610635565b919050565b5f67ffffffffffffffff82111561069a57610699610608565b5b6106a3826105f8565b9050602081019050919050565b828183375f83830152505050565b5f6106d06106cb84610680565b610666565b9050828152602081018484840111156106ec576106eb6105f4565b5b6106f78482856106b0565b509392505050565b5f82601f830112610713576107126105f0565b5b81356107238482602086016106be565b91505092915050565b5f60208284031215610741576107406105e8565b5b5f82013567ffffffffffffffff81111561075e5761075d6105ec565b5b61076a848285016106ff565b91505092915050565b5f5ffd5b5f5ffd5b5f5f83601f8401126107905761078f6105f0565b5b8235905067ffffffffffffffff8111156107ad576107ac610773565b5b6020830191508360018202830111156107c9576107c8610777565b5b9250929050565b5f5f5f604084860312156107e7576107e66105e8565b5b5f84013567ffffffffffffffff811115610804576108036105ec565b5b610810868287016106ff565b935050602084013567ffffffffffffffff811115610831576108306105ec565b5b61083d8682870161077b565b92509250509250925092565b5f819050919050565b61085b81610849565b82525050565b5f6020820190506108745f830184610852565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6108b182610849565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036108e3576108e261087a565b5b600182019050919050565b5f819050919050565b61090861090382610849565b6108ee565b82525050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f61093a8261090e565b6109448185610918565b9350610954818560208601610922565b80840191505092915050565b5f61096b82866108f7565b60208201915061097b82856108f7565b60208201915061098b8284610930565b9150819050949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b5f819050919050565b6109d7816109c5565b82525050565b5f6020820190506109f05f8301846109ce565b92915050565b5f60ff82169050919050565b610a0b816109f6565b82525050565b5f608082019050610a245f8301876109ce565b610a316020830186610a02565b610a3e60408301856109ce565b610a4b60608301846109ce565b9594505050505056fea2646970667358221220b3afe6d2bcb8fd25bdb05b143b2c8d0d4f443504c856fc371db1d3ddf250725664736f6c634300081c0033",
15+
"nonce": "0x39",
16+
"chainId": "0xaa36a7"
17+
},
18+
"additionalContracts": [],
19+
"isFixedGasLimit": false
20+
}
21+
],
22+
"receipts": [
23+
{
24+
"status": "0x1",
25+
"cumulativeGasUsed": "0xf86ab5",
26+
"logs": [],
27+
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
28+
"type": "0x2",
29+
"transactionHash": "0x23bfe882d57a8feeb40d999f62daa9cafaa2d3a5c30101c3afe71c196238c2c0",
30+
"transactionIndex": "0x9c",
31+
"blockHash": "0x8420fccb19cbd1292ac1da1411c867dfa2f2dc2e8b33974fbf87e019fad15496",
32+
"blockNumber": "0x7e95af",
33+
"gasUsed": "0x9ac45",
34+
"effectiveGasPrice": "0xf4251",
35+
"from": "0xae5a4884d813f334e1b80b26402ec78fadaee7eb",
36+
"to": null,
37+
"contractAddress": "0xda51ebfbb740d2183e91faf762666b169a1a9a62"
38+
}
39+
],
40+
"libraries": [],
41+
"pending": [],
42+
"returns": {},
43+
"timestamp": 1746870410,
44+
"chain": 11155111,
45+
"commit": "cce2192"
46+
}

script/DeployMultisend.s.sol

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ pragma solidity ^0.8.28;
44
import "forge-std/Script.sol";
55
import "forge-std/Vm.sol";
66
import "src/EOAMultisend.sol";
7-
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
8-
import "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol";
7+
import "lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol";
8+
import "lib/openzeppelin-contracts/contracts/utils/cryptography/MessageHashUtils.sol";
99

10-
contract DeployBatchCaller is Script {
10+
contract DeployMultisend is Script {
1111
EOAMultisend public multisend;
1212

1313
function run() external {

ts/index.ts

Lines changed: 0 additions & 58 deletions
This file was deleted.

ts/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"type": "module",
55
"private": true,
66
"scripts": {
7-
"fmt": "prettier --write *.ts"
7+
"fmt": "prettier --write **/*.ts"
88
},
99
"devDependencies": {
1010
"@types/bun": "latest",

ts/contract.ts renamed to ts/src/contract.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,5 @@ export const batchCallerABI = [
6666
},
6767
] as const;
6868

69-
export const contractAddress = "0x862d8Fd8dc4979b1AA72E808E73773dD0AAC3211";
69+
export const BATCH_CALLER_ADDRESS =
70+
"0x862d8Fd8dc4979b1AA72E808E73773dD0AAC3211";

ts/src/index.ts

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import dotenv from "dotenv";
2+
import {
3+
createWalletClient,
4+
http,
5+
encodeFunctionData,
6+
zeroAddress,
7+
toHex,
8+
getAddress,
9+
type Chain,
10+
parseEther,
11+
} from "viem";
12+
import { sepolia } from "viem/chains";
13+
import { privateKeyToAccount } from "viem/accounts";
14+
import { batchCallerABI, BATCH_CALLER_ADDRESS } from "./contract";
15+
import {
16+
EOA_MULTISEND_ADDRESS,
17+
type MetaTransaction,
18+
encodeMulti,
19+
} from "./multisend";
20+
21+
function printHash(chain: Chain, hash: `0x${string}`) {
22+
const explorer = chain.blockExplorers?.default;
23+
console.log(" Tx Receipt:", explorer?.url + "/tx/" + hash);
24+
}
25+
26+
async function batchCall(pk: `0x${string}`, calls: MetaTransaction[]) {
27+
console.log("Batch Call");
28+
const account = privateKeyToAccount(pk);
29+
30+
const walletClient = createWalletClient({
31+
account,
32+
chain: sepolia,
33+
transport: http(),
34+
});
35+
const authorization = await walletClient.signAuthorization({
36+
executor: "self",
37+
contractAddress: BATCH_CALLER_ADDRESS,
38+
});
39+
40+
const hash = await walletClient.sendTransaction({
41+
authorizationList: [authorization],
42+
data: encodeFunctionData({
43+
abi: batchCallerABI,
44+
functionName: "execute",
45+
args: [
46+
calls.map((c) => ({
47+
to: getAddress(c.to),
48+
value: BigInt(c.value),
49+
data: c.data as `0x${string}`,
50+
})),
51+
],
52+
}),
53+
to: walletClient.account.address,
54+
});
55+
printHash(walletClient.chain, hash);
56+
}
57+
58+
async function eoaMultisend(pk: `0x${string}`, calls: MetaTransaction[]) {
59+
console.log("EOA Multisend");
60+
const account = privateKeyToAccount(pk);
61+
62+
const walletClient = createWalletClient({
63+
account,
64+
chain: sepolia,
65+
transport: http(),
66+
});
67+
const authorization = await walletClient.signAuthorization({
68+
executor: "self",
69+
contractAddress: EOA_MULTISEND_ADDRESS,
70+
});
71+
72+
const hash = await walletClient.sendTransaction({
73+
authorizationList: [authorization],
74+
data: encodeMulti(calls),
75+
to: walletClient.account.address,
76+
});
77+
printHash(walletClient.chain, hash);
78+
}
79+
80+
const run = async (): Promise<void> => {
81+
dotenv.config();
82+
let privateKey = process.env.PK as `0x${string}`;
83+
if (!privateKey) {
84+
console.warn("Missing PK, using dummy account");
85+
privateKey =
86+
"0xe4dc8cbe94cbc139084c9c7adc5c2a829d3246f76282679e0c067147a47eb3f8";
87+
}
88+
89+
const calls = [
90+
{
91+
to: zeroAddress,
92+
value: toHex(parseEther("0.00001")),
93+
data: "0x",
94+
},
95+
{
96+
to: "0x1111111111111111111111111111111111111111",
97+
value: toHex(parseEther("0.00002")),
98+
data: "0x",
99+
},
100+
];
101+
// This is the human readable version of the multisend call
102+
// await batchCall(privateKey, calls);
103+
104+
// This is compact - gas efficient representation.
105+
await eoaMultisend(privateKey, calls);
106+
};
107+
108+
run();

0 commit comments

Comments
 (0)