@portal-hq/provider 0.2.0-beta10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,114 @@
1
+ import { NativeModules } from 'react-native'
2
+ import { KeychainAdapter, MpcSigningError } from '@portal-hq/utils'
3
+
4
+ import { Provider } from '../index'
5
+ import Signer from './abstract'
6
+
7
+ import {
8
+ type MpcSignerOptions,
9
+ type PortalMobileMpc,
10
+ type SigningRequestArguments,
11
+ type SigningResponse,
12
+ } from '../../types'
13
+
14
+ class MpcSigner implements Signer {
15
+ public _address: string
16
+ private keychain: KeychainAdapter
17
+ private mpc: PortalMobileMpc
18
+ private mpcUrl: string
19
+
20
+ constructor(opts: MpcSignerOptions) {
21
+ this.keychain = opts.keychain
22
+ this.mpc = NativeModules.PortalMobileMpc
23
+ this.mpcUrl = opts.mpcUrl
24
+
25
+ if (!this.mpc) {
26
+ throw new Error(
27
+ `[Portal.Provider.MpcSigner] The MPC module could not be found by the signer. This is usually an issue with React Native linking. Please verify that the 'PortalReactNative' module is properly linked to this project.`,
28
+ )
29
+ }
30
+ }
31
+
32
+ public get address() {
33
+ return (async () => {
34
+ if (this._address) {
35
+ return this._address
36
+ }
37
+
38
+ const address = await this.keychain.getAddress()
39
+
40
+ this._address = address
41
+
42
+ return address
43
+ })()
44
+ }
45
+
46
+ public async sign(
47
+ message: SigningRequestArguments,
48
+ provider: Provider,
49
+ ): Promise<any> {
50
+ const address = await this.keychain.getAddress()
51
+ const apiKey = provider.apiKey
52
+
53
+ const { method, params } = message
54
+
55
+ switch (method) {
56
+ case 'eth_requestAccounts':
57
+ return [address]
58
+ case 'eth_accounts':
59
+ return [address]
60
+ default:
61
+ break
62
+ }
63
+
64
+ console.log(
65
+ `[Portal:MpcSigner] Requesting signature from PortalMobileMpc for:`,
66
+ JSON.stringify(message, null, 2),
67
+ )
68
+
69
+ const dkg = await this.keychain.getDkgResult()
70
+
71
+ console.log(`[PortalMpcSigner] RPC URL: ${provider.rpcUrl}`)
72
+
73
+ const result = await this.mpc.sign(
74
+ apiKey,
75
+ this.mpcUrl,
76
+ dkg,
77
+ message.method,
78
+ JSON.stringify(this.buildParams(method, params)),
79
+ provider.rpcUrl,
80
+ provider.chainId.toString(),
81
+ )
82
+
83
+ console.log(`[PortalMpcSigner] Result: `, result)
84
+
85
+ const { data, error } = JSON.parse(String(result)) as SigningResponse
86
+
87
+ if (error && error.length) {
88
+ throw new MpcSigningError(error as string)
89
+ }
90
+
91
+ return data
92
+ }
93
+
94
+ private buildParams = (method: string, txParams: any) => {
95
+ let params = txParams
96
+
97
+ switch (method) {
98
+ case 'eth_sign':
99
+ case 'personal_sign':
100
+ if (!Array.isArray(txParams)) {
101
+ params = [txParams]
102
+ }
103
+ break
104
+ default:
105
+ if (Array.isArray(txParams)) {
106
+ params = txParams[0]
107
+ }
108
+ }
109
+
110
+ return params
111
+ }
112
+ }
113
+
114
+ export default MpcSigner
package/types.d.ts ADDED
@@ -0,0 +1,98 @@
1
+ // Types
2
+
3
+ import { KeychainAdapter } from '@portal-hq/utils'
4
+
5
+ export type EventHandler = (data: any) => void
6
+
7
+ export type GatewayLike = GatewayConfig | string
8
+
9
+ export type ValidHttpRequestMethods = 'DELETE' | 'GET' | 'POST' | 'PUT'
10
+
11
+ // Interfaces
12
+
13
+ export interface GatewayConfig {
14
+ [key: number]: string
15
+ }
16
+
17
+ export interface HttpRequesterOptions {
18
+ baseUrl: string
19
+ }
20
+
21
+ export interface HttpSignerOptions extends SignerOptions {
22
+ portal: HttpRequester
23
+ }
24
+
25
+ export interface MpcSignerOptions extends SignerOptions {
26
+ keychain: KeychainAdapter
27
+ mpcUrl: string
28
+ }
29
+
30
+ export interface PortalMobileMpc {
31
+ generate: (clientApiKey: string, mpcApiUrl: string) => Promise<string>
32
+ rotate: (
33
+ clientApiKey: string,
34
+ mpcApiUrl: string,
35
+ isSim: boolean,
36
+ dkgResult?: string,
37
+ ) => Promise<string>
38
+ sign: (
39
+ clientApiKey: string,
40
+ mpcApiUrl: string,
41
+ dkgResult: string,
42
+ message: string,
43
+ requestId: string,
44
+ mpcUrl: string,
45
+ chainId: string,
46
+ ) => Promise<string>
47
+ }
48
+
49
+ export interface ProviderOptions {
50
+ // Required options
51
+ apiKey: string
52
+ chainId: number
53
+ keychain: KeychainAdapter
54
+ gatewayConfig: GatewayLike
55
+
56
+ // Optional options
57
+ apiUrl?: string
58
+ autoApprove?: boolean
59
+ enableMpc?: boolean
60
+ mpcUrl?: string
61
+ }
62
+
63
+ export interface RegisteredEventHandler {
64
+ handler: EventHandler
65
+ once?: boolean
66
+ }
67
+
68
+ export interface RequestArguments {
69
+ method: string
70
+ params?: unknown[] | SigningRequestParams
71
+ }
72
+
73
+ export interface SignResult {
74
+ R: string
75
+ S: string
76
+ }
77
+
78
+ export interface SignerOptions {}
79
+
80
+ export interface SigningRequestArguments {
81
+ readonly chainId?: number
82
+ readonly method: string
83
+ readonly params?: unknown[] | SigningRequestParams
84
+ readonly requestId?: string
85
+ }
86
+
87
+ export interface SigningRequestParams {
88
+ gas?: string
89
+ }
90
+
91
+ export interface SigningResponse {
92
+ data: string
93
+ error?: string
94
+ }
95
+
96
+ export interface SwitchEthereumChainParameter {
97
+ chainId: string
98
+ }