Skip to content

Conversation

@samgermain
Copy link
Contributor

@samgermain samgermain commented May 7, 2025

Background

What does this PR do?

Previously, waitForReceipt returned only a minimal object like { hash: "0x..." }. Since sendTransaction calls waitForReceipt and returns its result, this meant that the result of sendTransaction also only included the hash.

However, when I was extending ethers.Signer, there were methods that expected a full transaction receipt object with properties like to, from, hash, etc. When it tried to access something like tx["to"].concat(...), it failed because to was undefined, causing a runtime error.

This PR updates waitForReceipt to return the complete transaction receipt, ensuring sendTransaction passes back the full data structure

  • waitForReceipt returns the entire response object, instead of the just the hash
  • creates type EVMTransactionResult
  • new type TransactionLog
  • EVM transaction has more properites

Testing

Detailed testing results

import { config } from 'dotenv';
import { parseEther, createWalletClient, http } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { sepolia } from 'viem/chains';
import { viem } from '@goat-sdk/wallet-viem';
import {
    lit,
    createLitNodeClient,
    createEthersWallet,
    createLitContractsClient,
    mintCapacityCredit,
    mintPKP,
    getPKPSessionSigs,
    generateWrappedKey,
    getWrappedKeyMetadata,
    LIT_NETWORKS_KEYS,
} from '@goat-sdk/wallet-lit';
import { safe } from "@goat-sdk/wallet-safe";
import { crossmint } from "@goat-sdk/crossmint";
import { ethers } from 'ethers';


config();

const { 
    WALLET_PRIVATE_KEY,
    SEPOLIA_RPC,
    BASE_RPC,
    CHAIN_NAME,
    WALLET_ADDRESS,
    RECIPIENT,
    DOCILE_SEPOLIA_SAFE,
    LIT_NETWORK = 'datil-test',
    STAGING_CROSSMINT_SERVER_API_KEY,
    STAGING_CROSSMINT_SMART_WALLET_ADDRESS,
    STAGING_CROSSMINT_WALLET_CLIENT_SECRET_KEY,

} = process.env;

async function sendFromViemWallet() {
    const account = privateKeyToAccount(WALLET_PRIVATE_KEY! as `0x${string}`);

    const walletClient = viem(createWalletClient({
        account,
        chain: sepolia,
        transport: http(SEPOLIA_RPC!),
    }));

    const hash = await walletClient.sendTransaction({
        to: RECIPIENT! as `0x${string}`,
        value: parseEther('0.001'),
    });

    console.log('✅ Viem Wallet tx response:', hash);
}


async function sendFromLitWallet() {
    const litNodeClient = await createLitNodeClient(LIT_NETWORK as LIT_NETWORKS_KEYS);
    const signer = createEthersWallet(WALLET_PRIVATE_KEY!);
    const contractsClient = await createLitContractsClient(signer, LIT_NETWORK as LIT_NETWORKS_KEYS);

    const capacityCredit = await mintCapacityCredit(contractsClient, 10, 30);
    const pkp = await mintPKP(contractsClient);
    const sessionSigs = await getPKPSessionSigs(
        litNodeClient,
        pkp.publicKey,
        pkp.ethAddress,
        signer,
        capacityCredit.capacityTokenId
    );
    const wrappedKey = await generateWrappedKey(litNodeClient, sessionSigs, 'evm');
    const metadata = await getWrappedKeyMetadata(litNodeClient, sessionSigs, wrappedKey.id);

    const fundingWallet = new ethers.Wallet(WALLET_PRIVATE_KEY!, new ethers.providers.JsonRpcProvider(SEPOLIA_RPC!));
    const transferAmount = ethers.utils.parseEther('0.01');

    // console.log(
    //     `💰 Funding wrapped key ${metadata.wrappedKeyAddress} with ${ethers.utils.formatEther(transferAmount)} ETH...`
    // );
    const tx = await fundingWallet.sendTransaction({
        to: metadata.wrappedKeyAddress,
        value: transferAmount,
    });
    await tx.wait();
    // console.log(`✅ Funded wrapped key: ${tx.hash}`);

    const viemWalletClient = createWalletClient({
        transport: http(SEPOLIA_RPC!),
        chain: sepolia,
    });

    const litWallet = lit({
        litNodeClient,
        pkpSessionSigs: sessionSigs,
        wrappedKeyMetadata: metadata,
        network: 'evm',
        chainId: 11155111,
        litEVMChainIdentifier: 'sepolia',
        viemWalletClient,
    });

    const receipt = await litWallet.sendTransaction({
        to: RECIPIENT!,
        value: parseEther('0.001'),
    });

    console.log('✅ Lit Wallet tx:', receipt);
}



async function sendFromSafeWallet() {
    const wallet = await safe(
        WALLET_PRIVATE_KEY! as `0x${string}`, 
        sepolia
    );

    const tx = await wallet.sendTransaction({
        to: RECIPIENT! as `0x${string}`,
        value: parseEther('0.001'),
    });

    console.log("✅ Safe Wallet tx response:", tx);
}



async function sendFromSmartWallet() {
    const { evmSmartWallet } = crossmint(STAGING_CROSSMINT_SERVER_API_KEY);
    const wallet = await evmSmartWallet({
        address: STAGING_CROSSMINT_SMART_WALLET_ADDRESS,
        signer: {
            secretKey: STAGING_CROSSMINT_WALLET_CLIENT_SECRET_KEY as `0x${string}`,
        },
        chain: "base-sepolia", // or the appropriate chain
        provider: BASE_RPC,
    });

    const tx = await wallet.sendTransaction({
        to: RECIPIENT! as `0x${string}`,
        value: parseEther("0.001"),
    });

    console.log("✅ Smart Wallet tx response:", tx);
}

(async () => {
    // await sendFromViemWallet();
    // await sendFromLitWallet();
    // await sendFromSafeWallet();
    await sendFromSmartWallet();
})();
% tsx src/sendTransaction.test.ts
lit-js-sdk:constants:errors deprecated LitErrorKind is deprecated and will be removed in a future version. Use LIT_ERROR_KIND instead. node:internal/modules/cjs/loader:1369:14
✅ Viem Wallet tx response: {
  blockHash: '0xa4f27f05b04af92431f8b54ab6832ae028f902503a4ba87c9302ee5dbad2d8f1',
  blockNumber: 8277644n,
  contractAddress: '0xd04e7f0094979c86fdbee9d87ab45b3a4d9e01ee',
  cumulativeGasUsed: 9824381n,
  effectiveGasPrice: 2054000n,
  from: '0x0ef3456e616552238b0c562d409507ed6051a7b3',
  gasUsed: 53000n,
  logs: [],
  logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
  status: 'success',
  to: null,
  transactionHash: '0x2a4d40f9756bb0da45b8c47280f5772487d9aaf0b0172c1cdf58a14733e2fd91',
  transactionIndex: 86,
  type: 'eip1559',
  hash: '0x2a4d40f9756bb0da45b8c47280f5772487d9aaf0b0172c1cdf58a14733e2fd91'
}
✅ Lit Wallet tx: {
  blockHash: '0x4a9540354579fd81347987a112598e80a82f203651ff08ef25ac244ff222da81',
  blockNumber: 8332823n,
  contractAddress: null,
  cumulativeGasUsed: 26198647n,
  effectiveGasPrice: 12533407871n,
  from: '0x4c7e8a79c061897f4234a8ceab282bf464774c61',
  gasUsed: 21000n,
  logs: [],
  logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
  status: 'success',
  to: '0x0ef3456e616552238b0c562d409507ed6051a7b3',
  transactionHash: '0x3e9fe1f0e4859e2f07e1e09128f8b48045e0cc5eb4cde5211dac4f24310e289d',
  transactionIndex: 234,
  type: 'legacy',
  hash: '0x3e9fe1f0e4859e2f07e1e09128f8b48045e0cc5eb4cde5211dac4f24310e289d'
}

Checklist

  • I have tested this change and added the relevant screenshots to the PR description
  • I updated the README if necessary to include the new plugin, wallet, chain, etc.

If you require releasing a new version of the package:

  • I have added a changset for the specific package by running pnpm change:add from the typescript directory

samgermain added 3 commits May 2, 2025 17:06
… types TransactionLog and EVMTransactionResult

local types AccessList and Address for use in EVMTransaction
…eceipt

sendTransaction also returns the entire transaction receipt as well
@samgermain samgermain mentioned this pull request May 7, 2025
3 tasks
@changeset-bot
Copy link

changeset-bot bot commented May 15, 2025

⚠️ No Changeset found

Latest commit: c606ec1

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@samgermain
Copy link
Contributor Author

@0xaguspunk Any chance of this getting merged any time soon?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant