Skip to content

Commit

Permalink
feat: adds Orbit Client extension
Browse files Browse the repository at this point in the history
  • Loading branch information
douglance committed Dec 22, 2023
1 parent 737175c commit 366480f
Show file tree
Hide file tree
Showing 13 changed files with 300 additions and 207 deletions.
50 changes: 32 additions & 18 deletions examples/create-rollup-custom-fee-token/index.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
import { Chain, createPublicClient, http, Address } from 'viem';
import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts';
import { arbitrumSepolia } from 'viem/chains';
import { Chain, http, Address } from "viem";
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
import { arbitrumSepolia } from "viem/chains";
import {
createRollupPrepareConfig,
prepareChainConfig,
createRollupEnoughCustomFeeTokenAllowance,
createRollupPrepareCustomFeeTokenApprovalTransactionRequest,
createRollupPrepareTransactionRequest,
createRollupPrepareTransactionReceipt,
} from '@arbitrum/orbit-sdk';
import { generateChainId } from '@arbitrum/orbit-sdk/utils';
createOrbitClient,
} from "@arbitrum/orbit-sdk";
import { generateChainId } from "@arbitrum/orbit-sdk/utils";

function sanitizePrivateKey(privateKey: string): `0x${string}` {
if (!privateKey.startsWith('0x')) {
if (!privateKey.startsWith("0x")) {
return `0x${privateKey}`;
}

return privateKey as `0x${string}`;
}

function withFallbackPrivateKey(privateKey: string | undefined): `0x${string}` {
if (typeof privateKey === 'undefined') {
if (typeof privateKey === "undefined") {
return generatePrivateKey();
}

Expand All @@ -31,33 +32,41 @@ function getBlockExplorerUrl(chain: Chain) {
return chain.blockExplorers?.default.url;
}

if (typeof process.env.DEPLOYER_PRIVATE_KEY === 'undefined') {
throw new Error(`Please provide the "DEPLOYER_PRIVATE_KEY" environment variable`);
if (typeof process.env.DEPLOYER_PRIVATE_KEY === "undefined") {
throw new Error(
`Please provide the "DEPLOYER_PRIVATE_KEY" environment variable`
);
}

// load or generate a random batch poster account
const batchPosterPrivateKey = withFallbackPrivateKey(process.env.BATCH_POSTER_PRIVATE_KEY);
const batchPosterPrivateKey = withFallbackPrivateKey(
process.env.BATCH_POSTER_PRIVATE_KEY
);
const batchPoster = privateKeyToAccount(batchPosterPrivateKey).address;

// load or generate a random validator account
const validatorPrivateKey = withFallbackPrivateKey(process.env.VALIDATOR_PRIVATE_KEY);
const validatorPrivateKey = withFallbackPrivateKey(
process.env.VALIDATOR_PRIVATE_KEY
);
const validator = privateKeyToAccount(validatorPrivateKey).address;

// set the parent chain and create a public client for it
const parentChain = arbitrumSepolia;
const parentChainPublicClient = createPublicClient({
const parentChainPublicClient = createOrbitClient({
chain: parentChain,
transport: http(),
});

// load the deployer account
const deployer = privateKeyToAccount(sanitizePrivateKey(process.env.DEPLOYER_PRIVATE_KEY));
const deployer = privateKeyToAccount(
sanitizePrivateKey(process.env.DEPLOYER_PRIVATE_KEY)
);

async function main() {
// generate a random chain id
const chainId = generateChainId();
// set the custom fee token
const nativeToken: Address = '0xf861378b543525ae0c47d33c90c954dc774ac1f9';
const nativeToken: Address = "0xf861378b543525ae0c47d33c90c954dc774ac1f9";

// create the chain config
const chainConfig = prepareChainConfig({
Expand All @@ -75,9 +84,10 @@ async function main() {
};

if (!(await createRollupEnoughCustomFeeTokenAllowance(allowanceParams))) {
const approvalTxRequest = await createRollupPrepareCustomFeeTokenApprovalTransactionRequest(
allowanceParams
);
const approvalTxRequest =
await createRollupPrepareCustomFeeTokenApprovalTransactionRequest(
allowanceParams
);

// sign and send the transaction
const approvalTxHash = await parentChainPublicClient.sendRawTransaction({
Expand Down Expand Up @@ -125,7 +135,11 @@ async function main() {
await parentChainPublicClient.waitForTransactionReceipt({ hash: txHash })
);

console.log(`Deployed in ${getBlockExplorerUrl(parentChain)}/tx/${txReceipt.transactionHash}`);
console.log(
`Deployed in ${getBlockExplorerUrl(parentChain)}/tx/${
txReceipt.transactionHash
}`
);
}

main();
49 changes: 34 additions & 15 deletions examples/create-rollup-eth/index.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
import { Chain, createPublicClient, http } from 'viem';
import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts';
import { arbitrumSepolia } from 'viem/chains';
import { Chain, http } from "viem";
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
import { arbitrumSepolia } from "viem/chains";
import {
createRollupPrepareConfig,
prepareChainConfig,
createRollupPrepareTransactionRequest,
createRollupPrepareTransactionReceipt,
} from '@arbitrum/orbit-sdk';
import { generateChainId } from '@arbitrum/orbit-sdk/utils';
createOrbitClient,
} from "@arbitrum/orbit-sdk";
import { generateChainId } from "@arbitrum/orbit-sdk/utils";

function sanitizePrivateKey(privateKey: string): `0x${string}` {
if (!privateKey.startsWith('0x')) {
if (!privateKey.startsWith("0x")) {
return `0x${privateKey}`;
}

return privateKey as `0x${string}`;
}

function withFallbackPrivateKey(privateKey: string | undefined): `0x${string}` {
if (typeof privateKey === 'undefined') {
if (typeof privateKey === "undefined") {
return generatePrivateKey();
}

Expand All @@ -29,24 +30,35 @@ function getBlockExplorerUrl(chain: Chain) {
return chain.blockExplorers?.default.url;
}

if (typeof process.env.DEPLOYER_PRIVATE_KEY === 'undefined') {
throw new Error(`Please provide the "DEPLOYER_PRIVATE_KEY" environment variable`);
if (typeof process.env.DEPLOYER_PRIVATE_KEY === "undefined") {
throw new Error(
`Please provide the "DEPLOYER_PRIVATE_KEY" environment variable`
);
}

// load or generate a random batch poster account
const batchPosterPrivateKey = withFallbackPrivateKey(process.env.BATCH_POSTER_PRIVATE_KEY);
const batchPosterPrivateKey = withFallbackPrivateKey(
process.env.BATCH_POSTER_PRIVATE_KEY
);
const batchPoster = privateKeyToAccount(batchPosterPrivateKey).address;

// load or generate a random validator account
const validatorPrivateKey = withFallbackPrivateKey(process.env.VALIDATOR_PRIVATE_KEY);
const validatorPrivateKey = withFallbackPrivateKey(
process.env.VALIDATOR_PRIVATE_KEY
);
const validator = privateKeyToAccount(validatorPrivateKey).address;

// set the parent chain and create a public client for it
const parentChain = arbitrumSepolia;
const parentChainPublicClient = createPublicClient({ chain: parentChain, transport: http() });
const parentChainPublicClient = createOrbitClient({
chain: parentChain,
transport: http(),
});

// load the deployer account
const deployer = privateKeyToAccount(sanitizePrivateKey(process.env.DEPLOYER_PRIVATE_KEY));
const deployer = privateKeyToAccount(
sanitizePrivateKey(process.env.DEPLOYER_PRIVATE_KEY)
);

async function main() {
// generate a random chain id
Expand All @@ -55,7 +67,10 @@ async function main() {
// create the chain config
const chainConfig = prepareChainConfig({
chainId,
arbitrum: { InitialChainOwner: deployer.address, DataAvailabilityCommittee: true },
arbitrum: {
InitialChainOwner: deployer.address,
DataAvailabilityCommittee: true,
},
});

// prepare the transaction for deploying the core contracts
Expand Down Expand Up @@ -83,7 +98,11 @@ async function main() {
await parentChainPublicClient.waitForTransactionReceipt({ hash: txHash })
);

console.log(`Deployed in ${getBlockExplorerUrl(parentChain)}/tx/${txReceipt.transactionHash}`);
console.log(
`Deployed in ${getBlockExplorerUrl(parentChain)}/tx/${
txReceipt.transactionHash
}`
);
}

main();
26 changes: 15 additions & 11 deletions examples/prepare-node-config/index.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,30 @@
import { Chain, createPublicClient, http } from 'viem';
import { arbitrumSepolia } from 'viem/chains';
import { Chain, http } from "viem";
import { arbitrumSepolia } from "viem/chains";
import {
ChainConfig,
createRollupPrepareTransaction,
createRollupPrepareTransactionReceipt,
prepareNodeConfig,
} from '@arbitrum/orbit-sdk';
createOrbitClient,
} from "@arbitrum/orbit-sdk";

import { writeFile } from 'fs/promises';
import { writeFile } from "fs/promises";

function getRpcUrl(chain: Chain) {
return chain.rpcUrls.default.http[0];
}

// set the parent chain and create a public client for it
const parentChain = arbitrumSepolia;
const parentChainPublicClient = createPublicClient({
const parentChainPublicClient = createOrbitClient({
chain: parentChain,
transport: http(),
});

async function main() {
// tx hash for the transaction to create rollup
const txHash = '0x22bb24020ee839e4a266960aa73c6bf5b02621e2de3f2a755c9f2869014140d7';
const txHash =
"0x22bb24020ee839e4a266960aa73c6bf5b02621e2de3f2a755c9f2869014140d7";

// get the transaction
const tx = createRollupPrepareTransaction(
Expand All @@ -35,22 +37,24 @@ async function main() {
);

// get the chain config from the transaction inputs
const chainConfig: ChainConfig = JSON.parse(tx.getInputs()[0].config.chainConfig);
const chainConfig: ChainConfig = JSON.parse(
tx.getInputs()[0].config.chainConfig
);
// get the core contracts from the transaction receipt
const coreContracts = txReceipt.getCoreContracts();

// prepare the node config
const nodeConfig = prepareNodeConfig({
chainName: 'My Orbit Chain',
chainName: "My Orbit Chain",
chainConfig,
coreContracts,
batchPosterPrivateKey: 'INSERT_BATCH_POSTER_PRIVATE_KEY_HERE',
validatorPrivateKey: 'INSERT_VALIDATOR_PRIVATE_KEY_HERE',
batchPosterPrivateKey: "INSERT_BATCH_POSTER_PRIVATE_KEY_HERE",
validatorPrivateKey: "INSERT_VALIDATOR_PRIVATE_KEY_HERE",
parentChainId: parentChain.id,
parentChainRpcUrl: getRpcUrl(parentChain),
});

await writeFile('node-config.json', JSON.stringify(nodeConfig, null, 2));
await writeFile("node-config.json", JSON.stringify(nodeConfig, null, 2));
console.log(`Node config written to "node-config.json"`);
}

Expand Down
40 changes: 26 additions & 14 deletions examples/set-valid-keyset/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Chain, createPublicClient, http } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { arbitrumSepolia } from 'viem/chains';
import { setValidKeysetPrepareTransactionRequest } from '@arbitrum/orbit-sdk';
import { Chain, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { arbitrumSepolia } from "viem/chains";
import { setValidKeysetPrepareTransactionRequest } from "@arbitrum/orbit-sdk";
import { createOrbitClient } from "@arbitrum/orbit-sdk/dist";

function sanitizePrivateKey(privateKey: string): `0x${string}` {
if (!privateKey.startsWith('0x')) {
if (!privateKey.startsWith("0x")) {
return `0x${privateKey}`;
}

Expand All @@ -15,26 +16,33 @@ function getBlockExplorerUrl(chain: Chain) {
return chain.blockExplorers?.default.url;
}

if (typeof process.env.DEPLOYER_PRIVATE_KEY === 'undefined') {
throw new Error(`Please provide the "DEPLOYER_PRIVATE_KEY" environment variable`);
if (typeof process.env.DEPLOYER_PRIVATE_KEY === "undefined") {
throw new Error(
`Please provide the "DEPLOYER_PRIVATE_KEY" environment variable`
);
}

const keyset =
'0x00000000000000010000000000000001012160000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000';
"0x00000000000000010000000000000001012160000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";

// set the parent chain and create a public client for it
const parentChain = arbitrumSepolia;
const parentChainPublicClient = createPublicClient({ chain: parentChain, transport: http() });
const parentChainPublicClient = createOrbitClient({
chain: parentChain,
transport: http(),
});

// load the deployer account
const deployer = privateKeyToAccount(sanitizePrivateKey(process.env.DEPLOYER_PRIVATE_KEY));
const deployer = privateKeyToAccount(
sanitizePrivateKey(process.env.DEPLOYER_PRIVATE_KEY)
);

async function main() {
// prepare the transaction setting the keyset
const txRequest = await setValidKeysetPrepareTransactionRequest({
coreContracts: {
upgradeExecutor: '0x82c42d2cdcbe6b4482900e299b3532082e217132',
sequencerInbox: '0x42b5da0625cf278067955f07045f63cafd79274f',
upgradeExecutor: "0x82c42d2cdcbe6b4482900e299b3532082e217132",
sequencerInbox: "0x42b5da0625cf278067955f07045f63cafd79274f",
},
keyset,
account: deployer.address,
Expand All @@ -47,10 +55,14 @@ async function main() {
});

// wait for the transaction receipt
const txReceipt = await parentChainPublicClient.waitForTransactionReceipt({ hash: txHash });
const txReceipt = await parentChainPublicClient.waitForTransactionReceipt({
hash: txHash,
});

console.log(
`Keyset updated in ${getBlockExplorerUrl(parentChain)}/tx/${txReceipt.transactionHash}`
`Keyset updated in ${getBlockExplorerUrl(parentChain)}/tx/${
txReceipt.transactionHash
}`
);
}

Expand Down
12 changes: 8 additions & 4 deletions src/contracts.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { parseAbi } from 'viem';
import { parseAbi } from "viem";

import {
erc20ABI,
arbOwnerConfig,
arbOwnerPublicConfig,
rollupCreatorConfig,
tokenBridgeCreatorConfig,
} from './generated';
} from "./generated";

export const erc20 = {
abi: erc20ABI,
Expand All @@ -25,9 +25,13 @@ export const arbOwnerPublic = {
export const rollupCreator = rollupCreatorConfig;
export const tokenBridgeCreator = tokenBridgeCreatorConfig;

export const getRollupCreatorAddressForChainId = (
chainId: keyof typeof rollupCreator.address
) => rollupCreator.address[chainId];

export const upgradeExecutor = {
abi: parseAbi([
'function execute(address upgrade, bytes upgradeCallData)',
'function executeCall(address target, bytes targetCallData)',
"function execute(address upgrade, bytes upgradeCallData)",
"function executeCall(address target, bytes targetCallData)",
]),
};
Loading

0 comments on commit 366480f

Please sign in to comment.