Skip to content

Commit

Permalink
fix(walletconnect): handle all possible response types from algo_sign…
Browse files Browse the repository at this point in the history
…Txn (#185)

There are no restrictions or rules about the `algo_signTxn` RPC method response type. Each wallet can decide on its own how to format the signed transactions it returns.

(This should probably be spec'd or defined somewhere!)

The WalletConnect provider now handles numerous potential response types, to make sure it always returns an array of encoded signed transactions as `Promise<Uint8Array[]>`.

Its signing function response is now typed as

```ts
type SignTxnsResponse = Array<Uint8Array | string | null | undefined>
```
  • Loading branch information
drichar authored Jun 13, 2024
1 parent 4f2330a commit 1e246e1
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 4 deletions.
18 changes: 18 additions & 0 deletions packages/use-wallet/src/__tests__/wallets/walletconnect.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,24 @@ describe('WalletConnect', () => {
])
)
})

it('should return encoded signed transactions if the wallet returns base64 strings', async () => {
const signedTxn = byteArrayToBase64(txn1.toByte())
mockSignClient.request.mockResolvedValueOnce([signedTxn])

const result = await wallet.signTransactions([txn1])

expect(result).toEqual([txn1.toByte()])
})

it('should return encoded signed transactions if the wallet returns Uint8Arrays', async () => {
const signedTxn = txn1.toByte()
mockSignClient.request.mockResolvedValueOnce([signedTxn])

const result = await wallet.signTransactions([txn1])

expect(result).toEqual([txn1.toByte()])
})
})

describe('transactionSigner', () => {
Expand Down
10 changes: 6 additions & 4 deletions packages/use-wallet/src/wallets/walletconnect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ type WalletConnectModalOptions = Pick<

export type WalletConnectOptions = SignClientOptions & WalletConnectModalOptions

export type SignTxnsResponse = Array<Uint8Array | string | null | undefined>

export class SessionError extends Error {
constructor(message: string) {
super(message)
Expand Down Expand Up @@ -352,16 +354,16 @@ export class WalletConnect extends BaseWallet {
const request = formatJsonRpcRequest('algo_signTxn', [txnsToSign])

// Sign transactions
const signTxnsResult = await client.request<Array<string | null>>({
const signTxnsResult = await client.request<SignTxnsResponse>({
chainId: caipChainId[this.activeNetwork]!,
topic: this.session.topic,
request
})

// Filter out null values
// Filter out nullish values
const signedTxns = signTxnsResult.reduce<Uint8Array[]>((acc, value) => {
if (value !== null) {
const signedTxn = base64ToByteArray(value)
if (value) {
const signedTxn = typeof value === 'string' ? base64ToByteArray(value) : value
acc.push(signedTxn)
}
return acc
Expand Down

0 comments on commit 1e246e1

Please sign in to comment.