Step 6: Signing transactions with Privy

The application must sign the transactions received during the quote-fetching step using the user key stored in Privy.

To accomplish this, the app utilizes the PrivyProvider. Here’s an example:

import { Address, createWalletClient, custom, Hash } from "viem";
import { ConnectedWallet } from "@privy-io/react-auth";
// below interface corresponds to ChainOperationSwaggerDto on OneBalance Swagger documentation
import { ChainOperation } from '<your path to OneBalance interfaces>';
// below interface corresponds to QuoteSwaggerDto on OneBalance Swagger documentation
import { Quote } from '<your path to OneBalance interfaces>';

const signTypedDataWithPrivy =
  (embeddedWallet: ConnectedWallet) =>
  async (typedData: any): Promise<Hash> => {
    const provider = await embeddedWallet.getEthereumProvider();
    const walletClient = createWalletClient({
      transport: custom(provider),
      account: embeddedWallet.address as Address,
    });

    return walletClient.signTypedData(typedData);
  };

const signOperation = (embeddedWallet: ConnectedWallet) => async (
    operation: ChainOperation
  ): Promise<ChainOperation> => {
    const signature = await signTypedDataWithPrivy(embeddedWallet)(operation.typedDataToSign);

    return {
      ...operation,
      userOp: { ...operation.userOp, signature },
    };
  };

export const signQuote = async (quote: Quote, embeddedWallet: ConnectedWallet) => {
    const signWithEmbeddedWallet = signOperation(embeddedWallet);

    const signedQuote = {
      ...quote,
    };

    signedQuote.originChainsOperations = await Promise.all(
      quote.originChainsOperations.map(signWithEmbeddedWallet)
    );
    if (quote.destinationChainOperation) {
      signedQuote.destinationChainOperation = await signWithEmbeddedWallet(
        quote.destinationChainOperation
      );
    }
    return signedQuote;
}

For more detailed implementation, refer to the sample application here.

Last updated