Skip to content

Commit

Permalink
Merge pull request #26 from getsumer/mmo/feat-wallet-observer
Browse files Browse the repository at this point in the history
Mmo/feat wallet observer
  • Loading branch information
cito-lito authored Jun 20, 2023
2 parents 99cf25e + e618b02 commit 86854c2
Show file tree
Hide file tree
Showing 21 changed files with 170 additions and 490 deletions.
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 13 additions & 7 deletions src/Sumer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Fragment, JsonFragment } from '@ethersproject/abi'
import { NotifyService, NotifyFactory } from './services'
import { SumerContract } from './SumerContract'
import { SumerTarget } from './SumerTarget'
import { Observer, ErrorObserver, TransactionObserver } from './observers'
import { Observer, TransactionObserver } from './observers'

declare global {
interface Window {
Expand Down Expand Up @@ -47,11 +47,7 @@ export class Sumer {
standalone = true,
}: SumerInitArguments): void {
this.notifyService = NotifyFactory.create(dappKey, dns)
this.sumerObservers = [
...observers,
new ErrorObserver(this.notifyService),
new TransactionObserver(this.notifyService),
]
this.sumerObservers = [...observers, new TransactionObserver(this.notifyService)]
this._dappKey = dappKey
this._dns = dns
this.initializeWindow(standalone)
Expand Down Expand Up @@ -92,8 +88,18 @@ export class Sumer {
private static initializeWindow(standalone?: boolean) {
if (typeof window !== 'undefined' && !this.isInitialized) {
const sumerTarget = new SumerTarget(this.sumerObservers)

if (window.ethereum && standalone) {
window.ethereum = sumerTarget.proxy(window.ethereum)
const desc = Object.getOwnPropertyDescriptor(window, 'ethereum')
const isReadOnly = desc && !desc.writable

if (!isReadOnly) {
window.ethereum = sumerTarget.proxy(window.ethereum)
} else {
console.warn(
'Unable to initialize in standalone mode as window.ethereum is set as readonly.',
)
}
}
}
}
Expand Down
15 changes: 1 addition & 14 deletions src/SumerContract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { Contract, Signer } from 'ethers'
import { Fragment, JsonFragment } from '@ethersproject/abi'
import { Provider } from '@ethersproject/providers'
import { NotifyService } from './services'
import { ContractError } from './models'

interface SumerContractArguments {
addressOrName: string
Expand Down Expand Up @@ -47,19 +46,7 @@ export class SumerContract {
})
return result
} catch (err) {
let signerOrProviderAddress: string
if (Signer.isSigner(signerOrProvider)) {
signerOrProviderAddress = await signerOrProvider.getAddress()
}
const contracError = new ContractError({
contractAddress: addressOrName,
signerOrProviderAddress,
name: prop,
args,
reason: err.reason,
})

notifyService.trackError(contracError)
console.info('trackError log: ', err)
throw err
}
}
Expand Down
14 changes: 14 additions & 0 deletions src/SumerTarget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,20 @@ export class SumerTarget implements Target {
if (prop === Symbol.iterator) {
return target[Symbol.iterator].bind(target)
}

// coinbase wallet installed
if (target.selectedProvider && target.selectedProvider[prop]) {
target = target.selectedProvider
}

// brave wallet installed
if (target.isBraveWallet && typeof target.isBraveWallet === 'boolean') {
const _target = target[prop]
if (!(typeof _target === 'function' && prop === 'request')) {
return _target
}
}

const method = target[prop]
const methodType = typeof method
switch (methodType) {
Expand Down
34 changes: 0 additions & 34 deletions src/models/ContractError.ts

This file was deleted.

37 changes: 0 additions & 37 deletions src/models/ProviderError.ts

This file was deleted.

17 changes: 14 additions & 3 deletions src/models/Transaction.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { Parser } from 'bowser'

export interface Transaction {
hash: string
hash?: string

to?: string
from?: string
toAddress?: string
fromAddress?: string
functionName?: string
args?: any[]
gas?: string

// Transaction Response
nonce?: number
Expand All @@ -25,4 +28,12 @@ export interface Transaction {
effectiveGasPrice?: string
cumulativeGasUsed?: string
status?: number

// Error
error?: {
code: number
message: string
}

metadata?: Parser.ParsedResult | Record<string, string>
}
6 changes: 5 additions & 1 deletion src/models/eip/1193.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
// https://eips.ethereum.org/EIPS/eip-1193
import { EipError } from '../ProviderError'
export interface EipError {
statusCode: number
name: string
description: string
}

export const ProviderErrorsEip1193: EipError[] = [
{
Expand Down
3 changes: 2 additions & 1 deletion src/models/eip/1474.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// https://eips.ethereum.org/EIPS/eip-1474
import { EipError } from '../ProviderError'

import { EipError } from './1193'

export const RPCErrorsEip1474: EipError[] = [
{ statusCode: -32700, name: 'Parse error', description: 'Invalid JSON' },
Expand Down
2 changes: 0 additions & 2 deletions src/models/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
export * from './ContractError'
export * from './ProviderError'
export * from './Transaction'
52 changes: 0 additions & 52 deletions src/observers/ErrorObserver.ts

This file was deleted.

45 changes: 44 additions & 1 deletion src/observers/SumerObserver.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,55 @@
import { Target } from './Target'
import { Target, TargetExecution } from './Target'
import { Observer } from './Observer'
import { NotifyService } from '../services'
import bowser, { Parser } from 'bowser'

enum Wallet {
BRAVEWALLET = 'isBraveWallet',
COINBASE = 'isCoinbaseWallet',
METAMASK = 'isMetaMask',
}
export abstract class SumerObserver implements Observer {
private readonly NULL_ADDRESS = '0x0000000000000000000000000000000000000000'
protected readonly notifyService: NotifyService

constructor(notifyService: NotifyService) {
this.notifyService = notifyService
}

public abstract inspect(_target: Target): Promise<void>

protected getWallet(_executionTarget: Record<string, string | object>): string | undefined {
const wallets = {
[Wallet.COINBASE]: { addressKey: '_addresses', nameKey: 'Coinbase' },
[Wallet.BRAVEWALLET]: { addressKey: 'selectedAddress', nameKey: 'Brave' },
[Wallet.METAMASK]: { addressKey: 'selectedAddress', nameKey: 'Metamask' },
}

for (const [walletKey, { addressKey, nameKey }] of Object.entries(wallets)) {
if (
_executionTarget?.[walletKey] &&
typeof _executionTarget[walletKey] === 'boolean' &&
_executionTarget[addressKey]
) {
return nameKey
}
}
return undefined
}
protected meta(): Parser.ParsedResult | Record<string, string> {
if (window?.navigator?.userAgent) {
return bowser.parse(window.navigator.userAgent)
}
return {}
}

protected getAddress(execution: TargetExecution): string {
if (execution.target.selectedAddress) {
return execution.target.selectedAddress.toString()
}
if (execution.target._addresses && execution.target._addresses[0]) {
return execution.target._addresses[0].toString()
}
return this.NULL_ADDRESS
}
}
Loading

0 comments on commit 86854c2

Please sign in to comment.