@portal-hq/provider 3.0.6 → 4.0.1
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.
- package/lib/commonjs/providers/index.js +116 -62
- package/lib/commonjs/signers/mpc.js +39 -16
- package/lib/esm/providers/index.js +117 -63
- package/lib/esm/signers/mpc.js +39 -16
- package/package.json +4 -4
- package/src/providers/index.ts +129 -71
- package/src/signers/mpc.ts +53 -24
- package/types.d.ts +6 -3
package/src/providers/index.ts
CHANGED
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
import PortalConnect from '@portal-hq/connect'
|
|
2
|
+
import { PortalCurve } from '@portal-hq/core'
|
|
2
3
|
import {
|
|
3
4
|
Events,
|
|
4
5
|
HttpRequester,
|
|
5
6
|
IPortalProvider,
|
|
6
7
|
InvalidApiKeyError,
|
|
7
|
-
InvalidChainIdError,
|
|
8
8
|
InvalidGatewayConfigError,
|
|
9
9
|
KeychainAdapter,
|
|
10
|
+
PortalRequests,
|
|
10
11
|
ProviderRpcError,
|
|
11
12
|
type RequestArguments,
|
|
12
13
|
RpcErrorCodes,
|
|
13
14
|
} from '@portal-hq/utils'
|
|
14
|
-
import { RpcErrorOptions } from '@portal-hq/utils/types'
|
|
15
|
+
import { AddressesByNamespace, RpcErrorOptions } from '@portal-hq/utils/types'
|
|
15
16
|
|
|
16
17
|
import {
|
|
17
18
|
type EventHandler,
|
|
18
19
|
type GatewayLike,
|
|
19
20
|
type ProviderOptions,
|
|
20
21
|
type RegisteredEventHandler,
|
|
21
|
-
|
|
22
|
+
SwitchEthereumChainParameter,
|
|
22
23
|
} from '../../types'
|
|
23
24
|
import { MpcSigner, Signer } from '../signers'
|
|
24
25
|
|
|
@@ -38,52 +39,52 @@ const signerMethods = [
|
|
|
38
39
|
'eth_signTypedData_v3',
|
|
39
40
|
'eth_signTypedData_v4',
|
|
40
41
|
'personal_sign',
|
|
42
|
+
'sol_signAndConfirmTransaction',
|
|
43
|
+
'sol_signAndSendTransaction',
|
|
44
|
+
'sol_signMessage',
|
|
45
|
+
'sol_signTransaction',
|
|
46
|
+
'raw_sign',
|
|
41
47
|
]
|
|
42
48
|
|
|
43
49
|
class Provider implements IPortalProvider {
|
|
44
50
|
public apiKey: string
|
|
45
51
|
public autoApprove: boolean
|
|
46
|
-
public chainId
|
|
52
|
+
public chainId?: string
|
|
47
53
|
public log: Console
|
|
48
|
-
public gateway:
|
|
54
|
+
public gateway: PortalRequests
|
|
49
55
|
|
|
50
56
|
private events: Record<string, RegisteredEventHandler[]>
|
|
51
57
|
private gatewayConfig: GatewayLike
|
|
52
|
-
private isSimulator: boolean
|
|
53
58
|
private keychain: KeychainAdapter
|
|
54
59
|
private readonly portalApi: HttpRequester
|
|
55
60
|
private signer: Signer
|
|
56
61
|
|
|
57
|
-
public get
|
|
58
|
-
return this.keychain.
|
|
62
|
+
public get addresses(): Promise<AddressesByNamespace | undefined> {
|
|
63
|
+
return this.keychain.getAddresses()
|
|
59
64
|
}
|
|
60
65
|
|
|
61
|
-
public get
|
|
62
|
-
return this.
|
|
66
|
+
public get address(): Promise<string | undefined> {
|
|
67
|
+
return this.keychain.getAddress()
|
|
63
68
|
}
|
|
64
69
|
|
|
65
70
|
constructor({
|
|
66
71
|
// Required
|
|
67
72
|
apiKey,
|
|
68
|
-
chainId,
|
|
69
73
|
keychain,
|
|
70
74
|
gatewayConfig,
|
|
71
75
|
|
|
72
76
|
// Optional
|
|
73
|
-
isSimulator = false,
|
|
74
77
|
autoApprove = false,
|
|
75
78
|
apiHost = 'api.portalhq.io',
|
|
76
79
|
mpcHost = 'mpc.portalhq.io',
|
|
77
80
|
version = 'v6',
|
|
78
|
-
|
|
81
|
+
chainId = 'eip155:11155111',
|
|
82
|
+
featureFlags = {},
|
|
79
83
|
}: ProviderOptions) {
|
|
80
84
|
// Handle required fields
|
|
81
85
|
if (!apiKey || apiKey.length === 0) {
|
|
82
86
|
throw new InvalidApiKeyError()
|
|
83
87
|
}
|
|
84
|
-
if (!chainId) {
|
|
85
|
-
throw new InvalidChainIdError()
|
|
86
|
-
}
|
|
87
88
|
if (!gatewayConfig) {
|
|
88
89
|
throw new InvalidGatewayConfigError()
|
|
89
90
|
}
|
|
@@ -94,7 +95,6 @@ class Provider implements IPortalProvider {
|
|
|
94
95
|
this.chainId = chainId
|
|
95
96
|
this.events = {}
|
|
96
97
|
this.gatewayConfig = gatewayConfig
|
|
97
|
-
this.isSimulator = isSimulator
|
|
98
98
|
this.keychain = keychain
|
|
99
99
|
|
|
100
100
|
// Add a logger
|
|
@@ -108,9 +108,7 @@ class Provider implements IPortalProvider {
|
|
|
108
108
|
})
|
|
109
109
|
|
|
110
110
|
// Initialize Gateway HttpRequester
|
|
111
|
-
this.gateway = new
|
|
112
|
-
baseUrl: this.getGatewayUrl(),
|
|
113
|
-
})
|
|
111
|
+
this.gateway = new PortalRequests()
|
|
114
112
|
|
|
115
113
|
// Initialize an MpcSigner
|
|
116
114
|
this.signer = new MpcSigner({
|
|
@@ -149,23 +147,27 @@ class Provider implements IPortalProvider {
|
|
|
149
147
|
*
|
|
150
148
|
* @returns string
|
|
151
149
|
*/
|
|
152
|
-
public getGatewayUrl(): string {
|
|
150
|
+
public getGatewayUrl(chainId?: string): string {
|
|
151
|
+
chainId = chainId ?? this.chainId
|
|
152
|
+
if (!chainId) {
|
|
153
|
+
throw new Error('[PortalProvider] No chainId provided')
|
|
154
|
+
}
|
|
153
155
|
if (typeof this.gatewayConfig === 'string') {
|
|
154
156
|
// If the gatewayConfig is just a static URL, return that
|
|
155
157
|
return this.gatewayConfig
|
|
156
158
|
} else if (
|
|
157
159
|
typeof this.gatewayConfig === 'object' &&
|
|
158
160
|
// eslint-disable-next-line no-prototype-builtins
|
|
159
|
-
!this.gatewayConfig.hasOwnProperty(
|
|
161
|
+
!this.gatewayConfig.hasOwnProperty(chainId)
|
|
160
162
|
) {
|
|
161
163
|
// If there's no explicit mapping for the current chainId, error out
|
|
162
164
|
throw new Error(
|
|
163
|
-
`[PortalProvider] No RPC endpoint configured for chainId: ${
|
|
165
|
+
`[PortalProvider] No RPC endpoint configured for chainId: ${chainId}`,
|
|
164
166
|
)
|
|
165
167
|
}
|
|
166
168
|
|
|
167
169
|
// Get the entry for the current chainId from the gatewayConfig
|
|
168
|
-
const config = this.gatewayConfig[
|
|
170
|
+
const config = this.gatewayConfig[chainId]
|
|
169
171
|
|
|
170
172
|
if (typeof config === 'string') {
|
|
171
173
|
return config
|
|
@@ -173,7 +175,7 @@ class Provider implements IPortalProvider {
|
|
|
173
175
|
|
|
174
176
|
// If we got this far, there's no way to support the chain with the current config
|
|
175
177
|
throw new Error(
|
|
176
|
-
`[PortalProvider] Could not find a valid gatewayConfig entry for chainId: ${
|
|
178
|
+
`[PortalProvider] Could not find a valid gatewayConfig entry for chainId: ${chainId}`,
|
|
177
179
|
)
|
|
178
180
|
}
|
|
179
181
|
|
|
@@ -259,8 +261,18 @@ class Provider implements IPortalProvider {
|
|
|
259
261
|
chainId,
|
|
260
262
|
connect,
|
|
261
263
|
}: RequestArguments): Promise<any> {
|
|
264
|
+
chainId = chainId ?? this.chainId
|
|
265
|
+
if (!chainId) {
|
|
266
|
+
throw new Error('[PortalProvider] No chainId provided')
|
|
267
|
+
}
|
|
262
268
|
if (method === 'eth_chainId') {
|
|
263
|
-
|
|
269
|
+
if (typeof chainId === 'string' && chainId.includes(':')) {
|
|
270
|
+
return chainId.split(':')[1]
|
|
271
|
+
} else {
|
|
272
|
+
throw new Error(
|
|
273
|
+
"[PortalProvider] Invalid chainId format. Must be 'namespace:reference'",
|
|
274
|
+
)
|
|
275
|
+
}
|
|
264
276
|
}
|
|
265
277
|
|
|
266
278
|
// Handle changing chains
|
|
@@ -268,7 +280,7 @@ class Provider implements IPortalProvider {
|
|
|
268
280
|
const param = (params as any[])[0]
|
|
269
281
|
const chainId = parseInt(param.chainId as string, 16)
|
|
270
282
|
|
|
271
|
-
this.chainId = chainId
|
|
283
|
+
this.chainId = `eip155:${String(chainId)}`
|
|
272
284
|
|
|
273
285
|
this.emit('portal_signatureReceived', {
|
|
274
286
|
method,
|
|
@@ -282,7 +294,11 @@ class Provider implements IPortalProvider {
|
|
|
282
294
|
let result: any
|
|
283
295
|
if (!isSignerMethod && !method.startsWith('wallet_')) {
|
|
284
296
|
// Send to Gateway for RPC calls
|
|
285
|
-
const response = await this.handleGatewayRequests({
|
|
297
|
+
const response = await this.handleGatewayRequests({
|
|
298
|
+
method,
|
|
299
|
+
params,
|
|
300
|
+
chainId,
|
|
301
|
+
})
|
|
286
302
|
|
|
287
303
|
this.emit('portal_signatureReceived', {
|
|
288
304
|
method,
|
|
@@ -304,6 +320,24 @@ class Provider implements IPortalProvider {
|
|
|
304
320
|
connect,
|
|
305
321
|
})
|
|
306
322
|
|
|
323
|
+
if (transactionHash) {
|
|
324
|
+
try {
|
|
325
|
+
await this.portalApi.post('/api/v1/analytics/track', {
|
|
326
|
+
headers: {
|
|
327
|
+
Authentication: `Bearer ${this.apiKey}`,
|
|
328
|
+
},
|
|
329
|
+
body: {
|
|
330
|
+
event: Events.TransactionSigned,
|
|
331
|
+
properties: {
|
|
332
|
+
method,
|
|
333
|
+
},
|
|
334
|
+
},
|
|
335
|
+
})
|
|
336
|
+
} catch (error) {
|
|
337
|
+
// Do nothing, because we don't want metrics gathering
|
|
338
|
+
// to block the SDK
|
|
339
|
+
}
|
|
340
|
+
}
|
|
307
341
|
if (transactionHash) {
|
|
308
342
|
this.emit('portal_signatureReceived', {
|
|
309
343
|
method,
|
|
@@ -326,7 +360,6 @@ class Provider implements IPortalProvider {
|
|
|
326
360
|
|
|
327
361
|
return result
|
|
328
362
|
}
|
|
329
|
-
|
|
330
363
|
/**
|
|
331
364
|
* Updates the chainId of this instance and builds a new RPC HttpRequester for
|
|
332
365
|
* the gateway used for the new chain
|
|
@@ -335,29 +368,35 @@ class Provider implements IPortalProvider {
|
|
|
335
368
|
* @returns BaseProvider
|
|
336
369
|
*/
|
|
337
370
|
public async setChainId(
|
|
338
|
-
chainId: number,
|
|
371
|
+
chainId: string | number,
|
|
339
372
|
connect?: PortalConnect,
|
|
340
|
-
): Promise<
|
|
373
|
+
): Promise<IPortalProvider> {
|
|
374
|
+
if (typeof chainId === 'number') {
|
|
375
|
+
chainId = `eip155:${String(chainId)}`
|
|
376
|
+
}
|
|
341
377
|
// Update the chainId
|
|
342
378
|
this.chainId = chainId
|
|
379
|
+
if (chainId.includes(':')) {
|
|
380
|
+
const chainIdParts = chainId.split(':')
|
|
381
|
+
const reference = parseInt(chainIdParts[1])
|
|
343
382
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
})
|
|
348
|
-
|
|
349
|
-
// Emit event for update
|
|
350
|
-
this.emit('chainChanged', {
|
|
351
|
-
chainId: this.chainId,
|
|
352
|
-
} as SwitchEthereumChainParameter)
|
|
353
|
-
|
|
354
|
-
if (connect && connect.connected) {
|
|
355
|
-
connect.emit('portalConnect_chainChanged', {
|
|
356
|
-
chainId: this.chainId,
|
|
383
|
+
// Emit event for update
|
|
384
|
+
this.emit('chainChanged', {
|
|
385
|
+
chainId: reference,
|
|
357
386
|
} as SwitchEthereumChainParameter)
|
|
387
|
+
|
|
388
|
+
if (connect && connect.connected) {
|
|
389
|
+
connect.emit('portalConnect_chainChanged', {
|
|
390
|
+
chainId: reference,
|
|
391
|
+
} as SwitchEthereumChainParameter)
|
|
392
|
+
}
|
|
393
|
+
// Dispatch 'connect' event
|
|
394
|
+
this.dispatchConnect(chainId)
|
|
395
|
+
} else {
|
|
396
|
+
console.error(
|
|
397
|
+
`[PortalProvider] Invalid chainId format. Must be 'namespace:reference', but got ${chainId}`,
|
|
398
|
+
)
|
|
358
399
|
}
|
|
359
|
-
// Dispatch 'connect' event
|
|
360
|
-
this.dispatchConnect()
|
|
361
400
|
|
|
362
401
|
return new Promise((resolve) => resolve(this))
|
|
363
402
|
}
|
|
@@ -444,9 +483,10 @@ class Provider implements IPortalProvider {
|
|
|
444
483
|
})
|
|
445
484
|
}
|
|
446
485
|
|
|
447
|
-
private dispatchConnect() {
|
|
486
|
+
private dispatchConnect(chainId: string) {
|
|
487
|
+
const reference = chainId.split(':')[1]
|
|
448
488
|
this.emit('connect', {
|
|
449
|
-
chainId: `0x${
|
|
489
|
+
chainId: `0x${Number(reference).toString(16)}`,
|
|
450
490
|
})
|
|
451
491
|
}
|
|
452
492
|
|
|
@@ -459,12 +499,15 @@ class Provider implements IPortalProvider {
|
|
|
459
499
|
private async handleGatewayRequests({
|
|
460
500
|
method,
|
|
461
501
|
params,
|
|
502
|
+
chainId,
|
|
462
503
|
}: RequestArguments): Promise<any> {
|
|
504
|
+
const gatewayUrl = this.getGatewayUrl(chainId)
|
|
463
505
|
// Pass request off to the gateway
|
|
464
|
-
|
|
506
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
507
|
+
return await this.gateway.post<any>(gatewayUrl, '', {
|
|
465
508
|
body: {
|
|
466
509
|
jsonrpc: '2.0',
|
|
467
|
-
id:
|
|
510
|
+
id: chainId,
|
|
468
511
|
method,
|
|
469
512
|
params,
|
|
470
513
|
},
|
|
@@ -493,10 +536,20 @@ class Provider implements IPortalProvider {
|
|
|
493
536
|
)
|
|
494
537
|
return
|
|
495
538
|
}
|
|
539
|
+
let namespace = 'eip155'
|
|
540
|
+
let reference = chainId
|
|
541
|
+
if (typeof chainId == 'string' && chainId.includes(':')) {
|
|
542
|
+
const tmp = chainId.split(':')
|
|
543
|
+
namespace = tmp[0]
|
|
544
|
+
reference = tmp[1]
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
const curve =
|
|
548
|
+
namespace == 'eip155' ? PortalCurve.SECP256K1 : PortalCurve.ED25519
|
|
496
549
|
|
|
497
550
|
switch (method) {
|
|
498
551
|
case 'eth_chainId':
|
|
499
|
-
return `0x${
|
|
552
|
+
return `0x${Number(reference).toString(16)}`
|
|
500
553
|
case 'eth_accounts':
|
|
501
554
|
case 'eth_requestAccounts':
|
|
502
555
|
case 'eth_sendTransaction':
|
|
@@ -504,30 +557,35 @@ class Provider implements IPortalProvider {
|
|
|
504
557
|
case 'eth_signTransaction':
|
|
505
558
|
case 'eth_signTypedData_v3':
|
|
506
559
|
case 'eth_signTypedData_v4':
|
|
507
|
-
case 'personal_sign':
|
|
560
|
+
case 'personal_sign':
|
|
561
|
+
case 'sol_signAndConfirmTransaction':
|
|
562
|
+
case 'sol_signAndSendTransaction':
|
|
563
|
+
case 'sol_signMessage':
|
|
564
|
+
case 'sol_signTransaction': {
|
|
508
565
|
const result = await this.signer?.sign(
|
|
509
|
-
{
|
|
566
|
+
{
|
|
567
|
+
chainId: `${namespace}:${reference}`,
|
|
568
|
+
method,
|
|
569
|
+
params,
|
|
570
|
+
curve,
|
|
571
|
+
isRaw: false,
|
|
572
|
+
},
|
|
510
573
|
this,
|
|
511
574
|
)
|
|
512
575
|
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
} catch (error) {
|
|
527
|
-
// Do nothing, because we don't want metrics gathering
|
|
528
|
-
// to block the SDK
|
|
529
|
-
}
|
|
530
|
-
}
|
|
576
|
+
return result
|
|
577
|
+
}
|
|
578
|
+
case 'raw_sign': {
|
|
579
|
+
const result = await this.signer?.sign(
|
|
580
|
+
{
|
|
581
|
+
chainId: '',
|
|
582
|
+
method: '',
|
|
583
|
+
params,
|
|
584
|
+
curve,
|
|
585
|
+
isRaw: true,
|
|
586
|
+
},
|
|
587
|
+
this,
|
|
588
|
+
)
|
|
531
589
|
|
|
532
590
|
return result
|
|
533
591
|
}
|
package/src/signers/mpc.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { PortalCurve } from '@portal-hq/core'
|
|
1
2
|
import { FeatureFlags } from '@portal-hq/core/types'
|
|
2
3
|
import {
|
|
3
4
|
IPortalProvider,
|
|
@@ -16,29 +17,18 @@ import {
|
|
|
16
17
|
import Signer from './abstract'
|
|
17
18
|
|
|
18
19
|
class MpcSigner implements Signer {
|
|
19
|
-
private isSimulator: boolean
|
|
20
20
|
private keychain: KeychainAdapter
|
|
21
21
|
private mpc: PortalMobileMpc
|
|
22
22
|
private mpcHost: string // should we add a default here mpc.portalhq.io
|
|
23
23
|
private version = 'v6'
|
|
24
24
|
private featureFlags: FeatureFlags
|
|
25
25
|
|
|
26
|
-
private get address(): Promise<string | undefined> {
|
|
27
|
-
return this.keychain.getAddress(this.isSimulator)
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
private get signingShare(): Promise<string> {
|
|
31
|
-
return this.keychain.getDkgResult(this.isSimulator)
|
|
32
|
-
}
|
|
33
|
-
|
|
34
26
|
constructor({
|
|
35
27
|
keychain,
|
|
36
|
-
isSimulator = false,
|
|
37
28
|
mpcHost = 'mpc.portalhq.io',
|
|
38
29
|
version = 'v6',
|
|
39
|
-
featureFlags = {
|
|
30
|
+
featureFlags = {},
|
|
40
31
|
}: MpcSignerOptions) {
|
|
41
|
-
this.isSimulator = isSimulator
|
|
42
32
|
this.keychain = keychain
|
|
43
33
|
this.mpc = NativeModules.PortalMobileMpc
|
|
44
34
|
this.mpcHost = mpcHost
|
|
@@ -56,37 +46,71 @@ class MpcSigner implements Signer {
|
|
|
56
46
|
message: SigningRequestArguments,
|
|
57
47
|
provider: IPortalProvider,
|
|
58
48
|
): Promise<any> {
|
|
59
|
-
const
|
|
49
|
+
const eip155Address = await this.keychain.getEip155Address()
|
|
50
|
+
|
|
60
51
|
const apiKey = provider.apiKey
|
|
61
52
|
|
|
62
|
-
const { method,
|
|
53
|
+
const { method, chainId, curve, isRaw } = message
|
|
63
54
|
|
|
64
55
|
switch (method) {
|
|
65
56
|
case 'eth_requestAccounts':
|
|
66
|
-
return [
|
|
57
|
+
return [eip155Address]
|
|
67
58
|
case 'eth_accounts':
|
|
68
|
-
return [
|
|
59
|
+
return [eip155Address]
|
|
69
60
|
default:
|
|
70
61
|
break
|
|
71
62
|
}
|
|
72
63
|
|
|
73
|
-
const
|
|
64
|
+
const shares = await this.keychain.getShares()
|
|
65
|
+
|
|
66
|
+
let signingShare = shares.secp256k1.share
|
|
67
|
+
|
|
68
|
+
if (curve === PortalCurve.ED25519) {
|
|
69
|
+
if (!shares.ed25519) {
|
|
70
|
+
throw new Error(
|
|
71
|
+
'[Portal.Provider.MpcSigner] The ED25519 share is missing from the keychain.',
|
|
72
|
+
)
|
|
73
|
+
}
|
|
74
|
+
signingShare = shares.ed25519.share
|
|
75
|
+
}
|
|
74
76
|
|
|
75
77
|
const metadata: PortalMobileMpcMetadata = {
|
|
76
78
|
clientPlatform: 'REACT_NATIVE',
|
|
77
79
|
isMultiBackupEnabled: this.featureFlags.isMultiBackupEnabled,
|
|
78
80
|
mpcServerVersion: this.version,
|
|
79
|
-
optimized:
|
|
81
|
+
optimized: true,
|
|
82
|
+
curve,
|
|
83
|
+
chainId,
|
|
84
|
+
isRaw,
|
|
80
85
|
}
|
|
86
|
+
|
|
81
87
|
const stringifiedMetadata = JSON.stringify(metadata)
|
|
88
|
+
|
|
89
|
+
let formattedParams: string
|
|
90
|
+
let rpcUrl: string
|
|
91
|
+
|
|
92
|
+
if (isRaw) {
|
|
93
|
+
formattedParams = this.buildParams(method, message.params)
|
|
94
|
+
rpcUrl = ''
|
|
95
|
+
} else {
|
|
96
|
+
formattedParams = JSON.stringify(this.buildParams(method, message.params))
|
|
97
|
+
rpcUrl = provider.getGatewayUrl(chainId)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (typeof formattedParams !== 'string') {
|
|
101
|
+
throw new Error(
|
|
102
|
+
`[Portal.Provider.MpcSigner] The formatted params for the signing request could not be converted to a string. The params were: ${formattedParams}`,
|
|
103
|
+
)
|
|
104
|
+
}
|
|
105
|
+
|
|
82
106
|
const result = await this.mpc.sign(
|
|
83
107
|
apiKey,
|
|
84
108
|
this.mpcHost,
|
|
85
|
-
signingShare,
|
|
109
|
+
JSON.stringify(signingShare),
|
|
86
110
|
message.method,
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
111
|
+
formattedParams,
|
|
112
|
+
rpcUrl,
|
|
113
|
+
chainId,
|
|
90
114
|
stringifiedMetadata,
|
|
91
115
|
)
|
|
92
116
|
|
|
@@ -107,16 +131,21 @@ class MpcSigner implements Signer {
|
|
|
107
131
|
case 'personal_sign':
|
|
108
132
|
case 'eth_signTypedData_v3':
|
|
109
133
|
case 'eth_signTypedData_v4':
|
|
134
|
+
case 'sol_signMessage':
|
|
135
|
+
case 'sol_signTransaction':
|
|
136
|
+
case 'sol_signAndSendTransaction':
|
|
137
|
+
case 'sol_signAndConfirmTransaction':
|
|
110
138
|
if (!Array.isArray(txParams)) {
|
|
111
139
|
params = [txParams]
|
|
112
140
|
}
|
|
113
141
|
break
|
|
114
142
|
default:
|
|
115
143
|
if (Array.isArray(txParams)) {
|
|
116
|
-
|
|
144
|
+
if (txParams.length === 1) {
|
|
145
|
+
params = txParams[0]
|
|
146
|
+
}
|
|
117
147
|
}
|
|
118
148
|
}
|
|
119
|
-
|
|
120
149
|
return params
|
|
121
150
|
}
|
|
122
151
|
}
|
package/types.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ export type ValidHttpRequestMethods = 'DELETE' | 'GET' | 'POST' | 'PUT'
|
|
|
12
12
|
// Interfaces
|
|
13
13
|
|
|
14
14
|
export interface GatewayConfig {
|
|
15
|
-
[key:
|
|
15
|
+
[key: string]: string
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
export interface MpcSignerOptions extends SignerOptions {
|
|
@@ -33,10 +33,13 @@ export interface PortalMobileMpcMetadata {
|
|
|
33
33
|
| 'PASSKEY'
|
|
34
34
|
| 'PASSWORD'
|
|
35
35
|
| 'UNKNOWN'
|
|
36
|
+
chainId?: string
|
|
37
|
+
curve?: PortalCurve
|
|
36
38
|
clientPlatform: string
|
|
37
39
|
isMultiBackupEnabled?: boolean
|
|
38
40
|
mpcServerVersion: string
|
|
39
|
-
optimized:
|
|
41
|
+
optimized: true
|
|
42
|
+
isRaw?: boolean
|
|
40
43
|
}
|
|
41
44
|
|
|
42
45
|
export interface PortalMobileMpc {
|
|
@@ -67,11 +70,11 @@ export interface PortalMobileMpc {
|
|
|
67
70
|
export interface ProviderOptions {
|
|
68
71
|
// Required
|
|
69
72
|
apiKey: string
|
|
70
|
-
chainId: number
|
|
71
73
|
keychain: KeychainAdapter
|
|
72
74
|
gatewayConfig: GatewayLike
|
|
73
75
|
|
|
74
76
|
// Optional
|
|
77
|
+
chainId?: string
|
|
75
78
|
isSimulator?: boolean
|
|
76
79
|
autoApprove?: boolean
|
|
77
80
|
apiHost?: string
|