diff --git a/package.json b/package.json index a273531..23498ce 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@web3mq/client", - "version": "1.1.0-beta.1", + "version": "1.1.0-beta.2", "main": "dist/index.js", "repository": "git@github.com:Generative-Labs/web3-mq-sdk.git", "author": "zhaowei", diff --git a/src/register/index.ts b/src/register/index.ts index ee808b1..b1572f9 100644 --- a/src/register/index.ts +++ b/src/register/index.ts @@ -41,6 +41,9 @@ import { AccountType, BlockChainMap, BlockChainType, + GetSignContentForRegisterParams, + RegisterBySignatureParams, + LoginByWalletKeysParams, } from '../types'; import { StarknetConnect, WalletId } from './StarknetConnect'; @@ -168,7 +171,57 @@ export class Register { // @ts-ignore request.defaults.headers['web3mq-request-pubkey'] = PublicKey; // @ts-ignore - request.defaults.headers['didkey'] = `${didType}:${didValue}`; + request.defaults.headers['didkey'] = `${BlockChainMap[didType]}:${didValue}`; + return { + tempPrivateKey: PrivateKey, + tempPublicKey: PublicKey, + mainPrivateKey, + mainPublicKey, + pubkeyExpiredTimestamp, + }; + } catch (error: any) { + throw new Error(error.message); + } + }; + loginByWallet = async (options: LoginByWalletKeysParams): Promise => { + const { + password, + userid, + didValue, + didType, + mainPrivateKey, + mainPublicKey, + pubkeyExpiredTimestamp = Date.now() + 86400 * 1000, + } = options; + try { + const timestamp = Date.now(); + + const { PublicKey, PrivateKey } = await GenerateEd25519KeyPair(); + + const signContent = sha3_224(userid + PublicKey + pubkeyExpiredTimestamp + timestamp); + const AesKey = await GetAESBase64Key(password); + const AesIv = AesKey.slice(0, 16); + const decode_data = await aesGCMDecrypt(AesKey, AesIv, Base64StringToUint8(mainPrivateKey)); + const decode_dataStr = new TextDecoder().decode(new Uint8Array(decode_data)); + const login_signature = await getDataSignature(decode_dataStr, signContent); + + const payload: LoginApiParams = { + userid, + did_type: didType, + did_value: didValue, + login_signature, + signature_content: signContent, + main_pubkey: mainPublicKey, + pubkey_value: PublicKey, + pubkey_type: 'ed25519', + timestamp, + pubkey_expired_timestamp: pubkeyExpiredTimestamp, + }; + await userLoginRequest(payload); + // @ts-ignore + request.defaults.headers['web3mq-request-pubkey'] = PublicKey; + // @ts-ignore + request.defaults.headers['didkey'] = `${BlockChainMap[didType]}:${didValue}`; return { tempPrivateKey: PrivateKey, tempPublicKey: PublicKey, @@ -272,6 +325,29 @@ If your Web3MQ wallet-associated password and this signature is exposed to any m In the event of such an incident, don’t panic. You can call Web3MQ’s key revoke API and service to revoke access to the exposed encryption key and generate a new one! +Nonce: ${magicString}`; + + return { signContent }; + }; + getSignContentForMainKeys = async (options: { + password: string; + didValue: string; + didType: BlockChainType; + }): Promise => { + const { password, didType, didValue } = options; + const keyIndex = 1; + const keyMSG = `${didType}:${didValue}${keyIndex}${password}`; + + const magicString = Uint8ToBase64String( + new TextEncoder().encode(sha3_224(`$web3mq${keyMSG}web3mq$`)), + ); + + const signContent = `Signing this message will allow this app to decrypt messages in the Web3MQ protocol for the following address: ${didValue}. This won’t cost you anything. + +If your Web3MQ wallet-associated password and this signature is exposed to any malicious app, this would result in exposure of Web3MQ account access and encryption keys, and the attacker would be able to read your messages. + +In the event of such an incident, don’t panic. You can call Web3MQ’s key revoke API and service to revoke access to the exposed encryption key and generate a new one! + Nonce: ${magicString}`; return { signContent }; @@ -333,4 +409,73 @@ Issued At: ${getCurrentDate()}`; this.registerTime = timestamp; return { signContent }; }; + getSignContentForRegister = async ( + options: GetSignContentForRegisterParams, + ): Promise => { + const { + mainPublicKey, + didType, + didValue, + userid, + signContentURI = window.location.origin, + } = options; + + const pubkey_type = this.pubicKeyType; + const timestamp = Date.now(); + const NonceContent = sha3_224( + userid + pubkey_type + mainPublicKey + didType + didValue + timestamp, + ); + + const signContent = `Web3MQ wants you to sign in with your ${didType} account: +${didValue} +For Web3MQ register +URI: ${signContentURI} +Version: 1 + +Nonce: ${NonceContent} +Issued At: ${getCurrentDate()}`; + + this.registerSignContent = signContent; + this.registerTime = timestamp; + return { signContent, registerTime: timestamp }; + }; + + registerBySign = async (options: RegisterBySignatureParams) => { + const { + userid, + didValue, + mainPublicKey, + signature, + did_pubkey = '', + didType = 'eth', + nickname = '', + avatar_url = '', + avatar_base64 = '', + } = options; + if (!this.registerTime || !this.registerSignContent) { + throw new Error('Please create register sign content first!'); + } + + const payload: RegisterApiParams = { + userid, + did_type: didType, + did_value: didValue, + did_pubkey, + did_signature: signature, + signature_content: this.registerSignContent, + pubkey_type: this.pubicKeyType, + pubkey_value: mainPublicKey, + nickname, + avatar_url, + avatar_base64, + timestamp: this.registerTime, + testnet_access_key: this.appKey, + }; + + try { + return await userRegisterRequest(payload); + } catch (error: any) { + throw new Error(error.message); + } + }; } diff --git a/src/types.ts b/src/types.ts index ff6b897..fc6f601 100644 --- a/src/types.ts +++ b/src/types.ts @@ -51,6 +51,18 @@ export type RegisterBySignParams = { avatar_url?: string; avatar_base64?: string; }; +export type RegisterBySignatureParams = { + userid: string; + didValue: string; + mainPublicKey: string; + signature: string; + did_pubkey?: string; + didType?: BlockChainType; + signContentURI?: string; + nickname?: string; + avatar_url?: string; + avatar_base64?: string; +}; export type LoginByKeysParams = { mainPrivateKey: string; @@ -61,6 +73,15 @@ export type LoginByKeysParams = { password: string; pubkeyExpiredTimestamp?: number; }; +export type LoginByWalletKeysParams = { + mainPrivateKey: string; + mainPublicKey: string; + didType: BlockChainType; + didValue: string; + userid: string; + password: string; + pubkeyExpiredTimestamp?: number; +}; export type InitOptions = { connectUrl?: string | null; @@ -117,6 +138,12 @@ export type GetMainKeypairParams = { did_value: string; }; +export type GenerateMainKeypair = { + password: string; + walletType: WalletType; + address: string; +}; + export interface SignConnectOptions extends SendTempConnectOptions { wsUrl: string; } @@ -493,6 +520,7 @@ export type WalletSignRes = { export type GetSignContentResponse = { signContent: string; + registerTime?: number }; export type GetRegisterSignContentParams = { @@ -502,6 +530,13 @@ export type GetRegisterSignContentParams = { didValue: string; signContentURI?: string; }; +export type GetSignContentForRegisterParams = { + userid: string; + mainPublicKey: string; + didType: BlockChainType; + didValue: string; + signContentURI?: string; +}; export type MainKeypairType = { publicKey: string;