-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #13 from pontem-network/feature-LS-1150-add-trust-…
…wallet feat(adapter): LS-1150 add trust wallet
- Loading branch information
Showing
3 changed files
with
312 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,310 @@ | ||
import { Types } from 'aptos'; | ||
import { | ||
WalletAccountChangeError, | ||
WalletDisconnectionError, | ||
WalletGetNetworkError, | ||
WalletNetworkChangeError, | ||
WalletNotConnectedError, | ||
WalletNotReadyError, | ||
WalletSignAndSubmitMessageError, | ||
WalletSignMessageError, | ||
WalletSignTransactionError | ||
} from '../WalletProviders/errors'; | ||
import { | ||
AccountKeys, | ||
BaseWalletAdapter, | ||
NetworkInfo, | ||
scopePollingDetectionStrategy, | ||
SignMessagePayload, | ||
SignMessageResponse, | ||
WalletAdapterNetwork, | ||
WalletName, | ||
WalletReadyState | ||
} from './BaseAdapter'; | ||
|
||
interface IApotsErrorResult { | ||
code: number; | ||
name: string; | ||
message: string; | ||
} | ||
|
||
type AddressInfo = { address: string; publicKey: string; authKey?: string }; | ||
|
||
interface IAptosWallet { | ||
connect: () => Promise<AddressInfo>; | ||
account: () => Promise<AddressInfo>; | ||
isConnected: () => Promise<boolean>; | ||
signAndSubmitTransaction( | ||
transaction: any, | ||
options?: any | ||
): Promise<{ hash: Types.HexEncodedBytes } | IApotsErrorResult>; | ||
signTransaction(transaction: any, options?: any): Promise<Uint8Array | IApotsErrorResult>; | ||
signMessage(message: SignMessagePayload): Promise<SignMessageResponse>; | ||
disconnect(): Promise<void>; | ||
network(): Promise<WalletAdapterNetwork>; | ||
requestId: Promise<number>; | ||
onAccountChange: (listener: (newAddress: AddressInfo) => void) => void; | ||
onNetworkChange: (listener: (network: { networkName: string }) => void) => void; | ||
} | ||
|
||
interface AptosWindow extends Window { | ||
aptos?: IAptosWallet | ||
} | ||
|
||
declare const window: AptosWindow; | ||
|
||
export const TrustWalletName = 'Trust' as WalletName<'Trust'>; | ||
|
||
export interface TrustWalletAdapterConfig { | ||
provider?: IAptosWallet; | ||
// network?: WalletAdapterNetwork; | ||
timeout?: number; | ||
} | ||
|
||
export class TrustWalletAdapter extends BaseWalletAdapter { | ||
name = TrustWalletName; | ||
|
||
url = 'https://trustwallet.com/'; | ||
|
||
icon = 'https://trustwallet.com/assets/images/trust_logotype.svg'; | ||
|
||
protected _provider: IAptosWallet | undefined; | ||
|
||
protected _network: WalletAdapterNetwork; | ||
|
||
protected _chainId: string; | ||
|
||
protected _api: string; | ||
|
||
protected _timeout: number; | ||
|
||
protected _readyState: WalletReadyState = | ||
typeof window === 'undefined' || typeof document === 'undefined' | ||
? WalletReadyState.Unsupported | ||
: WalletReadyState.NotDetected; | ||
|
||
protected _connecting: boolean; | ||
|
||
protected _wallet: any | null; | ||
|
||
constructor({ | ||
// provider, | ||
// network = WalletAdapterNetwork.Testnet, | ||
timeout = 10000 | ||
}: TrustWalletAdapterConfig = {}) { | ||
super(); | ||
|
||
this._provider = typeof window !== 'undefined' ? window.aptos : undefined; | ||
this._network = undefined; | ||
this._timeout = timeout; | ||
this._connecting = false; | ||
this._wallet = null; | ||
|
||
if (typeof window !== 'undefined' && this._readyState !== WalletReadyState.Unsupported) { | ||
scopePollingDetectionStrategy(() => { | ||
if (window.aptos) { | ||
this._readyState = WalletReadyState.Installed; | ||
this.emit('readyStateChange', this._readyState); | ||
return true; | ||
} | ||
return false; | ||
}); | ||
} | ||
} | ||
|
||
get publicAccount(): AccountKeys { | ||
return { | ||
publicKey: this._wallet?.publicKey || null, | ||
address: this._wallet?.address || null, | ||
authKey: this._wallet?.authKey || null | ||
}; | ||
} | ||
|
||
get network(): NetworkInfo { | ||
return { | ||
name: this._network, | ||
api: this._api, | ||
chainId: this._chainId | ||
}; | ||
} | ||
|
||
get connecting(): boolean { | ||
return this._connecting; | ||
} | ||
|
||
get connected(): boolean { | ||
return !!this._wallet?.isConnected; | ||
} | ||
|
||
get readyState(): WalletReadyState { | ||
return this._readyState; | ||
} | ||
|
||
async connect(): Promise<void> { | ||
try { | ||
if (this.connected || this.connecting) return; | ||
if ( | ||
!( | ||
this._readyState === WalletReadyState.Loadable || | ||
this._readyState === WalletReadyState.Installed | ||
) | ||
) | ||
throw new WalletNotReadyError(); | ||
this._connecting = true; | ||
|
||
const provider = this._provider || window.aptos; | ||
const response = await provider?.connect(); | ||
this._wallet = { | ||
address: response?.address, | ||
publicKey: response?.publicKey, | ||
isConnected: true | ||
}; | ||
|
||
try { | ||
const name = await provider?.network(); | ||
const chainId = null; | ||
const api = null; | ||
|
||
this._network = name; | ||
this._chainId = chainId; | ||
this._api = api; | ||
} catch (error: any) { | ||
const errMsg = error.message; | ||
this.emit('error', new WalletGetNetworkError(errMsg)); | ||
throw error; | ||
} | ||
|
||
this.emit('connect', this._wallet.address); | ||
} catch (error: any) { | ||
this.emit('error', error); | ||
throw error; | ||
} finally { | ||
this._connecting = false; | ||
} | ||
} | ||
|
||
async disconnect(): Promise<void> { | ||
const wallet = this._wallet; | ||
const provider = this._provider || window.aptos; | ||
if (wallet) { | ||
this._wallet = null; | ||
|
||
try { | ||
await provider?.disconnect(); | ||
} catch (error: any) { | ||
this.emit('error', new WalletDisconnectionError(error?.message, error)); | ||
} | ||
} | ||
|
||
this.emit('disconnect'); | ||
} | ||
|
||
async signTransaction(transaction: Types.TransactionPayload, options?: any): Promise<Uint8Array> { | ||
try { | ||
const wallet = this._wallet; | ||
const provider = this._provider || window.aptos; | ||
if (!wallet || !provider) throw new WalletNotConnectedError(); | ||
|
||
const response = await provider.signTransaction(transaction, options); | ||
if ((response as IApotsErrorResult).code) { | ||
throw new Error((response as IApotsErrorResult).message); | ||
} | ||
return response as Uint8Array; | ||
} catch (error: any) { | ||
const errMsg = error.message; | ||
this.emit('error', new WalletSignTransactionError(errMsg)); | ||
throw error; | ||
} | ||
} | ||
|
||
async signAndSubmitTransaction( | ||
transaction: Types.TransactionPayload, | ||
options?: any | ||
): Promise<{ hash: Types.HexEncodedBytes }> { | ||
try { | ||
const wallet = this._wallet; | ||
const provider = this._provider || window.aptos; | ||
if (!wallet || !provider) throw new WalletNotConnectedError(); | ||
|
||
const response = await provider.signAndSubmitTransaction(transaction, options); | ||
if ((response as IApotsErrorResult).code) { | ||
throw new Error((response as IApotsErrorResult).message); | ||
} | ||
return response as { hash: Types.HexEncodedBytes }; | ||
} catch (error: any) { | ||
const errMsg = error.message; | ||
this.emit('error', new WalletSignAndSubmitMessageError(errMsg)); | ||
throw error; | ||
} | ||
} | ||
|
||
async signMessage(msgPayload: SignMessagePayload): Promise<SignMessageResponse> { | ||
try { | ||
const wallet = this._wallet; | ||
const provider = this._provider || window.aptos; | ||
if (!wallet || !provider) throw new WalletNotConnectedError(); | ||
if (typeof msgPayload !== 'object' || !msgPayload.nonce) { | ||
throw new WalletSignMessageError('Invalid signMessage Payload'); | ||
} | ||
const response = await provider?.signMessage(msgPayload); | ||
if (response) { | ||
return response; | ||
} else { | ||
throw new Error('Sign Message failed'); | ||
} | ||
} catch (error: any) { | ||
const errMsg = error.message; | ||
this.emit('error', new WalletSignMessageError(errMsg)); | ||
throw error; | ||
} | ||
} | ||
|
||
async onAccountChange(): Promise<void> { | ||
try { | ||
const wallet = this._wallet; | ||
const provider = this._provider || window.aptos; | ||
if (!wallet || !provider) throw new WalletNotConnectedError(); | ||
const handleAccountChange = async (newAccount: AddressInfo) => { | ||
if (newAccount?.publicKey) { | ||
this._wallet = { | ||
...this._wallet, | ||
publicKey: newAccount.publicKey || this._wallet?.publicKey, | ||
authKey: newAccount.authKey || this._wallet?.authKey, | ||
address: newAccount.address || this._wallet?.address | ||
}; | ||
} else { | ||
const response = await provider?.connect(); | ||
this._wallet = { | ||
...this._wallet, | ||
authKey: response?.authKey || this._wallet?.authKey, | ||
address: response?.address || this._wallet?.address, | ||
publicKey: response?.publicKey || this._wallet?.publicKey | ||
}; | ||
} | ||
this.emit('accountChange', newAccount.publicKey); | ||
}; | ||
await provider?.onAccountChange(handleAccountChange); | ||
} catch (error: any) { | ||
const errMsg = error.message; | ||
this.emit('error', new WalletAccountChangeError(errMsg)); | ||
throw error; | ||
} | ||
} | ||
|
||
async onNetworkChange(): Promise<void> { | ||
try { | ||
const wallet = this._wallet; | ||
const provider = this._provider || window.aptos; | ||
if (!wallet || !provider) throw new WalletNotConnectedError(); | ||
const handleNetworkChange = async (newNetwork: { networkName: WalletAdapterNetwork }) => { | ||
this._network = newNetwork.networkName; | ||
this.emit('networkChange', this._network); | ||
}; | ||
await provider?.onNetworkChange(handleNetworkChange); | ||
} catch (error: any) { | ||
const errMsg = error.message; | ||
this.emit('error', new WalletNetworkChangeError(errMsg)); | ||
throw error; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters