Skip to content

Commit

Permalink
feat(awgmi): Catch more wallets user reject error (#5242)
Browse files Browse the repository at this point in the history
  • Loading branch information
0xjojoex authored Nov 9, 2022
1 parent 2265307 commit 2763b05
Show file tree
Hide file tree
Showing 12 changed files with 158 additions and 33 deletions.
6 changes: 6 additions & 0 deletions .changeset/pretty-mails-trade.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@pancakeswap/awgmi": patch
---

Catch more wallets user reject error for Petra, Martian, Blocto, Pontem

95 changes: 92 additions & 3 deletions packages/awgmi/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
# @pancakeswap/awgmi

connect to Aptos with similar [wagmi](https://github.com/wagmi-dev/wagmi) React hooks.
Connect to Aptos with similar [wagmi](https://github.com/wagmi-dev/wagmi) React hooks.

Support Aptos Wallet Connectors:
- Petra
- Martian
- Pontem
- Fewcha
- SafePal
- Trust Wallet


```jsx
Expand All @@ -9,12 +17,26 @@ import {
AwgmiConfig,
useConnect,
getDefaultProviders,
defaultChains,
} from '@pancakeswap/awgmi';
import { PetraConnector } from '@pancakeswap/awgmi/connectors/petra'
import { MartianConnector } from '@pancakeswap/awgmi/connectors/martain'
import { SafePalConnector } from '@pancakeswap/awgmi/connectors/safePal'
import { BloctoConnector } from '@pancakeswap/awgmi/connectors/blocto'
import { FewchaConnector } from '@pancakeswap/awgmi/connectors/fewcha'

// import { mainnet, testnet } from '@pancakeswap/awgmi/core'
const chains = defaultChains // mainnet, testnet, devnet

export const client = createClient({
connectors: [new PetraConnector(), new MartianConnector()],
connectors: [
new PetraConnector({ chains }),
new MartianConnector({ chains }),
new PetraConnector({ chains, options: { name: 'Trust Wallet', id: 'trustWallet' } }),
new SafePalConnector({ chains }),
new BloctoConnector({ chains, options: { appId: BLOCTO_APP_ID } }),
new FewchaConnector({ chains }),
],
provider: getDefaultProviders,
autoConnect: true,
});
Expand All @@ -23,8 +45,75 @@ export const client = createClient({
function App() {
return (
<AwgmiConfig client={client}>
<YourApp>
<YourApp />
</AwgmiConfig>
)
}
```


## Connector
```jsx
import { useConnect, useDisconnect } from '@pancakeswap/awgmi'

function ConnectButton() {
const { connect, connectors } = useConnect()

return (
<div>
{connectors.map((connector) => (
<button type="button" key={connector.id} onClick={() => connect({ connector, networkName: 'mainnet' })}>
{connector.name}
</button>
))}
</div>
)
}
```


## Hooks
```jsx
import {
useAccountBalance,
useAccountBalances,
useAccountResource,
useAccountResources,
useCoin,
useCoins,
useNetwork,
useSendTransaction,
useSimulateTransaction,
useTableItem,
} from '@pancakeswap/awgmi'
```

### Balance
```js
const { data } = useAccountBalance({
address: Address,
coin: '0x1::aptos_coin::AptosCoin',
watch: true
})
```

### Send Transaction
```js
import { UserRejectedRequestError } from '@pancakeswap/awgmi'

const { sendTransactionAsync } = useSendTransaction()

sendTransactionAsync({
payload: {
type: 'entry_function_payload',
function: '<address>::message::set_message',
arguments: ['are we gonna make it?'],
type_arguments: [],
},
}).catch(err => {
if (err instanceof UserRejectedRequestError) {
// handle user reject
}
// handle transaction error
})
```
4 changes: 2 additions & 2 deletions packages/awgmi/core/src/accounts/signMessage.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ConnectorNotFoundError, ProviderRpcError, UserRejectedRequestError } from '../errors'
import { ConnectorNotFoundError, WalletProviderError, UserRejectedRequestError } from '../errors'
import { getClient } from '../client'
import { SignMessagePayload, SignMessageResponse } from '../connectors'

Expand All @@ -16,7 +16,7 @@ export async function signMessage(args: SignMessageArgs): Promise<SignMessageRes
if (!activeConnector) throw new ConnectorNotFoundError()
return activeConnector.signMessage(args.message)
} catch (error) {
if ((error as ProviderRpcError).code === 4001) throw new UserRejectedRequestError(error)
if ((error as WalletProviderError).code === 4001) throw new UserRejectedRequestError(error)
throw error
}
}
1 change: 1 addition & 0 deletions packages/awgmi/core/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ export class Client<TProvider extends AptosClient = AptosClient> {
clearState() {
this.setState((x) => ({
...x,
chains: undefined,
connector: undefined,
data: undefined,
error: undefined,
Expand Down
18 changes: 16 additions & 2 deletions packages/awgmi/core/src/connectors/blocto.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import type { AptosProviderInterface, AptosProviderConfig } from '@blocto/sdk'
import { Types } from 'aptos'
import { Chain } from '../chain'
import { ChainNotConfiguredError, ConnectorNotFoundError, ConnectorUnauthorizedError } from '../errors'
import {
ChainNotConfiguredError,
ConnectorNotFoundError,
ConnectorUnauthorizedError,
UserRejectedRequestError,
} from '../errors'
import { Address } from '../types'
import { Connector, ConnectorData, ConnectorTransactionResponse } from './base'
import { Account, SignMessagePayload, SignMessageResponse } from './types'
Expand Down Expand Up @@ -87,7 +92,16 @@ export class BloctoConnector extends Connector<AptosProviderInterface, Partial<A
async signAndSubmitTransaction(transaction?: Types.TransactionPayload): Promise<ConnectorTransactionResponse> {
const provider = await this.getProvider()
if (!provider) throw new ConnectorNotFoundError()
return provider.signAndSubmitTransaction(transaction)
try {
const response = await provider.signAndSubmitTransaction(transaction)
return response
} catch (error) {
if ((error as any)?.message === 'User declined to send the transaction') {
throw new UserRejectedRequestError(error)
} else {
throw error
}
}
}

async signTransaction(transaction?: Types.TransactionPayload): Promise<Uint8Array> {
Expand Down
13 changes: 10 additions & 3 deletions packages/awgmi/core/src/connectors/martian.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Types } from 'aptos'
import { Chain } from '../chain'
import { Connector } from './base'
import { ConnectorNotFoundError } from '../errors'
import { ConnectorNotFoundError, UserRejectedRequestError } from '../errors'
import { Address } from '../types'
import { SignMessagePayload, SignMessageResponse } from './types'

Expand Down Expand Up @@ -110,9 +110,16 @@ export class MartianConnector extends Connector<Window['martian'], MartianConnec

if (!transaction) throw new Error('Failed to generate transaction')

const hash = await provider.signAndSubmitTransaction(transaction)
try {
const hash = await provider.signAndSubmitTransaction(transaction)

return { hash }
return { hash }
} catch (error) {
if (error === 'User Rejected the request') {
throw new UserRejectedRequestError(error)
}
throw error
}
}

async signTransaction(payload: Types.TransactionPayload) {
Expand Down
13 changes: 10 additions & 3 deletions packages/awgmi/core/src/connectors/pontem.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Types } from 'aptos'
import { Chain } from '../chain'
import { ConnectorNotFoundError } from '../errors'
import { ConnectorNotFoundError, UserRejectedRequestError } from '../errors'
import { Address } from '../types'
import { Connector } from './base'
import { SignMessagePayload, SignMessageResponse } from './types'
Expand Down Expand Up @@ -119,12 +119,19 @@ export class PontemConnector extends Connector<Window['pontem']> {
const provider = await this.getProvider()
if (!provider) throw new ConnectorNotFoundError()

const response = await provider.signAndSubmit(payload)
let response

try {
response = await provider.signAndSubmit(payload)
} catch (error) {
if ((error as any)?.code === 1002) {
throw new UserRejectedRequestError(error)
}
}
if (!response || !response.success) {
// TODO: unify WalletProviderError
throw new Error('sign and submit failed')
}

return response.result
}

Expand Down
4 changes: 2 additions & 2 deletions packages/awgmi/core/src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export class RpcError<T = undefined> extends Error {
* Error subclass implementing Ethereum Provider errors per EIP-1193.
* @see https://eips.ethereum.org/EIPS/eip-1193
*/
export class ProviderRpcError<T = undefined> extends RpcError<T> {
export class WalletProviderError<T = undefined> extends RpcError<T> {
/**
* https://petra.app/docs/errors
*/
Expand All @@ -97,7 +97,7 @@ export class ProviderRpcError<T = undefined> extends RpcError<T> {
}
}

export class UserRejectedRequestError extends ProviderRpcError {
export class UserRejectedRequestError extends WalletProviderError {
name = 'UserRejectedRequestError'

constructor(error: unknown) {
Expand Down
4 changes: 2 additions & 2 deletions packages/awgmi/core/src/transactions/sendTransaction.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { equalsIgnoreCase } from '@pancakeswap/utils/equalsIgnoreCase'
import { Types } from 'aptos'
import { getAccount } from '../accounts/account'
import { ChainMismatchError, ConnectorNotFoundError, ProviderRpcError, UserRejectedRequestError } from '../errors'
import { ChainMismatchError, ConnectorNotFoundError, WalletProviderError, UserRejectedRequestError } from '../errors'
import { getNetwork } from '../network/network'
import { getProvider } from '../providers'
import { TransactionResponse } from './types'
Expand Down Expand Up @@ -46,7 +46,7 @@ export async function sendTransaction({
}
return response
} catch (error) {
if ((<ProviderRpcError>error).code === 4001) throw new UserRejectedRequestError(error)
if ((<WalletProviderError>error).code === 4001) throw new UserRejectedRequestError(error)
throw error
}
}
6 changes: 3 additions & 3 deletions packages/awgmi/core/src/transactions/simulateTransaction.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { HexString, TxnBuilderTypes, Types } from 'aptos'
import { getAccount } from '../accounts/account'
import { getClient } from '../client'
import { ProviderRpcError, SimulateTransactionError } from '../errors'
import { WalletProviderError, SimulateTransactionError } from '../errors'
import { getProvider } from '../providers'

export type SimulateTransactionArgs = {
Expand All @@ -23,7 +23,7 @@ export async function simulateTransaction({
const { account } = getAccount()
const provider = getProvider({ networkName })

if (!account) throw new ProviderRpcError(4100, 'No Account')
if (!account) throw new WalletProviderError(4100, 'No Account')

let { publicKey } = account

Expand All @@ -34,7 +34,7 @@ export async function simulateTransaction({
publicKey = accountFromActiveConnector?.publicKey
}

if (!publicKey) throw new ProviderRpcError(4100, 'Missing pubic key')
if (!publicKey) throw new WalletProviderError(4100, 'Missing pubic key')

if (Array.isArray(publicKey)) {
throw new Error('Multi sig not supported')
Expand Down
6 changes: 6 additions & 0 deletions packages/awgmi/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"name": "@pancakeswap/awgmi",
"license": "MIT",
"version": "0.0.9",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
Expand All @@ -14,6 +15,11 @@
"use-sync-external-store": "^1.2.0",
"zustand": "^4.1.1"
},
"keywords": [
"pancakeswap",
"aptos",
"wallets"
],
"peerDependencies": {
"@blocto/sdk": "^0.3.1",
"aptos": "^1.3.16",
Expand Down
21 changes: 8 additions & 13 deletions packages/awgmi/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {
export {
defaultChain,
defaultChains,
APTOS_COIN,
Expand All @@ -9,20 +9,15 @@ import {
parseVmStatusError,
isStructTag,
getDefaultProviders,
UserRejectedRequestError,
SimulateTransactionError,
ConnectorNotFoundError,
ChainMismatchError,
ChainNotConfiguredError,
ConnectorUnauthorizedError,
ConnectorAlreadyConnectedError,
} from '@pancakeswap/awgmi/core'

export {
defaultChain,
defaultChains,
APTOS_COIN,
isHexStringEquals,
isAccountAddress,
isPendingTransaction,
isUserTransaction,
parseVmStatusError,
isStructTag,
getDefaultProviders,
}
export * from './client'
export * from './context'
export * from './hooks/useAccount'
Expand Down

0 comments on commit 2763b05

Please sign in to comment.