Skip to content

Commit

Permalink
Metamask signing support (#69)
Browse files Browse the repository at this point in the history
* Support for payable contract methods

* Metamask signing support
  • Loading branch information
0xslipk authored Oct 27, 2022
1 parent 333b25f commit ef3f5c1
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 10 deletions.
47 changes: 47 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,21 @@ const key = new HDKey(new WSProvider(HARMONY_RPC_WS), options)
const key = new HDKey(HarmonyShards.SHARD_0, options)
```

## Metamask Provider

Implementation a subclass of HttpProvider that takes window.ethereum as a parameter, each method of HttpProvider is implemented by this subclass by cascading the request appropriately to window.ethereum

```ts
import detectEthereumProvider from '@metamask/detect-provider'
import { MetamaskProvider } from 'harmony-marketplace-sdk'

const provider = await detectEthereumProvider()

// Using a MetamaskProvider with window or a detected provider.
const key = new Key(new MetamaskProvider(window.ethereum || provider))

```

## Base Token

The `BaseToken` is an extension over a regular [Contract](https://github.com/harmony-one/sdk/tree/master/packages/harmony-contract) which is the Harmony recomendation for interact with smart contracts. This abstract class contains the core functionality for interact with Harmony Smart Contracts.
Expand Down Expand Up @@ -1365,6 +1380,38 @@ const { addr, receiptId } = await bridge.sendToken(
)
```

## Development

Install all the dependencies:

```sh
npmn ci
```

Copy the `.env.sample` file to `.env`

```sh
cp .env.sample .env
```

In the project directory, you can run:

### `npm run test`

Running the unit tests.

### `npm run test:cov`

Running the test coverage.

### `npm run test:e2e`

Running the end to end test.

### `npm run test:lint`

Running the lint.

## Change Log

See [Changelog](CHANGELOG.md) for more information.
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export * from './wallets'
export * from './constants'
export * from './interfaces'
export * from './utils'
export * from './providers'
19 changes: 18 additions & 1 deletion src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Arrayish } from '@harmony-js/crypto'
import { HttpProvider, WSProvider } from '@harmony-js/network'
import { ChainID, ChainType } from '@harmony-js/utils'
import BN from 'bn.js'
import { MetamaskProvider } from './providers'
import { Key, MnemonicKey, PrivateKey } from './wallets'

export type BNish = BN | Arrayish | bigint | number
Expand Down Expand Up @@ -34,7 +35,7 @@ export enum HarmonyShards {
SHARD_0_DEVNET = 'SHARD_0_DEVNET',
}

export type RpcProviderType = string | HttpProvider | WSProvider | HarmonyShards
export type RpcProviderType = string | HttpProvider | WSProvider | MetamaskProvider | HarmonyShards

export type ContractProviderType = Wallet | Key | PrivateKey | MnemonicKey

Expand Down Expand Up @@ -92,3 +93,19 @@ export interface BridgeResponse {
export interface ChainId {
[key: number]: string
}

interface ProviderRequestArguments {
readonly method: string
readonly params?: readonly unknown[] | object
}

export interface MetaMaskEthereumProvider {
isMetaMask?: boolean
once(eventName: string | symbol, listener: (...args: any[]) => void): this
on(eventName: string | symbol, listener: (...args: any[]) => void): this
off(eventName: string | symbol, listener: (...args: any[]) => void): this
addListener(eventName: string | symbol, listener: (...args: any[]) => void): this
removeListener(eventName: string | symbol, listener: (...args: any[]) => void): this
removeAllListeners(event?: string | symbol): this
request(args: ProviderRequestArguments): Promise<any>
}
1 change: 1 addition & 0 deletions src/providers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './metamaskProvider'
20 changes: 20 additions & 0 deletions src/providers/metamaskProvider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { HttpProvider, RPCRequestPayload } from '@harmony-js/network'
import { MetaMaskEthereumProvider } from '../interfaces'

export class MetamaskProvider extends HttpProvider {
private readonly provider: MetaMaskEthereumProvider

constructor(provider?: MetaMaskEthereumProvider) {
super('')

if (!provider) {
throw new Error('Invalid MetaMask provider!')
}

this.provider = provider
}

requestFunc({ payload }: { payload: RPCRequestPayload<object> }): Promise<any> {
return this.provider.request({ method: payload.method, params: payload.params })
}
}
10 changes: 1 addition & 9 deletions src/wallets/key.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Wallet } from '@harmony-js/account'
import { Messenger, HttpProvider, WSProvider } from '@harmony-js/network'
import { ChainID, ChainType, isWs } from '@harmony-js/utils'
import { HARMONY_SHARDS, CHAINS_ID } from '../constants'
import { HARMONY_SHARDS } from '../constants'
import { HarmonyRpcConfig, HarmonyShards, RpcProviderType } from '../interfaces'

/**
Expand All @@ -21,14 +21,6 @@ export class Key extends Wallet {
provider = url
} else if (typeof url === 'string') {
provider = isWs(url) ? new WSProvider(url) : new HttpProvider(url)
} else if (url['isMetaMask']) {
const _chain = Number(url['networkVersion'])
const rpc_url = CHAINS_ID[_chain]

if (!rpc_url) throw new Error('Invalid metamask harmony chain.')

provider = new HttpProvider(rpc_url)
chain = _chain
} else {
throw new Error('Invalid url param.')
}
Expand Down

0 comments on commit ef3f5c1

Please sign in to comment.