Skip to content

Commit

Permalink
update wallet with sendTransaction
Browse files Browse the repository at this point in the history
  • Loading branch information
jnsdls committed Jan 17, 2024
1 parent 2f42c51 commit e3e08f3
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 59 deletions.
2 changes: 1 addition & 1 deletion packages/thirdweb/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ const tx = contract.transaction({
});

// Step 6: execute the transaction with the wallet
const receipt = await wallet.execute(tx);
const receipt = await wallet.sendTransaction(tx);

console.log("tx hash", receipt.transactionHash);

Expand Down
2 changes: 1 addition & 1 deletion packages/thirdweb/src/transaction/actions/estimate-gas.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { AbiFunction, Address } from "abitype";
import type { Transaction } from "../index.js";
import type { IWallet } from "../../wallets/utils/wallet.js";
import { getDefaultGasOverrides } from "../../gas/fee-data.js";
import { encode } from "./encode.js";
import { formatTransactionRequest, hexToBigInt } from "viem/utils";
import type { IWallet } from "../../wallets/interfaces/wallet.js";

export async function estimateGas<
const abiFn extends AbiFunction,
Expand Down
45 changes: 3 additions & 42 deletions packages/thirdweb/src/transaction/actions/execute.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import type { AbiFunction, Address } from "abitype";
import type { AbiFunction } from "abitype";
import type { Transaction } from "../index.js";
import type { IWallet } from "../../wallets/utils/wallet.js";
import { getDefaultGasOverrides } from "../../gas/fee-data.js";
import { encode } from "./encode.js";
import { estimateGas } from "./estimate-gas.js";
import { transactionCount } from "../../rpc/methods.js";
import type { Hash } from "viem";
import type { IWallet } from "../../wallets/interfaces/wallet.js";

export async function execute<
const abiFn extends AbiFunction,
Expand All @@ -14,39 +9,5 @@ export async function execute<
if (!wallet || !wallet.address) {
throw new Error("no wallet to sign with");
}
const rpcRequest = tx.client.rpc({ chainId: tx.inputs.chainId });

const [gasOverrides, encodedData, nextNonce, estimatedGas] =
await Promise.all([
getDefaultGasOverrides(tx.client, tx.inputs.chainId),
encode(tx),
transactionCount(rpcRequest, wallet.address),
estimateGas(tx, wallet),
]);

const signedTx = await wallet.signTransaction({
gas: estimatedGas,
to: tx.inputs.address as Address,
chainId: tx.inputs.chainId,
data: encodedData,
nonce: nextNonce,
...gasOverrides,
});

// send the tx
// TODO: move into rpc/methods
const { result } = await rpcRequest({
method: "eth_sendRawTransaction",
params: [signedTx],
});

tx.transactionHash = result as Hash;

return {
transactionHash: result as Hash,
wait: async () => {
const { waitForTxReceipt } = await import("./wait-for-tx-receipt.js");
return waitForTxReceipt(tx);
},
};
return wallet.sendTransaction(tx);
}
1 change: 0 additions & 1 deletion packages/thirdweb/src/transaction/actions/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export { encode } from "./encode.js";
export { estimateGas } from "./estimate-gas.js";
export { execute } from "./execute.js";
export { read } from "./read.js";
export { waitForTxReceipt } from "./wait-for-tx-receipt.js";
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import type { Transaction } from "../../transaction/index.js";
import type {
AbiFunction,
Address,
Hex,
SignableMessage,
TransactionReceipt,
TransactionSerializable,
TypedData,
TypedDataDefinition,
Expand All @@ -13,11 +16,22 @@ export interface IWallet {
disconnect: () => Promise<void>;
//
signMessage: (_message: SignableMessage) => Promise<Hex>;
signTransaction: (_tx: TransactionSerializable) => Promise<Hex>;
signTypedData: <
signTransaction?: (_tx: TransactionSerializable) => Promise<Hex>;
signTypedData?: <
const typedData extends TypedData | Record<string, unknown>,
primaryType extends keyof typedData | "EIP712Domain" = keyof typedData,
>(
_typedData: TypedDataDefinition<typedData, primaryType>,
) => Promise<Hex>;

// TX methods
sendTransaction: <abiFn extends AbiFunction>(
_tx: Transaction<abiFn>,
) => Promise<{
transactionHash: Hex,
wait: () => Promise<TransactionReceipt>,
}>;
estimateGas: <abiFn extends AbiFunction>(
_tx: Transaction<abiFn>,
) => Promise<bigint>;
}
71 changes: 59 additions & 12 deletions packages/thirdweb/src/wallets/private-key.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import type {
Hash,
Hex,
PrivateKeyAccount,
SignableMessage,
TransactionSerializable,
TypedDataDefinition,
} from "viem";
import type { ThirdwebClient } from "../client/client.js";
import type { IWallet } from "./utils/wallet.js";
import { privateKeyToAccount } from "viem/accounts";
import type { AbiFunction, TypedData } from "abitype";
import type { AbiFunction, Address, TypedData } from "abitype";
import type { Transaction } from "../transaction/index.js";
import { estimateGas } from "../transaction/actions/estimate-gas.js";
import { execute } from "../transaction/actions/execute.js";
import type { IWallet } from "./interfaces/wallet.js";

export function privateKeyWallet(client: ThirdwebClient) {
return new PrivateKeyWallet(client);
Expand All @@ -22,7 +20,6 @@ type PrivateKeyWalletConnectOptions = {
};

class PrivateKeyWallet implements IWallet {
// private _client: ThirdwebClient;
private account: PrivateKeyAccount | null = null;

get address() {
Expand All @@ -31,11 +28,12 @@ class PrivateKeyWallet implements IWallet {

// eslint-disable-next-line @typescript-eslint/no-unused-vars
constructor(_client: ThirdwebClient) {
// this._client = client;
// this.client = client;
}

public async connect(options: PrivateKeyWalletConnectOptions) {
const { pkey } = options;
const { privateKeyToAccount } = await import("viem/accounts");
this.account = privateKeyToAccount(pkey as Hex);
}

Expand Down Expand Up @@ -65,18 +63,67 @@ class PrivateKeyWallet implements IWallet {

// tx functions

public async estimateGas<abiFn extends AbiFunction>(tx: Transaction<abiFn>) {
if (!this.account) {
public async sendTransaction<abiFn extends AbiFunction>(
tx: Transaction<abiFn>,
) {
if (!this.account || !this.address) {
throw new Error("not connected");
}
return estimateGas(tx, this);
const rpcRequest = tx.client.rpc({ chainId: tx.inputs.chainId });

const [getDefaultGasOverrides, encode, transactionCount] =
await Promise.all([
import("../gas/fee-data.js").then((m) => m.getDefaultGasOverrides),
import("../transaction/actions/encode.js").then((m) => m.encode),
import("../rpc/methods.js").then((m) => m.transactionCount),
]);

const [gasOverrides, encodedData, nextNonce, estimatedGas] =
await Promise.all([
getDefaultGasOverrides(tx.client, tx.inputs.chainId),
encode(tx),
transactionCount(rpcRequest, this.address),
this.estimateGas(tx),
]);

const signedTx = await this.signTransaction({
gas: estimatedGas,
to: tx.inputs.address as Address,
chainId: tx.inputs.chainId,
data: encodedData,
nonce: nextNonce,
...gasOverrides,
});

// send the tx
// TODO: move into rpc/methods
const { result } = await rpcRequest({
method: "eth_sendRawTransaction",
params: [signedTx],
});
tx.transactionHash = result as Hash;

return {
transactionHash: result as Hash,
wait: async () => {
const { waitForTxReceipt } = await import(
"../transaction/actions/wait-for-tx-receipt.js"
);
return waitForTxReceipt(tx);
},
};
}

public async execute<abiFn extends AbiFunction>(tx: Transaction<abiFn>) {
public async estimateGas<abiFn extends AbiFunction>(
tx: Transaction<abiFn>,
): Promise<bigint> {
if (!this.account) {
throw new Error("not connected");
}
return execute(tx, this);
const { estimateGas } = await import(
"../transaction/actions/estimate-gas.js"
);
return estimateGas(tx, this);
}

public async disconnect() {
Expand Down

0 comments on commit e3e08f3

Please sign in to comment.