Skip to content

Instantly share code, notes, and snippets.

@yagopv
Last active May 27, 2024 13:54
Show Gist options
  • Save yagopv/60367ed1343ccc73f91e8feb6547b0e3 to your computer and use it in GitHub Desktop.
Save yagopv/60367ed1343ccc73f91e8feb6547b0e3 to your computer and use it in GitHub Desktop.
Counterfactual deployment + Transaction using the Safe SDK relay-kit
import { ethers } from "ethers";
import { EthersAdapter } from "@safe-global/protocol-kit";
import { Safe4337Pack } from "@safe-global/relay-kit";
const SAFE_OWNER = "";
const RPC_URL = "https://sepolia.base.org";
const BUNDLER_URL = "https://api.pimlico.io/v2/84532/rpc?apikey=";
const PRIVATE_KEY = ""
const TX_TO_ADDRESS = ""
const provider = new ethers.JsonRpcProvider(RPC_URL);
const signer = new ethers.Wallet(PRIVATE_KEY, provider);
const ethersAdapter = new EthersAdapter({
ethers,
signerOrProvider: signer,
});
// Counterfactual + Transaction execution
let safe4337Pack = await Safe4337Pack.init({
ethersAdapter,
rpcUrl: RPC_URL,
bundlerUrl: BUNDLER_URL,
options: {
owners: [SAFE_OWNER],
threshold: 1,
},
});
const safeAddress = await safe4337Pack.protocolKit.getAddress();
console.log("Safe Address:", safeAddress);
console.log(
"Is Safe deployed: ",
await safe4337Pack.protocolKit.isSafeDeployed()
);
const emptyTransaction = {
to: TX_TO_ADDRESS,
value: ethers.parseUnits("0.0001", "ether"),
data: "0x",
};
let safeOperation = await safe4337Pack.createTransaction({
transactions: [emptyTransaction],
});
let signedSafeOperation = await safe4337Pack.signSafeOperation(safeOperation);
await waitForUserOperation();
// Execute new transaction
safe4337Pack = await Safe4337Pack.init({
ethersAdapter,
rpcUrl: RPC_URL,
bundlerUrl: BUNDLER_URL,
options: {
safeAddress,
},
});
safeOperation = await safe4337Pack.createTransaction({
transactions: [emptyTransaction],
});
signedSafeOperation = await safe4337Pack.signSafeOperation(safeOperation);
await waitForUserOperation();
async function waitForUserOperation() {
let userOperationHash = await safe4337Pack.executeTransaction({
executable: signedSafeOperation,
});
let userOperationReceipt = null;
while (!userOperationReceipt) {
await new Promise((resolve) => setTimeout(resolve, 2000));
userOperationReceipt = await safe4337Pack.getUserOperationReceipt(
userOperationHash
);
}
console.group("User Operation Receipt and hash");
console.log("User Operation Receipt", userOperationReceipt);
console.log(
"User Operation By Hash",
await safe4337Pack.getUserOperationByHash(userOperationHash)
);
console.groupEnd();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment