generated from MetaMask/template-snap-monorepo
-
Notifications
You must be signed in to change notification settings - Fork 5
/
lit.ts
158 lines (142 loc) · 3.97 KB
/
lit.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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
import { BaseProvider } from '@metamask/providers';
import {
ContractInterface,
ContractTransaction,
ethers,
Signer,
utils,
} from 'ethers';
import { base58, toUtf8Bytes } from 'ethers/lib/utils';
import PKPNFTABI from '../../../../contracts/PKPNFT.json';
import PKPHelperABI from '../../../../contracts/PKPHelper.json';
import { ChainId, changeNetwork } from '../utils';
export type TokenPayload = {
iss: string;
at_hash?: string;
email_verified?: boolean;
sub: string;
azp?: string;
email?: string;
profile?: string;
picture?: string;
name?: string;
given_name?: string;
family_name?: string;
aud: string;
iat: number;
exp: number;
nonce?: string;
hd?: string;
locale?: string;
};
const decodeJwt = (token: string) => {
const base64Url = token.split('.')[1];
const base64 = base64Url.replace(/-/gu, '+').replace(/_/gu, '/');
const decodedBase64 = window.atob(base64);
const decodedToken = JSON.parse(
decodeURIComponent(encodeURIComponent(decodedBase64)),
) as TokenPayload;
return decodedToken;
};
export enum AuthMethodType {
EthWallet = 1,
LitAction,
WebAuthn,
Discord,
Google,
GoogleJwt,
}
const pkpNftAddress = '0xF5cB699652cED3781Dd75575EDBe075d6212DF98';
const pkpHelperAddress = '0x5a8e445BCFE85264566c32Be50A172F3d14F53Fc';
function getContract(
contractAddress: string,
contractJson: ContractInterface,
signer?: Signer,
) {
const ethersContract = new ethers.Contract(
contractAddress,
contractJson,
signer,
);
return ethersContract;
}
const getPkpHelperContract = () => {
return getContract(pkpHelperAddress, PKPHelperABI);
};
const getPkpNftContract = () => {
return getContract(pkpNftAddress, PKPNFTABI);
};
export async function mintPKPWithIpfsCid({ ipfsCid }: { ipfsCid: string }) {
console.log('mintPKPWithIpfsCid');
return await mintPKP({
authMethodType: AuthMethodType.LitAction,
idForAuthMethod: ipfsCid,
});
}
export async function mintPKPWithCredential({
credential,
}: {
credential: string;
}) {
console.log('mintPKPWithCredential');
const tokenPayload = decodeJwt(credential);
if (!tokenPayload) {
throw new Error('Failed to decode ID token');
}
const idForAuthMethod = utils.keccak256(
toUtf8Bytes(`${tokenPayload.sub}:${tokenPayload.aud}`),
);
return await mintPKP({
authMethodType: AuthMethodType.GoogleJwt,
idForAuthMethod,
});
}
async function mintPKP({
authMethodType,
idForAuthMethod,
}: {
authMethodType: AuthMethodType;
idForAuthMethod: string;
}) {
try {
await changeNetwork(ChainId.lit);
const provider = new ethers.providers.Web3Provider(
window.ethereum as BaseProvider,
);
const accounts = await provider.send('eth_requestAccounts', []);
console.log('accounts', accounts);
const signer = await provider.getSigner();
console.log('in mintPKP');
const pkpHelper = getPkpHelperContract().connect(signer);
const pkpNft = getPkpNftContract().connect(signer);
const mintCost = await pkpNft.mintCost();
console.log(idForAuthMethod);
// it doesn't return tx.
let encodedIdForAuthMethod: string | Uint8Array = idForAuthMethod;
if (authMethodType === AuthMethodType.LitAction) {
encodedIdForAuthMethod = base58.decode(idForAuthMethod);
}
const tx = (await pkpHelper.mintNextAndAddAuthMethods(
2,
[authMethodType],
[encodedIdForAuthMethod],
['0x'],
[[ethers.BigNumber.from('0')]],
true,
true,
{ value: mintCost },
)) as ContractTransaction;
console.log('txhash', tx.hash);
const mintReceipt = await tx.wait();
console.log('mintReceipt', mintReceipt);
const tokenId = mintReceipt.logs[0].topics[3];
console.log('minted token', tokenId);
const pkpEthAddress = await pkpNft.getEthAddress(tokenId);
const pkpPublicKey = await pkpNft.getPubkey(tokenId);
console.log('pkpPublicKey', pkpPublicKey);
return { pkpPublicKey, pkpEthAddress };
} catch (e) {
console.log('error', e);
throw e;
}
}