Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 0953199

Browse files
committedJan 22, 2025··
✨ Add evm migration API
1 parent d681408 commit 0953199

File tree

3 files changed

+142
-3
lines changed

3 files changed

+142
-3
lines changed
 

‎src/routes/wallet/index.ts

+44-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Router } from 'express';
22
import { checkCosmosSignPayload, checkEvmSignPayload } from '../../util/api/users';
33
import { ValidationError } from '../../util/ValidationError';
44
import { jwtSign } from '../../util/jwt';
5-
import { findLikeWalletByEvmWallet } from '../../util/api/wallet';
5+
import { findLikeWalletByEvmWallet, migrateLikeWalletToEvmWallet } from '../../util/api/wallet';
66

77
const router = Router();
88

@@ -51,4 +51,47 @@ router.post('/authorize', async (req, res, next) => {
5151
}
5252
});
5353

54+
router.post('/evm/migrate', async (req, res, next) => {
55+
try {
56+
const {
57+
wallet, from, signature, publicKey, message, signMethod,
58+
} = req.body;
59+
const inputWallet = wallet || from;
60+
if (!inputWallet || !signature || !publicKey || !message) throw new ValidationError('INVALID_PAYLOAD');
61+
if (!publicKey) throw new ValidationError('INVALID_PAYLOAD');
62+
const signed = checkCosmosSignPayload({
63+
signature, publicKey, message, inputWallet, signMethod, action: 'migrate',
64+
});
65+
if (!signed) {
66+
throw new ValidationError('INVALID_SIGN');
67+
}
68+
const { evmWallet } = signed;
69+
if (!evmWallet) {
70+
throw new ValidationError('INVALID_PAYLOAD');
71+
}
72+
const {
73+
isMigratedBookUser,
74+
isMigratedLikerId,
75+
isMigratedLikerLand,
76+
migratedLikerId,
77+
migratedLikerLandUser,
78+
migrateBookUserError,
79+
migrateLikerIdError,
80+
migrateLikerLandError,
81+
} = await migrateLikeWalletToEvmWallet(evmWallet, inputWallet);
82+
res.json({
83+
isMigratedBookUser,
84+
isMigratedLikerId,
85+
isMigratedLikerLand,
86+
migratedLikerId,
87+
migratedLikerLandUser,
88+
migrateBookUserError,
89+
migrateLikerIdError,
90+
migrateLikerLandError,
91+
});
92+
} catch (err) {
93+
next(err);
94+
}
95+
});
96+
5497
export default router;

‎src/util/api/wallet/index.ts

+80-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
import { likeNFTBookUserCollection } from '../../firebase';
1+
import {
2+
db, FieldValue, likeNFTBookUserCollection, userCollection,
3+
} from '../../firebase';
4+
import { migrateLikerLandEvmWallet } from '../../liker-land';
25

36
export async function findLikeWalletByEvmWallet(evmWallet: string) {
47
const userQuery = await likeNFTBookUserCollection.where('evmWallet', '==', evmWallet).get();
@@ -8,4 +11,80 @@ export async function findLikeWalletByEvmWallet(evmWallet: string) {
811
return userQuery.docs[0].data()?.likeWallet;
912
}
1013

14+
async function migrateBookUser(likeWallet: string, evmWallet: string) {
15+
try {
16+
const userExists = await db.runTransaction(async (t) => {
17+
const [evmQuery, userDoc] = await Promise.all([
18+
t.get(likeNFTBookUserCollection.where('evmWallet', '==', evmWallet).limit(1)),
19+
t.get(likeNFTBookUserCollection.doc(likeWallet).get()),
20+
]);
21+
if (evmQuery.docs.length > 0) {
22+
throw new Error('EVM_WALLET_ALREADY_EXIST');
23+
}
24+
if (!userDoc.exists) {
25+
t.create(likeNFTBookUserCollection.doc(likeWallet), {
26+
evmWallet,
27+
likeWallet,
28+
timestamp: FieldValue.serverTimestamp(),
29+
});
30+
} else {
31+
t.update({ evmWallet, likeWallet });
32+
}
33+
return userDoc.exists;
34+
});
35+
return { error: null };
36+
} catch (error) {
37+
// eslint-disable-next-line no-console
38+
console.error(error);
39+
return { error: (error as Error).message };
40+
}
41+
}
42+
43+
async function migrateLikerId(likeWallet:string, evmWallet: string) {
44+
try {
45+
const likerId = await db.runTransaction(async (t) => {
46+
const [evmQuery, userQuery] = await Promise.all([
47+
t.get(userCollection.where('evmWallet', '==', evmWallet).limit(1)),
48+
t.get(userCollection.where('likeWallet', '==', likeWallet).limit(1)),
49+
]);
50+
if (evmQuery.docs.length > 0) {
51+
throw new Error('EVM_WALLET_ALREADY_EXIST');
52+
}
53+
if (userQuery.docs.length === 0) {
54+
throw new Error('LIKE_WALLET_NOT_FOUND');
55+
}
56+
const userDoc = userQuery.docs[0];
57+
t.update(userDoc.ref, { evmWallet });
58+
return userDoc.id;
59+
});
60+
return { likerId, error: null };
61+
} catch (error) {
62+
// eslint-disable-next-line no-console
63+
console.error(error);
64+
return { error: (error as Error).message };
65+
}
66+
}
67+
68+
export async function migrateLikeWalletToEvmWallet(likeWallet: string, evmWallet: string) {
69+
const [
70+
{ error: migrateBookUserError },
71+
{ error: migrateLikerIdError, likerId },
72+
{ error: migrateLikerLandError, user: likerLandUser },
73+
] = await Promise.all([
74+
migrateBookUser(likeWallet, evmWallet),
75+
migrateLikerId(likeWallet, evmWallet),
76+
migrateLikerLandEvmWallet(likeWallet, evmWallet),
77+
]);
78+
return {
79+
isMigratedBookUser: !migrateBookUserError,
80+
isMigratedLikerId: !migrateLikerIdError,
81+
isMigratedLikerLand: !migrateLikerLandError,
82+
migratedLikerId: likerId,
83+
migratedLikerLandUser: likerLandUser,
84+
migrateBookUserError,
85+
migrateLikerIdError,
86+
migrateLikerLandError,
87+
};
88+
}
89+
1190
export default findLikeWalletByEvmWallet;

‎src/util/liker-land.ts

+18-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import axios from 'axios';
1+
import axios, { AxiosError } from 'axios';
22
import { LIKER_LAND_HOSTNAME } from '../constant';
33
import {
44
LIKER_LAND_GET_WALLET_SECRET,
@@ -431,3 +431,20 @@ export async function fetchLikerLandWalletUserInfo(wallet) {
431431
return null;
432432
}
433433
}
434+
435+
export async function migrateLikerLandEvmWallet(likeWallet: string, evmWallet: string) {
436+
try {
437+
const { data } = await axios.post(`https://${LIKER_LAND_HOSTNAME}/api/v2/users/wallet/evm/migrate`, {
438+
evmWallet,
439+
}, {
440+
headers: { 'x-likerland-api-key': LIKER_LAND_GET_WALLET_SECRET },
441+
params: { wallet: likeWallet },
442+
});
443+
return { user: data, error: null };
444+
} catch (error) {
445+
if (axios.isAxiosError(error)) {
446+
return { error: new Error((error as AxiosError).response?.data as string) };
447+
}
448+
return { user: null, error: null };
449+
}
450+
}

0 commit comments

Comments
 (0)
Please sign in to comment.