-
Notifications
You must be signed in to change notification settings - Fork 73
/
Copy pathEthWalletProvider.ts
129 lines (114 loc) · 3.97 KB
/
EthWalletProvider.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import {
AuthMethod,
AuthSig,
BaseProviderOptions,
EthWalletProviderOptions,
EthWalletAuthenticateOptions,
} from '@lit-protocol/types';
import { LIT_CHAINS, AuthMethodType } from '@lit-protocol/constants';
import { SiweMessage } from 'lit-siwe';
import { ethers } from 'ethers';
import { BaseProvider } from './BaseProvider';
import { checkAndSignAuthMessage } from '@lit-protocol/lit-node-client';
import { log } from '@lit-protocol/misc';
export default class EthWalletProvider extends BaseProvider {
/**
* The domain from which the signing request is made
*/
public domain: string;
/**
* The origin from which the signing request is made
*/
public origin: string;
constructor(options: BaseProviderOptions & EthWalletProviderOptions) {
super(options);
try {
this.domain = options.domain || window.location.hostname;
this.origin = options.origin || window.location.origin;
} catch (e) {
log(
'⚠️ Error getting "domain" and "origin" from window object, defaulting to "localhost" and "http://localhost"'
);
this.domain = options.domain || 'localhost';
this.origin = options.origin || 'http://localhost';
}
}
/**
* Generate a wallet signature to use as an auth method
*
* @param {EthWalletAuthenticateOptions} options
* @param {string} [options.address] - Address to sign with
* @param {function} [options.signMessage] - Function to sign message with
* @param {string} [options.chain] - Name of chain to use for signature
* @param {number} [options.expiration] - When the auth signature expires
*
* @returns {Promise<AuthMethod>} - Auth method object containing the auth signature
*/
public async authenticate(
options?: EthWalletAuthenticateOptions
): Promise<AuthMethod> {
const address = options?.address;
const signMessage = options?.signMessage;
const chain = options?.chain || 'ethereum';
let authSig: AuthSig;
if (address && signMessage) {
// Get chain ID or default to Ethereum mainnet
const selectedChain = LIT_CHAINS[chain];
const chainId = selectedChain?.chainId ? selectedChain.chainId : 1;
// Get expiration or default to 24 hours
const expiration =
options?.expiration ||
new Date(Date.now() + 1000 * 60 * 60 * 24).toISOString();
// Prepare Sign in with Ethereum message
const preparedMessage: Partial<SiweMessage> = {
domain: this.domain,
uri: this.origin,
address: ethers.utils.getAddress(address), // convert to EIP-55 format or else SIWE complains
version: '1',
chainId,
expirationTime: expiration,
};
const message: SiweMessage = new SiweMessage(preparedMessage);
const toSign: string = message.prepareMessage();
// Use provided function to sign message
const signature = await signMessage(toSign);
authSig = {
sig: signature,
derivedVia: 'web3.eth.personal.sign',
signedMessage: toSign,
address: address,
};
} else {
authSig = await checkAndSignAuthMessage({
chain,
});
}
const authMethod = {
authMethodType: AuthMethodType.EthWallet,
accessToken: JSON.stringify(authSig),
};
return authMethod;
}
/**
* Get auth method id that can be used to look up and interact with
* PKPs associated with the given auth method
*
* @param {AuthMethod} authMethod - Auth method object
*
* @returns {Promise<string>} - Auth method id
*/
public async getAuthMethodId(authMethod: AuthMethod): Promise<string> {
return EthWalletProvider.authMethodId(authMethod);
}
public static async authMethodId(authMethod: AuthMethod): Promise<string> {
let address: string;
try {
address = JSON.parse(authMethod.accessToken).address;
} catch (err) {
throw new Error(
`Error when parsing auth method to generate auth method ID for Eth wallet: ${err}`
);
}
return address.toLowerCase();
}
}