perawallet / connect

JavaScript SDK for integrating Pera Wallet to web applications.
https://perawallet.app
Other
64 stars 20 forks source link

Add support for TransactionSigner #44

Open smonn opened 2 years ago

smonn commented 2 years ago

The TransactionSigner works really well with the AtomicTransactionComposer, which is really helpful when interacting with smart contracts or group/atomic transactions. The TransactionSigner interface/type is defined as:

/**
 * This type represents a function which can sign transactions from an atomic transaction group.
 * @param txnGroup - The atomic group containing transactions to be signed
 * @param indexesToSign - An array of indexes in the atomic transaction group that should be signed
 * @returns A promise which resolves an array of encoded signed transactions. The length of the
 *   array will be the same as the length of indexesToSign, and each index i in the array
 *   corresponds to the signed transaction from txnGroup[indexesToSign[i]]
 */
export declare type TransactionSigner = (txnGroup: Transaction[], indexesToSign: number[]) => Promise<Uint8Array[]>;

A basic implementation of it would look like this (but should probably live in the PeraWalletConnect type/class):

function peraWalletSigner(peraWallet: PeraWalletConnect): TransactionSigner {
  return async (txnGroup, indexesToSign) => {
    return await peraWallet.signTransaction([
      txnGroup.map((txn, index) => {
        if (indexesToSign.includes(index)) {
          return {
            txn,
          };
        }

        return {
          txn,
          signers: [],
        };
      }),
    ]);
  };
}

Usage:

const peraWallet = new PeraWalletConnect();
const client = new Algodv2(/* ... */);
const atc = new AtomicTransactionComposer();
const sender = '....' // account address from peraWallet.connect() or peraWallet.reconnectSession()
const suggestedParams = await client.getTransactionParams().do();

atc.addTransaction({
  signer: peraWalletSigner(peraWallet),
  txn: algosdk.makePaymentTxnWithSuggestedParamsFromObject({
    suggestedParams,
    from: sender,
    amount: 0,
    to: sender,
    note: new Uint8Array(Buffer.from("Hello World", "utf-8")),
  }),
});

const result = await atc.execute(client, 5)
barnjamin commented 1 year ago

+1 please!