Skip to content

Commit c9dfa00

Browse files
committed
stylus deployer for deployment with constructor
1 parent 99b7764 commit c9dfa00

File tree

6 files changed

+319
-2
lines changed

6 files changed

+319
-2
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[
2+
"function stylus_constructor()"
3+
]
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[
2+
"function deploy(bytes calldata bytecode,bytes calldata initData,uint256 initValue,bytes32 salt) public payable returns (address)",
3+
"event ContractDeployed(address deployedContract)"
4+
]

packages/thirdweb/src/contract/deployment/deploy-with-abi.ts

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
import type { Abi, AbiConstructor } from "abitype";
2+
import { parseEventLogs } from "../../event/actions/parse-logs.js";
3+
import { FN_SELECTOR } from "../../extensions/stylus/__generated__/IStylusConstructor/write/stylus_constructor.js";
4+
import { contractDeployedEvent } from "../../extensions/stylus/__generated__/IStylusDeployer/events/ContractDeployed.js";
5+
import { deploy } from "../../extensions/stylus/__generated__/IStylusDeployer/write/deploy.js";
26
import { activateStylusContract } from "../../extensions/stylus/write/activateStylusContract.js";
7+
import { eth_blockNumber } from "../../rpc/actions/eth_blockNumber.js";
8+
import { getRpcClient } from "../../rpc/rpc.js";
39
import { sendAndConfirmTransaction } from "../../transaction/actions/send-and-confirm-transaction.js";
410
import { sendTransaction } from "../../transaction/actions/send-transaction.js";
511
import { prepareTransaction } from "../../transaction/prepare-transaction.js";
@@ -11,7 +17,7 @@ import { isZkSyncChain } from "../../utils/any-evm/zksync/isZkSyncChain.js";
1117
import { isContractDeployed } from "../../utils/bytecode/is-contract-deployed.js";
1218
import { ensureBytecodePrefix } from "../../utils/bytecode/prefix.js";
1319
import { concatHex } from "../../utils/encoding/helpers/concat-hex.js";
14-
import { type Hex, isHex } from "../../utils/encoding/hex.js";
20+
import { type Hex, isHex, toHex } from "../../utils/encoding/hex.js";
1521
import type { Prettify } from "../../utils/type-utils.js";
1622
import type { ClientAndChain } from "../../utils/types.js";
1723
import type { Account } from "../../wallets/interfaces/wallet.js";
@@ -171,6 +177,58 @@ export async function deployContract(
171177
to: info.create2FactoryAddress,
172178
}),
173179
});
180+
} else if (options.isStylus && options.constructorParams) {
181+
const STYLUS_DEPLOYER = "0xCeCbA2F1dC234F70Dd89f2041029807F8D03A990";
182+
const stylusDeployer = getContract({
183+
address: STYLUS_DEPLOYER,
184+
chain: options.chain,
185+
client: options.client,
186+
});
187+
188+
const constructorAbi = options.abi.find(
189+
(abi) => abi.type === "constructor",
190+
) as AbiConstructor | undefined;
191+
const constructorCalldata = (FN_SELECTOR +
192+
encodeAbiParameters(
193+
constructorAbi?.inputs || [], // Leave an empty array if there's no constructor
194+
normalizeFunctionParams(
195+
constructorAbi,
196+
options.constructorParams,
197+
).slice(2),
198+
)) as `${typeof FN_SELECTOR}${string}`;
199+
200+
const rpcRequest = getRpcClient({
201+
...options,
202+
});
203+
const blockNumber = await eth_blockNumber(rpcRequest);
204+
const salt = toHex(blockNumber, {
205+
size: 32,
206+
});
207+
208+
const deployTx = deploy({
209+
bytecode: options.bytecode,
210+
contract: stylusDeployer,
211+
initData: constructorCalldata,
212+
initValue: 0n,
213+
salt,
214+
});
215+
216+
const receipt = await sendAndConfirmTransaction({
217+
account: options.account,
218+
transaction: deployTx,
219+
});
220+
221+
const deployEvent = contractDeployedEvent();
222+
const decodedEvent = parseEventLogs({
223+
events: [deployEvent],
224+
logs: receipt.logs,
225+
});
226+
if (decodedEvent.length === 0 || !decodedEvent[0]) {
227+
throw new Error(
228+
`No ContractDeployed event found in transaction: ${receipt.transactionHash}`,
229+
);
230+
}
231+
address = decodedEvent[0]?.args.deployedContract;
174232
} else {
175233
const deployTx = prepareDirectDeployTransaction(options);
176234
const receipt = await sendAndConfirmTransaction({
@@ -180,7 +238,7 @@ export async function deployContract(
180238
address = receipt.contractAddress;
181239
if (!address) {
182240
throw new Error(
183-
`Could not find deployed contract address in transaction: ${receipt.transactionHash}`,
241+
`Could not find deployed contract address in transaction: $receipt.transactionHash`,
184242
);
185243
}
186244
}

packages/thirdweb/src/extensions/stylus/__generated__/IStylusConstructor/write/stylus_constructor.ts

Lines changed: 50 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/thirdweb/src/extensions/stylus/__generated__/IStylusDeployer/events/ContractDeployed.ts

Lines changed: 24 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/thirdweb/src/extensions/stylus/__generated__/IStylusDeployer/write/deploy.ts

Lines changed: 178 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)