diff --git a/packages/keysmith/package.json b/packages/keysmith/package.json index 1b46002..704a8c9 100644 --- a/packages/keysmith/package.json +++ b/packages/keysmith/package.json @@ -58,6 +58,7 @@ "@polkadot/keyring": "^10.1.8", "@polkadot/util": "^10.1.8", "@polkadot/util-crypto": "^10.1.8", + "@solana/web3.js": "^1.74.0", "@stablelib/bytes": "^1.0.1", "@stablelib/chacha20poly1305": "^1.0.1", "@stablelib/hex": "^1.0.1", @@ -70,7 +71,8 @@ "body-parser": "^1.20.1", "ethers": "^5.7.1", "googleapis": "^108.0.0", - "randomstring": "^1.2.2" + "randomstring": "^1.2.2", + "uuid": "^9.0.0" }, "resolutions": { "sharp": "0.28.0" diff --git a/packages/keysmith/src/chains/_share_/context.ts b/packages/keysmith/src/chains/_share_/context.ts new file mode 100644 index 0000000..0401341 --- /dev/null +++ b/packages/keysmith/src/chains/_share_/context.ts @@ -0,0 +1,10 @@ +import { Me3Wallet } from '../../types' +import { WalletCipher } from '../../safeV2/v2' + +export interface IChainContext { + readonly series: string + + createWallet(chains: any[], mnemonic: string, pkCipher: WalletCipher): Promise + + signTx(mainChain, wallet: Me3Wallet, tx: any, pkDecipher: WalletCipher): Promise +} \ No newline at end of file diff --git a/packages/keysmith/src/wallet/create-wallet/common.ts b/packages/keysmith/src/chains/_share_/functions.ts similarity index 100% rename from packages/keysmith/src/wallet/create-wallet/common.ts rename to packages/keysmith/src/chains/_share_/functions.ts diff --git a/packages/keysmith/src/chains/bitcoin/context.ts b/packages/keysmith/src/chains/bitcoin/context.ts new file mode 100644 index 0000000..9ae3b90 --- /dev/null +++ b/packages/keysmith/src/chains/bitcoin/context.ts @@ -0,0 +1,57 @@ +import _ from 'lodash' + +import { IChainContext } from '../_share_/context' +import { WalletCipher } from '../../safeV2/v2' +import { Me3Wallet } from '../../types' +import { getWalletName } from '../_share_/functions' + +const getGenerator = (series: string) => { + switch (_.toLower(series)) { + case 'btc': + return require('bitcore-lib') + case 'ltc': + return require('bitcore-lib-ltc') + case 'bch': + return require('bitcore-lib-cash') + default: + break + } + return undefined +} + +export class BitcoinContext implements IChainContext { + readonly series: string + + constructor(_series: string) { + this.series = _series + } + createWallet(chains: any[], mnemonic: string, pkCipher: WalletCipher): Promise { + const wallets = _.chain(chains) + .map(c => { + const generator = getGenerator(c.series) + if (_.isEmpty(generator)) { + return undefined + } + + const value = Buffer.from(mnemonic, 'utf8') + const hash = generator.crypto.Hash.sha256(value) + const bn = generator.crypto.BN.fromBuffer(hash) + const privateKey = new generator.PrivateKey(bn) + + return { + walletAddress: privateKey.toAddress().toString(), + secret: pkCipher(privateKey.toString()), + walletName: getWalletName(c.description), + chainName: c.name, + } as Me3Wallet + }) + .compact() + .value() + return Promise.resolve(wallets) + } + + signTx(mainChain, wallet: Me3Wallet, tx: any, pkDecipher: WalletCipher): Promise { + // TODO: BTC tx signning + return Promise.resolve('') + } +} \ No newline at end of file diff --git a/packages/keysmith/src/chains/cosmos/context.ts b/packages/keysmith/src/chains/cosmos/context.ts new file mode 100644 index 0000000..b740b8c --- /dev/null +++ b/packages/keysmith/src/chains/cosmos/context.ts @@ -0,0 +1,17 @@ +import { IChainContext } from '../_share_/context' +import { WalletCipher } from '../../safeV2/v2' +import { Me3Wallet } from '../../types' + +// TODO +export class CosmosContext implements IChainContext { + readonly series: string + + createWallet(chains: any[], mnemonic: string, pkCipher: WalletCipher): Promise { + return Promise.resolve([]) + } + + signTx(mainChain, wallet: Me3Wallet, tx: any, pkDecipher: WalletCipher): Promise { + return Promise.resolve('') + } + +} \ No newline at end of file diff --git a/packages/keysmith/src/chains/evm/context.ts b/packages/keysmith/src/chains/evm/context.ts new file mode 100644 index 0000000..6124b7c --- /dev/null +++ b/packages/keysmith/src/chains/evm/context.ts @@ -0,0 +1,41 @@ +import { ethers } from 'ethers' +import { Me3Wallet } from '../../types' +import { IChainContext } from '../_share_/context' +import { WalletCipher } from '../../safeV2/v2' +import { TransactionRequest } from './domain' +import { getWalletName } from '../_share_/functions' + +export class EvmContext implements IChainContext { + readonly series: string + + constructor(_series: string) { + this.series = _series + } + + createWallet(chains: any[], mnemonic: string, cipher: WalletCipher): Promise { + const wallets = chains.map(c => { + const accountIdx = 0 + const path = `${c.path}${accountIdx}` + + const wallet = ethers.Wallet.fromMnemonic(mnemonic, path) + return { + walletAddress: wallet.address, + secret: cipher(wallet.privateKey), + chainName: c.name, + walletName: getWalletName(c.description), + } as Me3Wallet + }) + + return Promise.resolve(wallets) + } + + async signTx(_, wallet: Me3Wallet, tx: TransactionRequest, pkDecipher: WalletCipher): Promise { + const rawPK = pkDecipher(wallet.secret) + try { + const wallet = new ethers.Wallet(rawPK) + return await wallet.signTransaction(tx) + } catch (error) { + throw new Error('Invalid privateKey provided') + } + } +} \ No newline at end of file diff --git a/packages/keysmith/src/chains/evm/domain.ts b/packages/keysmith/src/chains/evm/domain.ts new file mode 100644 index 0000000..52a453a --- /dev/null +++ b/packages/keysmith/src/chains/evm/domain.ts @@ -0,0 +1 @@ +export type TransactionRequest = Record \ No newline at end of file diff --git a/packages/keysmith/src/chains/file/context.ts b/packages/keysmith/src/chains/file/context.ts new file mode 100644 index 0000000..d8b8e90 --- /dev/null +++ b/packages/keysmith/src/chains/file/context.ts @@ -0,0 +1,45 @@ +import _ from 'lodash' +import * as signer from '@zondax/filecoin-signing-tools' + +import { IChainContext } from '../_share_/context' +import { WalletCipher } from '../../safeV2/v2' +import { Me3Wallet } from '../../types' +import { getWalletName } from '../_share_/functions' + +export class FileContext implements IChainContext { + readonly series: string + + constructor(_series: string) { + this.series = _series + } + + createWallet(chains: any[], mnemonic: string, pkCipher: WalletCipher): Promise { + const wallets = _.chain(chains) + .map(c => { + const accountIdx = 0 + const path = `${c.path}${accountIdx}` + + const key = signer.keyDerive( + mnemonic, + path, + _.toLower(c.name) === 'fil' ? 'mainnet' : 'testnet' + ) + + return { + walletAddress: key.address, + secret: pkCipher(key.private_base64), + walletName: getWalletName(c.description), + chainName: c.name, + } as Me3Wallet + }) + .compact() + .value() + + return Promise.resolve(wallets) + } + + signTx(mainChain, wallet: Me3Wallet, tx: any, pkDecipher: WalletCipher): Promise { + // TODO: File tx signning + return Promise.resolve('') + } +} diff --git a/packages/keysmith/src/chains/index.ts b/packages/keysmith/src/chains/index.ts new file mode 100644 index 0000000..3e63450 --- /dev/null +++ b/packages/keysmith/src/chains/index.ts @@ -0,0 +1,7 @@ +export * from './_share_/context' +export * from './bitcoin/context' +export * from './cosmos/context' +export * from './evm/context' +export * from './file/context' +export * from './solana/context' +export * from './substrate/context' \ No newline at end of file diff --git a/packages/keysmith/src/chains/solana/context.ts b/packages/keysmith/src/chains/solana/context.ts new file mode 100644 index 0000000..b9118e5 --- /dev/null +++ b/packages/keysmith/src/chains/solana/context.ts @@ -0,0 +1,64 @@ +import _ from 'lodash' +import * as bip39 from 'bip39' +import * as bs58 from 'bs58' +import { clusterApiUrl, Connection, Keypair, PublicKey, Transaction } from '@solana/web3.js' + +import { IChainContext } from '../_share_/context' +import { Me3Wallet } from '../../types' +import { WalletCipher } from '../../safeV2/v2' +import { getWalletName } from '../_share_/functions' + +const RpcEndpoint = { + 'sol': 'mainnet-beta', + 'soldev': 'devnet', + 'soltest': 'testnet', +} +export class SolanaContext implements IChainContext { + readonly series: string + + constructor(_series: string) { + this.series = _series + } + + async createWallet( + chains: any[], + mnemonic: string, + pkCipher: WalletCipher + ): Promise { + const seed = await bip39.mnemonicToSeed(mnemonic) + const keypair = Keypair.fromSeed(seed.subarray(0, 32)) + const wallets = chains.map(c => { + return { + chainName: c.name, + walletName: getWalletName(c.name), + walletAddress: keypair.publicKey.toBase58(), + secret: pkCipher(bs58.encode(keypair.secretKey)), + } as Me3Wallet + }) + return wallets + } + + async signTx( + mainChain, + wallet: Me3Wallet, + tx: Transaction, + pkDecipher: (pk: string) => string + ): Promise { + if (_.isEmpty(tx.recentBlockhash) || _.isNil(tx.lastValidBlockHeight)) { + const rpc = mainChain.node ?? clusterApiUrl(RpcEndpoint[_.toLower(wallet.chainName)]) + const solConn = new Connection(rpc) + const lastHash = await solConn.getLatestBlockhash('confirmed') + tx.recentBlockhash = lastHash.blockhash + tx.lastValidBlockHeight = lastHash.lastValidBlockHeight + } + + const rawPK = pkDecipher(wallet.secret) + const rawPKBytes = bs58.decode(rawPK) + tx.sign({ + publicKey: new PublicKey(wallet.walletAddress), + secretKey: rawPKBytes, + }) + const bytes = tx.serialize() + return bs58.encode(bytes) + } +} \ No newline at end of file diff --git a/packages/keysmith/src/chains/substrate/context.ts b/packages/keysmith/src/chains/substrate/context.ts new file mode 100644 index 0000000..0e8fd61 --- /dev/null +++ b/packages/keysmith/src/chains/substrate/context.ts @@ -0,0 +1,47 @@ +import { + cryptoIsReady, + cryptoWaitReady, + encodeAddress, + mnemonicToMiniSecret, + sr25519PairFromSeed, +} from '@polkadot/util-crypto' + +import { IChainContext } from '../_share_/context' +import { Me3Wallet } from '../../types' +import { WalletCipher } from '../../safeV2/v2' +import { u8aToHex } from '@polkadot/util' +import { getWalletName } from '../_share_/functions' + +export class SubstrateContext implements IChainContext { + readonly series: string + + constructor(_series: string) { + this.series = _series + if (!cryptoIsReady()) { + cryptoWaitReady().then(console.log) + } + } + createWallet(chains: any[], mnemonic: string, pkCipher: WalletCipher): Promise { + const mini = mnemonicToMiniSecret(mnemonic) + const { publicKey, secretKey } = sr25519PairFromSeed(mini) + const walletAddress = encodeAddress(publicKey) + const secret = pkCipher(u8aToHex(secretKey)) + + const wallets = chains.map(c => { + return { + chainName: c.name, + walletName: getWalletName(c.description), + walletAddress, + secret, + } as Me3Wallet + }) + + return Promise.resolve(wallets) + } + + signTx(mainChain, wallet: Me3Wallet, tx: any, pkDecipher: WalletCipher): Promise { + // TODO + return Promise.resolve('') + } + +} \ No newline at end of file diff --git a/packages/keysmith/src/me3.ts b/packages/keysmith/src/me3.ts index 315452a..cee3b56 100644 --- a/packages/keysmith/src/me3.ts +++ b/packages/keysmith/src/me3.ts @@ -4,38 +4,46 @@ import _ from 'lodash' import RandomString from 'randomstring' import * as bip39 from 'bip39' -import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios' -import { CommData, DriveName, ME3Config, Tokens, Me3Wallet } from './types' -import createWallet from './wallet' +import axios, { AxiosInstance, AxiosResponse } from 'axios' +import { CommData, DriveName, ME3Config, Me3Wallet, Tokens } from './types' import Google from './google' import { aes, rsa, v2 } from './safeV2' -import { signTransaction } from './transaction' +import { BitcoinContext, EvmContext, FileContext, IChainContext, SolanaContext, SubstrateContext } from './chains' export default class Me3 { private _gClient: Google private readonly _client: AxiosInstance + // TODO: Should be grouped in Me3Session {{{ private _apiToken?: Tokens private _userSecret?: any private _myPriRsa?: string private _serverPubRsa?: string + // TODO: Should be groupd in Me3Session }}} + + private _chainCtxs = new Map() constructor(credential: ME3Config) { this._client = axios.create({ baseURL: credential.endpoint, + timeout: (1000 * 60 * 30), + headers: { + 'Company-ID': 2000, + 'Partner-ID': credential.partnerId, + }, }) - const companyHeader = { - 'Company-ID': 2000, - 'Partner-ID': credential.partnerId, - } const _this: Me3 = this - this._client.interceptors.request.use( (config) => { - let chain = _.chain(companyHeader).pickBy(_.identity) + this._client.interceptors.request.use((config) => { + // https://stackoverflow.com/a/43439886 + delete process.env['http_proxy'] + delete process.env['HTTP_PROXY'] + delete process.env['https_proxy'] + delete process.env['HTTPS_PROXY'] + if (!_.isEmpty(_this._apiToken?.kc_access)) { - chain = chain.set('Authorization', `Bearer ${_this._apiToken.kc_access}`) + config.headers.set('Authorization', `Bearer ${_this._apiToken.kc_access}`) } - config.headers = chain.merge(config.headers).value() return config }) this._client.interceptors.response.use( @@ -61,6 +69,12 @@ export default class Me3 { return Promise.reject(err) } ) + + this._chainCtxs['sol'] = new SolanaContext('sol') + this._chainCtxs['eth'] = new EvmContext('eth') + this._chainCtxs['btc'] = new BitcoinContext('btc') + this._chainCtxs['dot'] = new SubstrateContext('dot') + this._chainCtxs['fil'] = new FileContext('fil') } /** @@ -71,7 +85,7 @@ export default class Me3 { } /** - * Please use before getWallets + * Please use before `signTx` */ isInitialized(): boolean { if (_.isEmpty(this._apiToken)) { @@ -120,23 +134,18 @@ export default class Me3 { const { email, krFileId } = await this._getUserProfile() const isNewUser = await this._loadBackupFile(krFileId) - if (!isNewUser) { + if (isNewUser) { + console.log(`New User, Create wallets for ${email}!`) + } else { console.log(`Already exist, Restore wallets for ${email}!`) - return await this._loadWallets() + const wallets = await this._loadWallets() + if (!_.isEmpty(wallets)) { + return wallets + } + console.log(`OOPS, no wallet found and creating wallets for ${email}!`) } - console.log(`New User, Create wallets for ${email}!`) - const [cipher] = v2.getWalletCiphers(this._userSecret) - - const wallets = await this._createWallets().then( - results => _.map(results, w => ({ - chainName: w.chainName, - walletName: w.walletName, - walletAddress: w.walletAddress, - // TODO: We will provide encrypted private key, as partner wants tx sign on our module - secret: cipher(w.secretRaw), - })), - ) + const wallets = await this._createWallets() for (const w of wallets) { await Promise.all([ this._client.post( @@ -194,7 +203,7 @@ export default class Me3 { * @param txRequest: parameters of a transaction {@link TransactionRequest} * @return string signedTransaction */ - async signTx(wallet: Me3Wallet, txRequest) { + async signTx(wallet: Me3Wallet, txRequest): Promise { const chains = await this._getChainList() const chainFound = _.chain(chains) .filter(c => _.toLower(c.name) === _.toLower(wallet.chainName)) @@ -203,13 +212,13 @@ export default class Me3 { if (_.isEmpty(chainFound)) { throw Error('Chain not supported') } - const [, decipher] = v2.getWalletCiphers(this._userSecret) - return await signTransaction({ - series: chainFound.series, - privateKey: decipher(wallet.secret), - transactionRequest: txRequest, - }) + + const refinedSeries = _.toLower(chainFound.series) + if (!_.has(this._chainCtxs, refinedSeries)) { + return Promise.reject(`Unsupported series ${refinedSeries}`) + } + return this._chainCtxs[refinedSeries].signTx(chainFound, wallet, txRequest, decipher) } // private async _generateQR(content: string): Promise { @@ -241,8 +250,18 @@ export default class Me3 { // Create wallets const mnemonic = bip39.generateMnemonic() const wallets = new Array() + + const [cipher] = v2.getWalletCiphers(this._userSecret) + for (const entry of _.entries(refined)) { - const _wallets = await createWallet(entry, mnemonic) + const [series, chains] = entry + + if (!_.has(this._chainCtxs, series)) { + console.error(`[Me3::_getChainList] Unsupported series ${series}`) + continue + } + + const _wallets = await this._chainCtxs[series].createWallet(chains, mnemonic, cipher) if (!_.isEmpty(_wallets)) { wallets.push(_wallets) } diff --git a/packages/keysmith/src/safe/aes.ts b/packages/keysmith/src/safe/aes.ts deleted file mode 100644 index bd1210f..0000000 --- a/packages/keysmith/src/safe/aes.ts +++ /dev/null @@ -1,39 +0,0 @@ -import _ from 'lodash' -import { createCipheriv, createDecipheriv, pbkdf2Sync } from 'crypto' - -const ENC_ALGO = 256 -const KEY_SIZE = ENC_ALGO / 8 -const IV_SIZE = 128 / 8 - -export function encrypt(plain: string, password: string, salt: string): string { - const key = pbkdf2Sync(password, salt, 1, KEY_SIZE, 'sha512') - const iv = pbkdf2Sync(password, salt, 1, IV_SIZE, 'sha512') - - const cipher = createCipheriv(`aes-${ENC_ALGO}-cbc`, key, iv) - cipher.setAutoPadding(false) - const encrypted = Buffer.concat([ - cipher.update(_paddingSpace(plain), 'utf8'), - cipher.final(), - ]).toString('hex') - return Buffer.from(encrypted, 'utf8') - .toString('base64') -} - -export function decrypt(b64Str: string, password: string, salt: string): string { - const key = pbkdf2Sync(password, salt, 1, KEY_SIZE, 'sha512') - const iv = pbkdf2Sync(password, salt, 1, IV_SIZE, 'sha512') - - const utf8 = Buffer.from(b64Str, 'base64').toString('utf8') - const decipher = createDecipheriv(`aes-${ENC_ALGO}-cbc`, key, iv) - decipher.setAutoPadding(false) - const decoded = Buffer.concat([ - decipher.update(utf8, 'hex'), - decipher.final(), - ]).toString('utf8') - return _.trimEnd(decoded, ' ') -} - -function _paddingSpace(str: string, pad = 16) { - const paddedLen = str.length + pad - (str.length % pad) - return _.padEnd(str, paddedLen) -} diff --git a/packages/keysmith/src/safe/chacha.ts b/packages/keysmith/src/safe/chacha.ts deleted file mode 100644 index a2665bc..0000000 --- a/packages/keysmith/src/safe/chacha.ts +++ /dev/null @@ -1,40 +0,0 @@ -import crypto, { randomBytes } from 'crypto' - -const ALGO_NAME = 'chacha20-poly1305' -const AUTHTAG_LEN = 16 -const NONCE_LEN = 12 - -export function genPassword(): Buffer { - return randomBytes(32) -} - -export function encrypt(key: Buffer, plain: Buffer): Buffer { - const nonce = randomBytes(NONCE_LEN) - const cipher = crypto.createCipheriv(ALGO_NAME, key, nonce, { - authTagLength: AUTHTAG_LEN, - }) - return Buffer.concat([ - //---Nonce--- - nonce, - //---Ciper texts--- - cipher.update(plain), - cipher.final(), - //---Auth Tag--- - cipher.getAuthTag(), - ]) -} - -export function decrypt(key: Buffer, encrypted: Buffer): Buffer { - const nonce = encrypted.subarray(0, NONCE_LEN) - const decipher = crypto.createDecipheriv(ALGO_NAME, key, nonce, { - authTagLength: AUTHTAG_LEN, - }) - decipher.setAuthTag(encrypted.subarray(-AUTHTAG_LEN)) - return Buffer.concat([ - decipher.update(encrypted.subarray( - NONCE_LEN, - -AUTHTAG_LEN - )), - decipher.final(), - ]) -} diff --git a/packages/keysmith/src/safe/index.ts b/packages/keysmith/src/safe/index.ts deleted file mode 100644 index 99e8eb5..0000000 --- a/packages/keysmith/src/safe/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * as v1 from './aes' -export * as v2 from './v2' -export * as aes from './aes' -export * as rsa from './rsa' diff --git a/packages/keysmith/src/safe/rsa.ts b/packages/keysmith/src/safe/rsa.ts deleted file mode 100644 index 26368db..0000000 --- a/packages/keysmith/src/safe/rsa.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { - createPrivateKey, - createPublicKey, - generateKeyPairSync, - KeyObject, - privateDecrypt, - privateEncrypt, - publicDecrypt, - publicEncrypt, -} from 'crypto' -import { RsaKey } from '../types' - -export async function genKeyPair(): Promise { - const { publicKey, privateKey } = await generateKeyPairSync('rsa', { - modulusLength: 1024, - publicExponent: 0x10001, - publicKeyEncoding: { - format: 'der', - type: 'spki', - }, - privateKeyEncoding: { - format: 'der', - type: 'pkcs8', - }, - }) - return { - privateKey: privateKey.toString('base64'), - publicKey: publicKey.toString('base64'), - } -} - -export function encrypt(b64Key: string, plain: Buffer, isPubKey = true): Buffer { - const keyObj = _b642RsaKey(b64Key, isPubKey) - return isPubKey - ? publicEncrypt(keyObj, plain) - : privateEncrypt(keyObj, plain) -} - -export function decrypt(b64Key: string, encrypted: Buffer, isPubKey = false): Buffer { - const keyObj = _b642RsaKey(b64Key, isPubKey) - return isPubKey - ? publicDecrypt(keyObj, encrypted) - : privateDecrypt(keyObj, encrypted) -} - -function _b642RsaKey(b64Str: string, isPubKey = true): KeyObject { - const buf = Buffer.from(b64Str, 'base64') - - return isPubKey - ? createPublicKey({ - key: buf, - format: 'der', - type: 'spki', - }) - : createPrivateKey({ - key: buf, - format: 'der', - type: 'pkcs8', - }) -} diff --git a/packages/keysmith/src/safe/v2.ts b/packages/keysmith/src/safe/v2.ts deleted file mode 100644 index 7fc6b64..0000000 --- a/packages/keysmith/src/safe/v2.ts +++ /dev/null @@ -1,60 +0,0 @@ -import _ from 'lodash' -import { randomBytes } from 'crypto' -import * as aes from './aes' -import * as rsa from './rsa' -import * as chacha from './chacha' -import { CommData, CommSecret } from '../types' - -export function encrypt(plain: string, commSecret: CommSecret): CommData { - if (!_.isEmpty(commSecret.aesPwd) && !_.isEmpty(commSecret.aesSalt)) { - plain = aes.encrypt( - plain, - commSecret.aesPwd!, - commSecret.aesSalt! - ) - } - - const chachaKey = randomBytes(32) - const data = chacha.encrypt( - chachaKey, - Buffer.from(plain, 'utf8') - ).toString('base64') - const secret = rsa.encrypt( - commSecret.rsaKey, - chachaKey, - commSecret.isPubKey - ).toString('base64') - return { data, secret } -} - -export function decrypt(data: CommData, commSecret: CommSecret): string { - const chachaKey = rsa.decrypt( - commSecret.rsaKey, - Buffer.from(data.secret, 'base64'), - commSecret.isPubKey - ) - const decryped = chacha.decrypt( - chachaKey, - Buffer.from(data.data, 'base64') - ) - - const ret = decryped.toString('utf8') - if (_.isEmpty(commSecret.aesPwd) || _.isEmpty(commSecret.aesSalt)) { - return ret - } - return aes.decrypt(ret, commSecret.aesPwd!, commSecret.aesSalt!) -} - -export function getWalletCiphers(krData) { - if (_.isEmpty(krData)) { - throw Error('Wrong KR info!') - } - - const { key, salt, password } = krData - const decryptedKey = aes.decrypt(key, password, salt) - - return [ - plainPK => aes.encrypt(plainPK, decryptedKey, salt), - encryptedPK => aes.decrypt(encryptedPK, decryptedKey, salt), - ] -} diff --git a/packages/keysmith/src/safeV2/v2.ts b/packages/keysmith/src/safeV2/v2.ts index 1a88db1..ab15933 100644 --- a/packages/keysmith/src/safeV2/v2.ts +++ b/packages/keysmith/src/safeV2/v2.ts @@ -36,7 +36,8 @@ export function decrypt(data: CommData, commSecret: CommSecret): string { return aes.decrypt(ret, commSecret.aesPwd!, commSecret.aesSalt!) } -export function getWalletCiphers(krData) { +export type WalletCipher = (key: string) => string +export function getWalletCiphers(krData): WalletCipher[] { if (_.isEmpty(krData)) { throw Error('Wrong KR info!') } diff --git a/packages/keysmith/src/transaction/domain.ts b/packages/keysmith/src/transaction/domain.ts deleted file mode 100644 index d6c3781..0000000 --- a/packages/keysmith/src/transaction/domain.ts +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Please provide params required to execute transactions on the blockchain of your choice - */ -export type TransactionRequest = Record - -/** - * WalletData interface is the shape of each wallet object returned by me3.getWallets() method - */ -export interface WalletData { - chainName: string; - secret: string; - [key: string]: any; -} - -export interface SignTransactionParams { - privateKey: string, - series: string, - transactionRequest: TransactionRequest, -} \ No newline at end of file diff --git a/packages/keysmith/src/transaction/index.ts b/packages/keysmith/src/transaction/index.ts deleted file mode 100644 index df3fb82..0000000 --- a/packages/keysmith/src/transaction/index.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { performSignEvmTransaction } from './perform-sign-transaction' -import { SignTransactionParams } from './domain' - -export const signTransaction = async ({ - series, - privateKey, - transactionRequest, -}: SignTransactionParams): Promise => { - console.log('signTransaction::transactionRequest to sign', transactionRequest) - - switch (series.toLowerCase()) { - case 'avax': - case 'bsc': - case 'matic': - case 'eth': { - return await performSignEvmTransaction(privateKey, transactionRequest) - } - case 'ltc': - case 'bch': - case 'btc': - case 'fil': - case 'dot': { - throw new Error('Not implemented yet') - } - default: { - throw new Error('Unsupported series') - } - } -} - -export default { - signTransaction, -} \ No newline at end of file diff --git a/packages/keysmith/src/transaction/perform-sign-transaction.ts b/packages/keysmith/src/transaction/perform-sign-transaction.ts deleted file mode 100644 index ef0c6b3..0000000 --- a/packages/keysmith/src/transaction/perform-sign-transaction.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { ethers } from 'ethers' - -import { TransactionRequest } from './domain' - -export const performSignEvmTransaction = async ( - privateKey: string, - transactionRequest: TransactionRequest -): Promise => { - let wallet - try { - wallet = new ethers.Wallet(privateKey) - } catch (error) { - throw new Error('Invalid privateKey provided') - } - - return await wallet.signTransaction(transactionRequest) -} - -export default { - performSignEvmTransaction, -} \ No newline at end of file diff --git a/packages/keysmith/src/types.ts b/packages/keysmith/src/types.ts index abef333..615ddb2 100644 --- a/packages/keysmith/src/types.ts +++ b/packages/keysmith/src/types.ts @@ -43,15 +43,10 @@ interface CommData { } interface Me3Wallet { - chainName: string; - walletName: string; - walletAddress: string; - secret: string; -} - -interface WalletRaw { - walletAddress: string; - secretRaw: string; + chainName: string, + walletName: string, + walletAddress: string, + secret: string, } -export { DriveName, ME3Config, RsaKey, Tokens, CommSecret, CommData, Me3Wallet, WalletRaw } +export { DriveName, ME3Config, RsaKey, Tokens, CommSecret, CommData, Me3Wallet } diff --git a/packages/keysmith/src/wallet.ts b/packages/keysmith/src/wallet.ts deleted file mode 100644 index d57a2f5..0000000 --- a/packages/keysmith/src/wallet.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { - cryptoIsReady, - cryptoWaitReady, - encodeAddress, - mnemonicToMiniSecret, - sr25519PairFromSeed, -} from '@polkadot/util-crypto' -import { u8aToHex } from '@polkadot/util' -import { ethers } from 'ethers' - -import { createFileCoinWallet } from './wallet/create-wallet/filecoin' -import { createBtcWallet } from './wallet/create-wallet/bitcoin' -import { getWalletName } from './wallet/create-wallet/common' - -export default async function createWallet(companyChain, mnemonic: string) { - const [series, chains] = companyChain - switch (series) { - case 'btc': - case 'ltc': - case 'bch': - return createBtcWallet(series, mnemonic) - - case 'eth': { - return chains.map(c => { - const wallet = ethers.Wallet.fromMnemonic(mnemonic, c.path) - return { - walletAddress: wallet.address, - secretRaw: wallet.privateKey, - chainName: c.name, - walletName: getWalletName(c.description), - } - }) - } - case 'dot': { - if (!cryptoIsReady()) { - await cryptoWaitReady() - } - const mini = mnemonicToMiniSecret(mnemonic) - const { publicKey, secretKey } = sr25519PairFromSeed(mini) - const walletAddress = encodeAddress(publicKey) - const secretRaw = u8aToHex(secretKey) - - return chains.map(c => { - return { - walletAddress, - secretRaw, - chainName: c.name, - walletName: getWalletName(c.description), - } - }) - } - case 'fil': - case 'filtest': { - return createFileCoinWallet(chains, mnemonic) - } - default: - break - } - return undefined -} - diff --git a/packages/keysmith/src/wallet/create-wallet/bitcoin.ts b/packages/keysmith/src/wallet/create-wallet/bitcoin.ts deleted file mode 100644 index 59edb9a..0000000 --- a/packages/keysmith/src/wallet/create-wallet/bitcoin.ts +++ /dev/null @@ -1,37 +0,0 @@ -import _ from 'lodash' -import { getWalletName } from './common' - -export const createBtcWallet = (chains: [any], mnemonic: string) => _.chain(chains) - .map(c => { - const generator = getGenerator(c.series) - if (_.isEmpty(generator)) { - return undefined - } - - const value = Buffer.from(mnemonic, 'utf8') - const hash = generator.crypto.Hash.sha256(value) - const bn = generator.crypto.BN.fromBuffer(hash) - const privateKey = new generator.PrivateKey(bn) - return { - walletAddress: privateKey.toAddress().toString(), - secretRaw: privateKey.toString(), - walletName: getWalletName(c.description), - chainName: c.name, - } - }) - .compact() - .value() - -const getGenerator = (series: string) => { - switch (_.toLower(series)) { - case 'btc': - return require('bitcore-lib') - case 'ltc': - return require('bitcore-lib-ltc') - case 'bch': - return require('bitcore-lib-cash') - default: - break - } - return undefined -} \ No newline at end of file diff --git a/packages/keysmith/src/wallet/create-wallet/filecoin.ts b/packages/keysmith/src/wallet/create-wallet/filecoin.ts deleted file mode 100644 index c4d6f14..0000000 --- a/packages/keysmith/src/wallet/create-wallet/filecoin.ts +++ /dev/null @@ -1,19 +0,0 @@ - -import _ from 'lodash' -import * as signer from '@zondax/filecoin-signing-tools' -import { getWalletName } from './common' - -export const createFileCoinWallet = (chains: [any], mnemonic: string) => chains.map(c => { - const key = signer.keyDerive( - mnemonic, - c.path, - _.toLower(c.name) === 'fil' ? 'mainnet' : 'testnet' - ) - - return { - walletAddress: key.address, - secretRaw: key.private_base64, - walletName: getWalletName(c.description), - chainName: c.name, - } -}) \ No newline at end of file diff --git a/packages/keysmith/test/chains/ethereum.ts b/packages/keysmith/test/chains/ethereum.ts new file mode 100644 index 0000000..dd99aef --- /dev/null +++ b/packages/keysmith/test/chains/ethereum.ts @@ -0,0 +1,51 @@ +import _ from 'lodash' +import * as bip39 from 'bip39' +import { describe } from 'mocha' +import { expect } from 'chai' +import { PublicKey, SystemProgram, Transaction } from '@solana/web3.js' + +import { v2 } from '../../src/safeV2' +import { EvmContext, IChainContext, SolanaContext } from '../../src/chains' +import { mockGetChainListResponse } from '../fixtures/me3-get-chain-list' +import { ALICE } from '../fixtures/configs' +import { Me3Wallet } from '../../src/types' +import { utils } from 'ethers' + +const SERIES = 'eth' +describe('Evm context testing', () => { + let ethCtx: IChainContext + let wallets: Me3Wallet[] + let chainMap + + before(function () { + ethCtx = new EvmContext(SERIES) + }) + + it('EvmContext::createWallet', async function () { + const mnemonic = bip39.generateMnemonic() + + chainMap = _.groupBy( + mockGetChainListResponse.data, + it => _.toLower(it.series) + ) + + const [cipher] = v2.getWalletCiphers(ALICE) + const size = chainMap[SERIES].length + wallets = await ethCtx.createWallet(chainMap[SERIES], mnemonic, cipher) + + expect(wallets.length).equal(size) + }) + + it('EvmContext::signTx', async function () { + const [, decipher] = v2.getWalletCiphers(ALICE) + + const tx = { + to: '0x8ba1f109551bD432803012645Ac136ddd64DBA72', + value: utils.parseEther('1.0'), + } + + const found = _.find(chainMap[ethCtx.series], c => c.name === wallets[0].chainName) + const rawTx = await ethCtx.signTx(found, wallets[0], tx, decipher) + expect(rawTx).to.not.be.null + }) +}) \ No newline at end of file diff --git a/packages/keysmith/test/chains/file.ts b/packages/keysmith/test/chains/file.ts new file mode 100644 index 0000000..ddd618d --- /dev/null +++ b/packages/keysmith/test/chains/file.ts @@ -0,0 +1,37 @@ +import _ from 'lodash' +import * as bip39 from 'bip39' +import { describe } from 'mocha' +import { expect } from 'chai' +import { PublicKey, SystemProgram, Transaction } from '@solana/web3.js' + +import { v2 } from '../../src/safeV2' +import { FileContext, IChainContext, SolanaContext } from '../../src/chains' +import { mockGetChainListResponse } from '../fixtures/me3-get-chain-list' +import { ALICE } from '../fixtures/configs' +import { Me3Wallet } from '../../src/types' +import { utils } from 'ethers' + +const SERIES = 'fil' +describe('File context testing', () => { + let fileCtx: IChainContext + let wallets: Me3Wallet[] + let chainMap + + before(function () { + fileCtx = new FileContext(SERIES) + }) + + it('FileContext::createWallet', async function () { + const mnemonic = bip39.generateMnemonic() + + chainMap = _.groupBy( + mockGetChainListResponse.data, + it => _.toLower(it.series) + ) + const size = chainMap[SERIES].length + const [cipher] = v2.getWalletCiphers(ALICE) + wallets = await fileCtx.createWallet(chainMap[SERIES], mnemonic, cipher) + + expect(wallets.length).equal(size) + }) +}) \ No newline at end of file diff --git a/packages/keysmith/test/chains/solana.ts b/packages/keysmith/test/chains/solana.ts new file mode 100644 index 0000000..69b0c3a --- /dev/null +++ b/packages/keysmith/test/chains/solana.ts @@ -0,0 +1,59 @@ +import _ from 'lodash' +import * as bip39 from 'bip39' +import { describe } from 'mocha' +import { expect } from 'chai' +import { PublicKey, SystemProgram, Transaction } from '@solana/web3.js' + +import { v2 } from '../../src/safeV2' +import { IChainContext, SolanaContext } from '../../src/chains' +import { mockGetChainListResponse } from '../fixtures/me3-get-chain-list' +import { ALICE } from '../fixtures/configs' +import { Me3Wallet } from '../../src/types' + +const SERIES = 'sol' +describe('Solana context testing', () => { + let solanaCtx: IChainContext + let wallets: Me3Wallet[] + let chainMap + + before(function () { + solanaCtx = new SolanaContext(SERIES) + }) + + it('SolanaContext::createWallet', async function () { + const mnemonic = bip39.generateMnemonic() + + chainMap = _.groupBy( + mockGetChainListResponse.data, + it => _.toLower(it.series) + ) + const size = chainMap[SERIES].length + const [cipher] = v2.getWalletCiphers(ALICE) + wallets = await solanaCtx.createWallet(chainMap[SERIES], mnemonic, cipher) + + expect(wallets.length).equal(size) + }) + + it('SolanaContext::signTx', async function () { + const [, decipher] = v2.getWalletCiphers(ALICE) + + const sender = new PublicKey(wallets[0].walletAddress) + const receiver = new PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v') + + const tx = new Transaction() + { + tx.add( + SystemProgram.transfer({ + fromPubkey: sender, + toPubkey: receiver, + lamports: 1000000, + }) + ) + // We can add more instructions here + } + + const found = _.find(chainMap[solanaCtx.series], c => c.name === wallets[0].chainName) + const rawTx = await solanaCtx.signTx(found, wallets[0], tx, decipher) + expect(rawTx).to.not.be.null + }) +}) \ No newline at end of file diff --git a/packages/keysmith/test/fixtures/me3-get-chain-list.ts b/packages/keysmith/test/fixtures/me3-get-chain-list.ts index 23bf66c..88da94b 100644 --- a/packages/keysmith/test/fixtures/me3-get-chain-list.ts +++ b/packages/keysmith/test/fixtures/me3-get-chain-list.ts @@ -1,182 +1,259 @@ export const mockGetChainListResponse = { - 'code': '0', - 'msg': 'success', - 'data': [ - { - 'id': 2, - 'name': 'ETH', - 'symbol': 'ETH', - 'symbolIcon': 'https://hicoinvip.oss-cn-beijing.aliyuncs.com/saas/20210930/fa2f1c8d81694848bff8d7e823dc82b1.png', - 'description': 'Ethereum\n', - 'chainId': 1, - 'node': 'https://api.tatum.io/v3/blockchain/node/ETH/d93807e0-1006-4db6-a4fe-681bb81eccdb_100', - 'series': 'ETH', - 'hdCoinId': 60, - 'path': 'm/44\'/60\'/0\'/0/', - 'icon': 'https://hicoinvip.oss-cn-beijing.aliyuncs.com/saas/1626847409064.png', - 'activeIcon': 'https://hicoinvip.oss-cn-beijing.aliyuncs.com/saas/1626847357176.png', - 'sort': 2, - 'state': 1, - 'companyId': 2000, - 'txUrl': 'https://etherscan.io/tx/', - 'supportNft': 1, - 'supportDapp': 1, - 'ctime': 1626336341000, - 'mtime': 1675983791000, - 'currency': 'USD', - 'symbolRate': 1548.99, - 'change': '-6.42614', - }, - { - 'id': 3, - 'name': 'Polygon', - 'symbol': 'MATIC', - 'symbolIcon': 'https://oss.metabazaar.vip/wallet/20221111/cf98579e32bd479caadd360b3e4d8f4c.png', - 'description': 'Polygon', - 'chainId': 137, - 'node': 'https://api.tatum.io/v3/blockchain/node/MATIC/d93807e0-1006-4db6-a4fe-681bb81eccdb_100', - 'series': 'ETH', - 'hdCoinId': null, - 'path': 'm/44\'/60\'/0\'/0/', - 'icon': 'https://oss.metabazaar.vip/wallet/20221111/ebf897bfc26a43faa839644a36f0dba2.png', - 'activeIcon': 'https://oss.metabazaar.vip/wallet/20221111/fa669583b9f0462badd8f805e903772f.png', - 'sort': 4, - 'state': 1, - 'companyId': 2000, - 'txUrl': 'https://polygonscan.com/tx/', - 'supportNft': 1, - 'supportDapp': 1, - 'ctime': 1626744235000, - 'mtime': 1675123862000, - 'currency': 'USD', - 'symbolRate': 1.23, - 'change': '-6.37164', - }, - { - 'id': 4, - 'name': 'PolygonTest', - 'symbol': 'MATIC', - 'symbolIcon': 'https://hicoinvip.oss-cn-beijing.aliyuncs.com/saas/20220312/f5e3df4bbd3f4d9281d62ddc7e742535.png', - 'description': 'Polygon Testnet', - 'chainId': 80001, - 'node': 'https://api.tatum.io/v3/blockchain/node/MATIC/a1f30291-a820-482e-ab19-ee3403f80383_100', - 'series': 'ETH', - 'hdCoinId': 60, - 'path': 'm/44\'/60\'/0\'/0/', - 'icon': 'https://hicoinvip.oss-cn-beijing.aliyuncs.com/saas/20220312/c05d9d8fba9f4b0e95827de85beb14bb.png', - 'activeIcon': 'https://hicoinvip.oss-cn-beijing.aliyuncs.com/saas/20220312/d3bf400b6cab41b6b8ccaa95f288c5de.png', - 'sort': 7, - 'state': 1, - 'companyId': 2000, - 'txUrl': 'https://mumbai.polygonscan.com/tx/', - 'supportNft': 1, - 'supportDapp': 1, - 'ctime': 1626744476000, - 'mtime': 1675197926000, - 'currency': 'USD', - 'symbolRate': 1.23, - 'change': '-6.37164', - }, - { - 'id': 16, - 'name': 'Fuji', - 'symbol': 'AVAX', - 'symbolIcon': 'https://oss.metabazaar.vip/wallet/20221111/37654adc00f74098a7173579d07b639d.png', - 'description': 'Fuji Testnet\n', - 'chainId': 43113, - 'node': 'https://capable-aged-resonance.avalanche-testnet.quiknode.pro/4eb68fc64be46f14cf35068125719bb13a68dfe0/ext/bc/C/rpc/', - 'series': 'ETH', - 'hdCoinId': null, - 'path': 'm/44\'/60\'/0\'/0/', - 'icon': 'https://oss.metabazaar.vip/wallet/20221111/bfeb32a9402248018a458c32dad135cc.png', - 'activeIcon': 'https://oss.metabazaar.vip/wallet/20221111/a55c009369c240bea8d06cc96f1846a5.png', - 'sort': 18, - 'state': 1, - 'companyId': 2000, - 'txUrl': 'https://testnet.snowtrace.io/tx/', - 'supportNft': 1, - 'supportDapp': 1, - 'ctime': 1653471985000, - 'mtime': 1673818239000, - 'currency': 'USD', - 'symbolRate': 17.94, - 'change': '-10.96622', - }, - { - 'id': 17, - 'name': 'AVAX', - 'symbol': 'AVAX', - 'symbolIcon': 'https://oss.metabazaar.vip/wallet/20221111/f40e34f7725f4043bb3f0a55d5f74350.png', - 'description': 'Avalanche', - 'chainId': 43114, - 'node': 'https://api.tatum.io/v3/blockchain/node/AVAX/d93807e0-1006-4db6-a4fe-681bb81eccdb_100', - 'series': 'ETH', - 'hdCoinId': null, - 'path': 'm/44\'/60\'/0\'/0/', - 'icon': 'https://oss.metabazaar.vip/wallet/20221111/4fd680c36ee14e26add93827f076ee80.png', - 'activeIcon': 'https://oss.metabazaar.vip/wallet/20221111/09bc80b6a03c4be5b91d669a2334532d.png', - 'sort': 18, - 'state': 1, - 'companyId': 2000, - 'txUrl': 'https://testnet.snowtrace.io/tx/', - 'supportNft': 1, - 'supportDapp': 1, - 'ctime': 1653471985000, - 'mtime': 1673818036000, - 'currency': 'USD', - 'symbolRate': 17.94, - 'change': '-10.96622', - }, - // the 2 below are fake data for testing purposes - { - 'id': 69, - 'name': 'MOON', - 'symbol': 'MOON', - 'symbolIcon': 'https://oss.metabazaar.vip/wallet/20221111/f40e34f7725f4043bb3f0a55d5f74350.png', - 'description': 'Mooncoin', - 'chainId': 43114, - 'node': 'https://api.tatum.io/v3/blockchain/node/AVAX/d93807e0-1006-4db6-a4fe-681bb81eccdb_100', - 'series': 'MOON', - 'hdCoinId': null, - 'path': 'm/44\'/60\'/0\'/0/', - 'icon': 'https://oss.metabazaar.vip/wallet/20221111/4fd680c36ee14e26add93827f076ee80.png', - 'activeIcon': 'https://oss.metabazaar.vip/wallet/20221111/09bc80b6a03c4be5b91d669a2334532d.png', - 'sort': 18, - 'state': 1, - 'companyId': 2000, - 'txUrl': 'https://testnet.snowtrace.io/tx/', - 'supportNft': 1, - 'supportDapp': 1, - 'ctime': 1653471985000, - 'mtime': 1673818036000, - 'currency': 'USD', - 'symbolRate': 17.94, - 'change': '-10.96622', - }, - { - 'id': 420, - 'name': 'LTC', - 'symbol': 'LTC', - 'symbolIcon': 'https://oss.metabazaar.vip/wallet/20221111/f40e34f7725f4043bb3f0a55d5f74350.png', - 'description': 'litecoin', - 'chainId': 43114, - 'node': 'https://api.tatum.io/v3/blockchain/node/AVAX/d93807e0-1006-4db6-a4fe-681bb81eccdb_100', - 'series': 'LTC', - 'hdCoinId': null, - 'path': 'm/44\'/60\'/0\'/0/', - 'icon': 'https://oss.metabazaar.vip/wallet/20221111/4fd680c36ee14e26add93827f076ee80.png', - 'activeIcon': 'https://oss.metabazaar.vip/wallet/20221111/09bc80b6a03c4be5b91d669a2334532d.png', - 'sort': 18, - 'state': 1, - 'companyId': 2000, - 'txUrl': 'https://testnet.snowtrace.io/tx/', - 'supportNft': 1, - 'supportDapp': 1, - 'ctime': 1653471985000, - 'mtime': 1673818036000, - 'currency': 'USD', - 'symbolRate': 17.94, - 'change': '-10.96622', - }, - ], + 'code': '0', + 'msg': 'success', + 'data': [ + { + 'id': 2, + 'name': 'ETH', + 'symbol': 'ETH', + 'symbolIcon': 'https://hicoinvip.oss-cn-beijing.aliyuncs.com/saas/20210930/fa2f1c8d81694848bff8d7e823dc82b1.png', + 'description': 'Ethereum\n', + 'chainId': 1, + 'node': 'https://api.tatum.io/v3/blockchain/node/ETH/d93807e0-1006-4db6-a4fe-681bb81eccdb_100', + 'series': 'ETH', + 'hdCoinId': 60, + 'path': 'm/44\'/60\'/0\'/0/', + 'icon': 'https://hicoinvip.oss-cn-beijing.aliyuncs.com/saas/1626847409064.png', + 'activeIcon': 'https://hicoinvip.oss-cn-beijing.aliyuncs.com/saas/1626847357176.png', + 'sort': 2, + 'state': 1, + 'companyId': 2000, + 'txUrl': 'https://etherscan.io/tx/', + 'supportNft': 1, + 'supportDapp': 1, + 'ctime': 1626336341000, + 'mtime': 1675983791000, + 'currency': 'USD', + 'symbolRate': 1548.99, + 'change': '-6.42614', + }, + { + 'id': 3, + 'name': 'Polygon', + 'symbol': 'MATIC', + 'symbolIcon': 'https://oss.metabazaar.vip/wallet/20221111/cf98579e32bd479caadd360b3e4d8f4c.png', + 'description': 'Polygon', + 'chainId': 137, + 'node': 'https://api.tatum.io/v3/blockchain/node/MATIC/d93807e0-1006-4db6-a4fe-681bb81eccdb_100', + 'series': 'ETH', + 'hdCoinId': null, + 'path': 'm/44\'/60\'/0\'/0/', + 'icon': 'https://oss.metabazaar.vip/wallet/20221111/ebf897bfc26a43faa839644a36f0dba2.png', + 'activeIcon': 'https://oss.metabazaar.vip/wallet/20221111/fa669583b9f0462badd8f805e903772f.png', + 'sort': 4, + 'state': 1, + 'companyId': 2000, + 'txUrl': 'https://polygonscan.com/tx/', + 'supportNft': 1, + 'supportDapp': 1, + 'ctime': 1626744235000, + 'mtime': 1675123862000, + 'currency': 'USD', + 'symbolRate': 1.23, + 'change': '-6.37164', + }, + { + 'id': 4, + 'name': 'PolygonTest', + 'symbol': 'MATIC', + 'symbolIcon': 'https://hicoinvip.oss-cn-beijing.aliyuncs.com/saas/20220312/f5e3df4bbd3f4d9281d62ddc7e742535.png', + 'description': 'Polygon Testnet', + 'chainId': 80001, + 'node': 'https://api.tatum.io/v3/blockchain/node/MATIC/a1f30291-a820-482e-ab19-ee3403f80383_100', + 'series': 'ETH', + 'hdCoinId': 60, + 'path': 'm/44\'/60\'/0\'/0/', + 'icon': 'https://hicoinvip.oss-cn-beijing.aliyuncs.com/saas/20220312/c05d9d8fba9f4b0e95827de85beb14bb.png', + 'activeIcon': 'https://hicoinvip.oss-cn-beijing.aliyuncs.com/saas/20220312/d3bf400b6cab41b6b8ccaa95f288c5de.png', + 'sort': 7, + 'state': 1, + 'companyId': 2000, + 'txUrl': 'https://mumbai.polygonscan.com/tx/', + 'supportNft': 1, + 'supportDapp': 1, + 'ctime': 1626744476000, + 'mtime': 1675197926000, + 'currency': 'USD', + 'symbolRate': 1.23, + 'change': '-6.37164', + }, + { + 'id': 16, + 'name': 'Fuji', + 'symbol': 'AVAX', + 'symbolIcon': 'https://oss.metabazaar.vip/wallet/20221111/37654adc00f74098a7173579d07b639d.png', + 'description': 'Fuji Testnet\n', + 'chainId': 43113, + 'node': 'https://capable-aged-resonance.avalanche-testnet.quiknode.pro/4eb68fc64be46f14cf35068125719bb13a68dfe0/ext/bc/C/rpc/', + 'series': 'ETH', + 'hdCoinId': null, + 'path': 'm/44\'/60\'/0\'/0/', + 'icon': 'https://oss.metabazaar.vip/wallet/20221111/bfeb32a9402248018a458c32dad135cc.png', + 'activeIcon': 'https://oss.metabazaar.vip/wallet/20221111/a55c009369c240bea8d06cc96f1846a5.png', + 'sort': 18, + 'state': 1, + 'companyId': 2000, + 'txUrl': 'https://testnet.snowtrace.io/tx/', + 'supportNft': 1, + 'supportDapp': 1, + 'ctime': 1653471985000, + 'mtime': 1673818239000, + 'currency': 'USD', + 'symbolRate': 17.94, + 'change': '-10.96622', + }, + { + 'id': 17, + 'name': 'AVAX', + 'symbol': 'AVAX', + 'symbolIcon': 'https://oss.metabazaar.vip/wallet/20221111/f40e34f7725f4043bb3f0a55d5f74350.png', + 'description': 'Avalanche', + 'chainId': 43114, + 'node': 'https://api.tatum.io/v3/blockchain/node/AVAX/d93807e0-1006-4db6-a4fe-681bb81eccdb_100', + 'series': 'ETH', + 'hdCoinId': null, + 'path': 'm/44\'/60\'/0\'/0/', + 'icon': 'https://oss.metabazaar.vip/wallet/20221111/4fd680c36ee14e26add93827f076ee80.png', + 'activeIcon': 'https://oss.metabazaar.vip/wallet/20221111/09bc80b6a03c4be5b91d669a2334532d.png', + 'sort': 18, + 'state': 1, + 'companyId': 2000, + 'txUrl': 'https://testnet.snowtrace.io/tx/', + 'supportNft': 1, + 'supportDapp': 1, + 'ctime': 1653471985000, + 'mtime': 1673818036000, + 'currency': 'USD', + 'symbolRate': 17.94, + 'change': '-10.96622', + }, + // the 2 below are fake data for testing purposes + { + 'id': 69, + 'name': 'MOON', + 'symbol': 'MOON', + 'symbolIcon': 'https://oss.metabazaar.vip/wallet/20221111/f40e34f7725f4043bb3f0a55d5f74350.png', + 'description': 'Mooncoin', + 'chainId': 43114, + 'node': 'https://api.tatum.io/v3/blockchain/node/AVAX/d93807e0-1006-4db6-a4fe-681bb81eccdb_100', + 'series': 'MOON', + 'hdCoinId': null, + 'path': 'm/44\'/60\'/0\'/0/', + 'icon': 'https://oss.metabazaar.vip/wallet/20221111/4fd680c36ee14e26add93827f076ee80.png', + 'activeIcon': 'https://oss.metabazaar.vip/wallet/20221111/09bc80b6a03c4be5b91d669a2334532d.png', + 'sort': 18, + 'state': 1, + 'companyId': 2000, + 'txUrl': 'https://testnet.snowtrace.io/tx/', + 'supportNft': 1, + 'supportDapp': 1, + 'ctime': 1653471985000, + 'mtime': 1673818036000, + 'currency': 'USD', + 'symbolRate': 17.94, + 'change': '-10.96622', + }, + { + 'id': 420, + 'name': 'LTC', + 'symbol': 'LTC', + 'symbolIcon': 'https://oss.metabazaar.vip/wallet/20221111/f40e34f7725f4043bb3f0a55d5f74350.png', + 'description': 'litecoin', + 'chainId': 43114, + 'node': 'https://api.tatum.io/v3/blockchain/node/AVAX/d93807e0-1006-4db6-a4fe-681bb81eccdb_100', + 'series': 'LTC', + 'hdCoinId': null, + 'path': 'm/44\'/60\'/0\'/0/', + 'icon': 'https://oss.metabazaar.vip/wallet/20221111/4fd680c36ee14e26add93827f076ee80.png', + 'activeIcon': 'https://oss.metabazaar.vip/wallet/20221111/09bc80b6a03c4be5b91d669a2334532d.png', + 'sort': 18, + 'state': 1, + 'companyId': 2000, + 'txUrl': 'https://testnet.snowtrace.io/tx/', + 'supportNft': 1, + 'supportDapp': 1, + 'ctime': 1653471985000, + 'mtime': 1673818036000, + 'currency': 'USD', + 'symbolRate': 17.94, + 'change': '-10.96622', + }, + // solana chains + { + 'id': 10000, + 'name': 'SOL', + 'symbol': 'SOL', + 'symbolIcon': 'https://upload.wikimedia.org/wikipedia/en/b/b9/Solana_logo.png', + 'description': 'SolanaMainBeta', + 'chainId': 43114, + 'node': 'https://api.mainnet-beta.solana.com', + 'series': 'SOL', + 'hdCoinId': null, + 'path': 'm/44\'/60\'/0\'/0/', + 'icon': 'https://oss.metabazaar.vip/wallet/20221111/4fd680c36ee14e26add93827f076ee80.png', + 'activeIcon': 'https://oss.metabazaar.vip/wallet/20221111/09bc80b6a03c4be5b91d669a2334532d.png', + 'sort': 18, + 'state': 1, + 'companyId': 2000, + 'txUrl': 'https://testnet.snowtrace.io/tx/', + 'supportNft': 1, + 'supportDapp': 1, + 'ctime': 1653471985000, + 'mtime': 1673818036000, + 'currency': 'USD', + 'symbolRate': 17.94, + 'change': '-10.96622', + }, + { + 'id': 10001, + 'name': 'SOL', + 'symbol': 'dSOL', + 'symbolIcon': 'https://upload.wikimedia.org/wikipedia/en/b/b9/Solana_logo.png', + 'description': 'SolanaDevNet', + 'chainId': 43114, + 'node': 'https://api.devnet.solana.com', + 'series': 'SOL', + 'hdCoinId': null, + 'path': 'm/44\'/60\'/0\'/0/', + 'icon': 'https://oss.metabazaar.vip/wallet/20221111/4fd680c36ee14e26add93827f076ee80.png', + 'activeIcon': 'https://oss.metabazaar.vip/wallet/20221111/09bc80b6a03c4be5b91d669a2334532d.png', + 'sort': 18, + 'state': 1, + 'companyId': 2000, + 'txUrl': 'https://testnet.snowtrace.io/tx/', + 'supportNft': 1, + 'supportDapp': 1, + 'ctime': 1653471985000, + 'mtime': 1673818036000, + 'currency': 'USD', + 'symbolRate': 17.94, + 'change': '-10.96622', + }, + { + 'id': 11, + 'name': 'FILTest', + 'symbol': 'tFIL', + 'symbolIcon': 'https\n' + + '://hicoinvip.oss-cn-beijing.aliyuncs.com/saas/20220401/53e0e61d3c8845c4a0b15da2c8809ac2.png', + 'description': 'FileCoinTest', + 'chainId': 461, + 'node': 'https://api.calibration.node.glif.io/rpc/v0', + 'series': 'FIL', + 'hdCoinId': null, + 'path': 'm/44\'/461\'/0\'/0/', + 'icon': 'https://hicoinvip.oss-cn-beijing.aliyuncs.com/saas/20220401/e141a6370f244ebbb5f388e0a9caaba0.png', + 'activeIcon': 'https://hicoinvip.oss-cn-beijing.aliyuncs.com/saas/20220401/c434dc8d4b8b40d2ad933363f63e5ff6.png', + 'sort': 22, + 'state': 1, + 'companyId': 2000, + 'txUrl': 'https://calibration.filscan.io/tipset/pool-message-detail?cid=', + 'supportNft': 0, + 'supportDapp': 0, + 'ctime': 1653471985000, + 'mtime': 1673818036000, + 'currency': 'USD', + 'symbolRate': 17.94, + 'change': '-10.96622', + }, + ], } \ No newline at end of file diff --git a/packages/keysmith/test/fixtures/safe.ts b/packages/keysmith/test/fixtures/safe.ts index b54f565..5344dcf 100644 --- a/packages/keysmith/test/fixtures/safe.ts +++ b/packages/keysmith/test/fixtures/safe.ts @@ -1,177 +1,177 @@ export const AES_PWD = 'b7f925cf-eb3d-4587-b81b-a17b212cd61d', - AES_SALT = '3990611c-f057-4c25-bde6-4fe932161a5d', - BIG_JSON = { - 'name': 'KyberSwap Token List Arbitrum', - 'keywords': ['dmmexchange', 'kyberswap'], - 'timestamp': '2022-06-20T00:00:00+00:00', - 'logoURI': 'https://kyberswap.com/favicon.png', - 'tokens': [ - { - 'chainId': 42161, - 'address': '0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8', - '_scan': 'https://arbiscan.io/token/0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8', - 'symbol': 'USDC', - 'name': 'USDC', - 'decimals': 6, - 'logoURI': 'https://assets.coingecko.com/coins/images/6319/large/USD_Coin_icon.png', - }, - { - 'chainId': 42161, - 'address': '0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9', - '_scan': 'https://arbiscan.io/token/0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9', - 'symbol': 'USDT', - 'name': 'USDT', - 'decimals': 6, - 'logoURI': 'https://coin.top/production/logo/usdtlogo.png', - }, - { - 'chainId': 42161, - 'address': '0xda10009cbd5d07dd0cecc66161fc93d7c9000da1', - '_scan': 'https://arbiscan.io/token/0xda10009cbd5d07dd0cecc66161fc93d7c9000da1', - 'symbol': 'DAI', - 'name': 'DAI', - 'decimals': 18, - 'logoURI': 'https://assets.coingecko.com/coins/images/9956/large/dai-multi-collateral-mcd.png', - }, - { - 'chainId': 42161, - 'address': '0x82af49447d8a07e3bd95bd0d56f35241523fbab1', - '_scan': 'https://arbiscan.io/token/0x82af49447d8a07e3bd95bd0d56f35241523fbab1', - 'symbol': 'WETH', - 'name': 'Wrapped Ether', - 'decimals': 18, - 'logoURI': 'https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2/logo.png', - }, - { - 'chainId': 42161, - 'address': '0x2f2a2543b76a4166549f7aab2e75bef0aefc5b0f', - '_scan': 'https://arbiscan.io/token/0x2f2a2543b76a4166549f7aab2e75bef0aefc5b0f', - 'symbol': 'WBTC', - 'name': 'WBTC', - 'decimals': 8, - 'logoURI': 'https://assets.coingecko.com/coins/images/7598/large/wrapped_bitcoin_wbtc.png', - }, - { - 'chainId': 42161, - 'address': '0xFEa7a6a0B346362BF88A9e4A88416B77a57D6c2A', - '_scan': 'https://arbiscan.io/token/0xFEa7a6a0B346362BF88A9e4A88416B77a57D6c2A', - 'symbol': 'MIM', - 'name': 'Magic Internet Money', - 'decimals': 18, - 'logoURI': 'https://s2.coinmarketcap.com/static/img/coins/64x64/162.png', - }, - { - 'chainId': 42161, - 'address': '0x3F56e0c36d275367b8C502090EDF38289b3dEa0d', - '_scan': 'https://arbiscan.io/token/0x3F56e0c36d275367b8C502090EDF38289b3dEa0d', - 'decimals': 18, - 'name': 'MAI', - 'symbol': 'MAI', - 'logoURI': 'https://raw.githubusercontent.com/KyberNetwork/ks-assets/main/img/token/MAI.svg', - }, - { - 'chainId': 42161, - 'address': '0x9d2f299715d94d8a7e6f5eaa8e654e8c74a988a7', - '_scan': 'https://arbiscan.io/token/0x9d2f299715d94d8a7e6f5eaa8e654e8c74a988a7', - 'decimals': 18, - 'name': 'Frax Share', - 'symbol': 'FXS', - 'logoURI': 'https://raw.githubusercontent.com/KyberNetwork/ks-assets/main/img/token/FXS.svg', - }, - { - 'chainId': 42161, - 'address': '0x080f6aed32fc474dd5717105dba5ea57268f46eb', - '_scan': 'https://arbiscan.io/token/0x080f6aed32fc474dd5717105dba5ea57268f46eb', - 'decimals': 18, - 'name': 'Synapse', - 'symbol': 'SYN', - 'logoURI': 'https://raw.githubusercontent.com/KyberNetwork/ks-assets/main/img/token/SYN.svg', - }, - { - 'chainId': 42161, - 'address': '0x319f865b287fcc10b30d8ce6144e8b6d1b476999', - '_scan': 'https://arbiscan.io/token/0x319f865b287fcc10b30d8ce6144e8b6d1b476999', - 'decimals': 18, - 'name': 'Cartesi', - 'symbol': 'CTSI', - 'logoURI': 'https://raw.githubusercontent.com/KyberNetwork/ks-assets/main/img/token/CTSI.png', - }, - { - 'chainId': 42161, - 'address': '0x9fb9a33956351cf4fa040f65a13b835a3c8764e3', - '_scan': 'https://arbiscan.io/token/0x9fb9a33956351cf4fa040f65a13b835a3c8764e3', - 'decimals': 18, - 'name': 'Multchain', - 'symbol': 'MULTI', - 'logoURI': 'https://raw.githubusercontent.com/KyberNetwork/ks-assets/main/img/token/MULTI.png', - }, - { - 'chainId': 42161, - 'address': '0x6694340fc020c5e6b96567843da2df01b2ce1eb6', - '_scan': 'https://arbiscan.io/token/0x6694340fc020c5e6b96567843da2df01b2ce1eb6', - 'decimals': 18, - 'name': 'Stargate Finance', - 'symbol': 'STG', - 'logoURI': 'https://raw.githubusercontent.com/KyberNetwork/ks-assets/main/img/token/STG.svg', - }, - { - 'chainId': 42161, - 'address': '0x99c409e5f62e4bd2ac142f17cafb6810b8f0baae', - '_scan': 'https://arbiscan.io/token/0x99c409e5f62e4bd2ac142f17cafb6810b8f0baae', - 'decimals': 18, - 'name': 'Beefy.Finance', - 'symbol': 'BIFI', - 'logoURI': 'https://raw.githubusercontent.com/KyberNetwork/ks-assets/main/img/token/BIFI.png', - }, - { - 'chainId': 42161, - 'address': '0x68ead55c258d6fa5e46d67fc90f53211eab885be', - '_scan': 'https://arbiscan.io/token/0x68ead55c258d6fa5e46d67fc90f53211eab885be', - 'decimals': 18, - 'name': 'Popcorn', - 'symbol': 'POP', - 'logoURI': 'https://raw.githubusercontent.com/KyberNetwork/ks-assets/main/img/token/POP.png', - }, - { - 'chainId': 42161, - 'address': '0xd74f5255d557944cf7dd0e45ff521520002d5748', - '_scan': 'https://arbiscan.io/token/0xd74f5255d557944cf7dd0e45ff521520002d5748', - 'decimals': 18, - 'name': 'Sperax USD', - 'symbol': 'USDS', - 'logoURI': 'https://raw.githubusercontent.com/KyberNetwork/ks-assets/main/img/token/USDS.svg', - }, - { - 'chainId': 42161, - 'address': '0xee9801669c6138e84bd50deb500827b776777d28', - '_scan': 'https://arbiscan.io/token/0xee9801669c6138e84bd50deb500827b776777d28', - 'decimals': 18, - 'name': 'O3 Swap', - 'symbol': 'O3', - 'logoURI': 'https://raw.githubusercontent.com/KyberNetwork/ks-assets/main/img/token/O3.png', - }, - { - 'chainId': 42161, - 'address': '0x21e60ee73f17ac0a411ae5d690f908c3ed66fe12', - '_scan': 'https://arbiscan.io/token/0x21e60ee73f17ac0a411ae5d690f908c3ed66fe12', - 'decimals': 18, - 'name': 'Deri Protocol', - 'symbol': 'DERI', - 'logoURI': 'https://raw.githubusercontent.com/KyberNetwork/ks-assets/main/img/token/DERI.svg', - }, - { - 'chainId': 42161, - 'address': '0xfc5A1A6EB076a2C7aD06eD22C90d7E710E35ad0a', - '_scan': 'https://arbiscan.io/token/0xfc5A1A6EB076a2C7aD06eD22C90d7E710E35ad0a', - 'decimals': 18, - 'name': 'GMX', - 'symbol': 'GMX', - 'logoURI': 'https://raw.githubusercontent.com/KyberNetwork/ks-assets/main/img/token/GMX.svg', - }, - ], - 'version': { - 'major': 1, - 'minor': 0, - 'patch': 1, - }, - } \ No newline at end of file + AES_SALT = '3990611c-f057-4c25-bde6-4fe932161a5d', + BIG_JSON = { + 'name': 'KyberSwap Token List Arbitrum', + 'keywords': ['dmmexchange', 'kyberswap'], + 'timestamp': '2022-06-20T00:00:00+00:00', + 'logoURI': 'https://kyberswap.com/favicon.png', + 'tokens': [ + { + 'chainId': 42161, + 'address': '0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8', + '_scan': 'https://arbiscan.io/token/0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8', + 'symbol': 'USDC', + 'name': 'USDC', + 'decimals': 6, + 'logoURI': 'https://assets.coingecko.com/coins/images/6319/large/USD_Coin_icon.png', + }, + { + 'chainId': 42161, + 'address': '0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9', + '_scan': 'https://arbiscan.io/token/0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9', + 'symbol': 'USDT', + 'name': 'USDT', + 'decimals': 6, + 'logoURI': 'https://coin.top/production/logo/usdtlogo.png', + }, + { + 'chainId': 42161, + 'address': '0xda10009cbd5d07dd0cecc66161fc93d7c9000da1', + '_scan': 'https://arbiscan.io/token/0xda10009cbd5d07dd0cecc66161fc93d7c9000da1', + 'symbol': 'DAI', + 'name': 'DAI', + 'decimals': 18, + 'logoURI': 'https://assets.coingecko.com/coins/images/9956/large/dai-multi-collateral-mcd.png', + }, + { + 'chainId': 42161, + 'address': '0x82af49447d8a07e3bd95bd0d56f35241523fbab1', + '_scan': 'https://arbiscan.io/token/0x82af49447d8a07e3bd95bd0d56f35241523fbab1', + 'symbol': 'WETH', + 'name': 'Wrapped Ether', + 'decimals': 18, + 'logoURI': 'https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2/logo.png', + }, + { + 'chainId': 42161, + 'address': '0x2f2a2543b76a4166549f7aab2e75bef0aefc5b0f', + '_scan': 'https://arbiscan.io/token/0x2f2a2543b76a4166549f7aab2e75bef0aefc5b0f', + 'symbol': 'WBTC', + 'name': 'WBTC', + 'decimals': 8, + 'logoURI': 'https://assets.coingecko.com/coins/images/7598/large/wrapped_bitcoin_wbtc.png', + }, + { + 'chainId': 42161, + 'address': '0xFEa7a6a0B346362BF88A9e4A88416B77a57D6c2A', + '_scan': 'https://arbiscan.io/token/0xFEa7a6a0B346362BF88A9e4A88416B77a57D6c2A', + 'symbol': 'MIM', + 'name': 'Magic Internet Money', + 'decimals': 18, + 'logoURI': 'https://s2.coinmarketcap.com/static/img/coins/64x64/162.png', + }, + { + 'chainId': 42161, + 'address': '0x3F56e0c36d275367b8C502090EDF38289b3dEa0d', + '_scan': 'https://arbiscan.io/token/0x3F56e0c36d275367b8C502090EDF38289b3dEa0d', + 'decimals': 18, + 'name': 'MAI', + 'symbol': 'MAI', + 'logoURI': 'https://raw.githubusercontent.com/KyberNetwork/ks-assets/main/img/token/MAI.svg', + }, + { + 'chainId': 42161, + 'address': '0x9d2f299715d94d8a7e6f5eaa8e654e8c74a988a7', + '_scan': 'https://arbiscan.io/token/0x9d2f299715d94d8a7e6f5eaa8e654e8c74a988a7', + 'decimals': 18, + 'name': 'Frax Share', + 'symbol': 'FXS', + 'logoURI': 'https://raw.githubusercontent.com/KyberNetwork/ks-assets/main/img/token/FXS.svg', + }, + { + 'chainId': 42161, + 'address': '0x080f6aed32fc474dd5717105dba5ea57268f46eb', + '_scan': 'https://arbiscan.io/token/0x080f6aed32fc474dd5717105dba5ea57268f46eb', + 'decimals': 18, + 'name': 'Synapse', + 'symbol': 'SYN', + 'logoURI': 'https://raw.githubusercontent.com/KyberNetwork/ks-assets/main/img/token/SYN.svg', + }, + { + 'chainId': 42161, + 'address': '0x319f865b287fcc10b30d8ce6144e8b6d1b476999', + '_scan': 'https://arbiscan.io/token/0x319f865b287fcc10b30d8ce6144e8b6d1b476999', + 'decimals': 18, + 'name': 'Cartesi', + 'symbol': 'CTSI', + 'logoURI': 'https://raw.githubusercontent.com/KyberNetwork/ks-assets/main/img/token/CTSI.png', + }, + { + 'chainId': 42161, + 'address': '0x9fb9a33956351cf4fa040f65a13b835a3c8764e3', + '_scan': 'https://arbiscan.io/token/0x9fb9a33956351cf4fa040f65a13b835a3c8764e3', + 'decimals': 18, + 'name': 'Multchain', + 'symbol': 'MULTI', + 'logoURI': 'https://raw.githubusercontent.com/KyberNetwork/ks-assets/main/img/token/MULTI.png', + }, + { + 'chainId': 42161, + 'address': '0x6694340fc020c5e6b96567843da2df01b2ce1eb6', + '_scan': 'https://arbiscan.io/token/0x6694340fc020c5e6b96567843da2df01b2ce1eb6', + 'decimals': 18, + 'name': 'Stargate Finance', + 'symbol': 'STG', + 'logoURI': 'https://raw.githubusercontent.com/KyberNetwork/ks-assets/main/img/token/STG.svg', + }, + { + 'chainId': 42161, + 'address': '0x99c409e5f62e4bd2ac142f17cafb6810b8f0baae', + '_scan': 'https://arbiscan.io/token/0x99c409e5f62e4bd2ac142f17cafb6810b8f0baae', + 'decimals': 18, + 'name': 'Beefy.Finance', + 'symbol': 'BIFI', + 'logoURI': 'https://raw.githubusercontent.com/KyberNetwork/ks-assets/main/img/token/BIFI.png', + }, + { + 'chainId': 42161, + 'address': '0x68ead55c258d6fa5e46d67fc90f53211eab885be', + '_scan': 'https://arbiscan.io/token/0x68ead55c258d6fa5e46d67fc90f53211eab885be', + 'decimals': 18, + 'name': 'Popcorn', + 'symbol': 'POP', + 'logoURI': 'https://raw.githubusercontent.com/KyberNetwork/ks-assets/main/img/token/POP.png', + }, + { + 'chainId': 42161, + 'address': '0xd74f5255d557944cf7dd0e45ff521520002d5748', + '_scan': 'https://arbiscan.io/token/0xd74f5255d557944cf7dd0e45ff521520002d5748', + 'decimals': 18, + 'name': 'Sperax USD', + 'symbol': 'USDS', + 'logoURI': 'https://raw.githubusercontent.com/KyberNetwork/ks-assets/main/img/token/USDS.svg', + }, + { + 'chainId': 42161, + 'address': '0xee9801669c6138e84bd50deb500827b776777d28', + '_scan': 'https://arbiscan.io/token/0xee9801669c6138e84bd50deb500827b776777d28', + 'decimals': 18, + 'name': 'O3 Swap', + 'symbol': 'O3', + 'logoURI': 'https://raw.githubusercontent.com/KyberNetwork/ks-assets/main/img/token/O3.png', + }, + { + 'chainId': 42161, + 'address': '0x21e60ee73f17ac0a411ae5d690f908c3ed66fe12', + '_scan': 'https://arbiscan.io/token/0x21e60ee73f17ac0a411ae5d690f908c3ed66fe12', + 'decimals': 18, + 'name': 'Deri Protocol', + 'symbol': 'DERI', + 'logoURI': 'https://raw.githubusercontent.com/KyberNetwork/ks-assets/main/img/token/DERI.svg', + }, + { + 'chainId': 42161, + 'address': '0xfc5A1A6EB076a2C7aD06eD22C90d7E710E35ad0a', + '_scan': 'https://arbiscan.io/token/0xfc5A1A6EB076a2C7aD06eD22C90d7E710E35ad0a', + 'decimals': 18, + 'name': 'GMX', + 'symbol': 'GMX', + 'logoURI': 'https://raw.githubusercontent.com/KyberNetwork/ks-assets/main/img/token/GMX.svg', + }, + ], + 'version': { + 'major': 1, + 'minor': 0, + 'patch': 1, + }, + } \ No newline at end of file diff --git a/packages/keysmith/test/me3.test.ts b/packages/keysmith/test/me3.test.ts index 615e964..de90b7f 100644 --- a/packages/keysmith/test/me3.test.ts +++ b/packages/keysmith/test/me3.test.ts @@ -7,7 +7,7 @@ import sinon from 'sinon' import Me3 from '../src' import { CONFIG, REDIRECTED, workableConfig } from './fixtures/configs' -import { v2, aes } from '../src/safe' +import { v2, aes } from '../src/safeV2' import { mockGetChainListResponse } from './fixtures/me3-get-chain-list' import axios from 'axios' diff --git a/packages/keysmith/test/safe.test.ts b/packages/keysmith/test/safe.test.ts index 5d68f4a..75d89db 100644 --- a/packages/keysmith/test/safe.test.ts +++ b/packages/keysmith/test/safe.test.ts @@ -1,9 +1,9 @@ import chai from 'chai' import { describe } from 'mocha' -import { aes, v1, v2 } from '../src/safe' -import * as rsa from '../src/safe/rsa' -import * as chacha from '../src/safe/chacha' +import { aes, v1, v2 } from '../src/safeV2' +import * as rsa from '../src/safeV2/rsa' +import * as chacha from '../src/safeV2/chacha' import { ALICE, RAWKEY } from './fixtures/configs' import chaiAsPromised from 'chai-as-promised' @@ -43,17 +43,16 @@ describe('Safe testing', () => { expect(key).to.be.ok const plain = 'Hello World' - const encoded = rsa.encrypt(key.publicKey, Buffer.from(plain, 'utf8')) - expect(rsa.decrypt(key.privateKey, encoded).toString('utf8')).to.deep.equal(plain) + const encoded = rsa.encrypt(key.publicKey, plain) + expect(rsa.decrypt(key.privateKey, encoded)).to.deep.equal(plain) }) it('Chacha testing', () => { - const chachaKey = chacha.genPassword() const plainText = 'Hello world' - const encrypted = chacha.encrypt(chachaKey, Buffer.from(plainText, 'utf8')) - const decrypted = chacha.decrypt(chachaKey, encrypted) - expect(decrypted.toString('utf8')).to.deep.equal(plainText) + const { keyBytes, b64DataBytes } = chacha.encrypt(plainText) + const decrypted = chacha.decrypt(keyBytes, b64DataBytes) + expect(decrypted).to.deep.equal(plainText) }) it('Enc/Dec testing', async function () { const rsaKey = await rsa.genKeyPair(), diff --git a/packages/keysmith/test/transaction/perform-sign-transaction.test.ts b/packages/keysmith/test/transaction/perform-sign-transaction.test.ts deleted file mode 100644 index 9202ae8..0000000 --- a/packages/keysmith/test/transaction/perform-sign-transaction.test.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { utils } from 'ethers' -import chai from 'chai' -import chaiAsPromised from 'chai-as-promised' -import { describe } from 'mocha' - -import { performSignEvmTransaction } from '../../src/transaction/perform-sign-transaction' - -chai.use(chaiAsPromised) -const { expect } = chai - -describe('performSignEvmTransaction unit test', () => { - it('Should throw when provided invalid privateKey', async () => { - const privateKey = 'invalid-priKey' - const tx = { - to: '0x8ba1f109551bD432803012645Ac136ddd64DBA72', - value: utils.parseEther('1.0'), - } - - await expect(performSignEvmTransaction(privateKey, tx)).to.eventually.be.rejectedWith('Invalid privateKey provided') - }) - - it('Should return signed tx when provided a valid privateKey and tx', async () => { - // Examples derived from https://docs.ethers.org/v5/api/signer/#Wallet - const privateKey = '0x1da6847600b0ee25e9ad9a52abbd786dd2502fa4005dd5af9310b7cc7a3b25db' - const tx = { - to: '0x8ba1f109551bD432803012645Ac136ddd64DBA72', - value: utils.parseEther('1.0'), - } - - const signed = await performSignEvmTransaction(privateKey, tx) - - expect(signed).to.deep.equal('0xf865808080948ba1f109551bd432803012645ac136ddd64dba72880de0b6b3a7640000801ca0918e294306d177ab7bd664f5e141436563854ebe0a3e523b9690b4922bbb52b8a01181612cec9c431c4257a79b8c9f0c980a2c49bb5a0e6ac52949163eeb565dfc') - }) -}) \ No newline at end of file diff --git a/packages/keysmith/test/transaction/transaction.test.ts b/packages/keysmith/test/transaction/transaction.test.ts deleted file mode 100644 index 722ca71..0000000 --- a/packages/keysmith/test/transaction/transaction.test.ts +++ /dev/null @@ -1,51 +0,0 @@ -import chai from 'chai' -import chaiAsPromised from 'chai-as-promised' -import { describe } from 'mocha' - -import { signTransaction } from '../../src/transaction' -import { utils } from 'ethers' - -chai.use(chaiAsPromised) -const { expect } = chai - -// valid reusable fixtures -const privateKey = '0x1da6847600b0ee25e9ad9a52abbd786dd2502fa4005dd5af9310b7cc7a3b25db' -const tx = { - to: '0x8ba1f109551bD432803012645Ac136ddd64DBA72', - value: utils.parseEther('1.0'), -} - -describe('signTransaction unit test', () => { - it('Should throw when provided unsupported series', async () => { - const invalidSeries = 'zil' - - await expect( - signTransaction({ - series: invalidSeries, - privateKey, - transactionRequest: tx, - })).to.eventually.be.rejectedWith('Unsupported series') - }); - - ['btc', 'ltc', 'fil', 'dot', 'bch'].forEach((series) => { - it(`Should throw when provided series that is not implemented yet - series=${series}`, async () => { - await expect( - signTransaction({ - series, - privateKey, - transactionRequest: {}, - }) - ).to.eventually.be.rejectedWith('Not implemented yet') - }) - }) - - it('Should return signed transaction when provided an evm (eth) series, valid privateKey and tx', async () => { - const signedTx = await signTransaction({ - series: 'eth', - privateKey, - transactionRequest: tx, - }) - - expect(signedTx).to.deep.equal('0xf865808080948ba1f109551bd432803012645ac136ddd64dba72880de0b6b3a7640000801ca0918e294306d177ab7bd664f5e141436563854ebe0a3e523b9690b4922bbb52b8a01181612cec9c431c4257a79b8c9f0c980a2c49bb5a0e6ac52949163eeb565dfc') - }) -}) \ No newline at end of file diff --git a/packages/keysmith/test/wallet/create-wallet-filecoin.test.ts b/packages/keysmith/test/wallet/create-wallet-filecoin.test.ts deleted file mode 100644 index 6da5a96..0000000 --- a/packages/keysmith/test/wallet/create-wallet-filecoin.test.ts +++ /dev/null @@ -1,32 +0,0 @@ -import * as chai from 'chai' -import chaiAsPromised from 'chai-as-promised' -import { describe } from 'mocha' - -import { createFileCoinWallet } from '../../src/wallet/create-wallet/filecoin' - -chai.use(chaiAsPromised) -const { expect } = chai - -describe('createWallet - filecoin', () => { - const mnemonic = 'equip will roof matter pink blind book anxiety banner elbow sun young' - - it('Should return walletAddress and secretRaw when provided mnemonic', async () => { - - // @zondax/filecoin-signing-tools - const newLib = createFileCoinWallet([ - { - series: 'fil', - name: 'FIL', - walletName: 'TestWallet', - }, - ], mnemonic) - console.info('output >', newLib) - - expect(newLib).to.deep.equal([{ - chainName: 'FIL', - walletName: 'TestWallet', - secretRaw: 'QNRGtRs1VdeqlXs8btpxrmEtzKOYybtfTcqqsigfBsA=', - walletAddress: 'f1trmstlgfyfpo6ineunloaeygjzpcfvq2dvbqtzi', - }]) - }) -}) \ No newline at end of file diff --git a/packages/sample/app.ts b/packages/sample/app.ts index 9c8cf06..f328934 100644 --- a/packages/sample/app.ts +++ b/packages/sample/app.ts @@ -59,6 +59,9 @@ app.get('/wallets', async function (req, res) { }) app.post('/signTx', bodyParser.json(), async (req: Request, res: Response) => { + if (!me3.isInitialized()) { + return res.json({ error: 'Oops, ERROR!', msg: 'Me3 still did not initialized!' }) + } if (_.isEmpty(wallets)) { return res.json({ error: 'Oops, ERROR!', msg: 'No wallets loaded' }) } @@ -74,5 +77,4 @@ app.post('/signTx', bodyParser.json(), async (req: Request, res: Response) => { } catch (e) { return res.json({ error: 'Oops, ERROR!', msg: e.message }) } -} -) +}) diff --git a/yarn.lock b/yarn.lock index f072baf..9772d4e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -257,6 +257,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.19.0" +"@babel/runtime@^7.12.5", "@babel/runtime@^7.17.2": + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.0.tgz#5b55c9d394e5fcf304909a8b00c07dc217b56673" + integrity sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw== + dependencies: + regenerator-runtime "^0.13.11" + "@babel/runtime@^7.20.6", "@babel/runtime@^7.20.7": version "7.20.13" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.13.tgz#7055ab8a7cff2b8f6058bf6ae45ff84ad2aded4b" @@ -1651,6 +1658,11 @@ npmlog "^6.0.2" write-file-atomic "^4.0.1" +"@noble/ed25519@^1.7.0": + version "1.7.3" + resolved "https://registry.yarnpkg.com/@noble/ed25519/-/ed25519-1.7.3.tgz#57e1677bf6885354b466c38e2b620c62f45a7123" + integrity sha512-iR8GBkDt0Q3GyaVcIu7mSsVIqnFbkbRzGLWlvhwunacoLwt4J3swfKhfaM6rN6WY+TBGoYT1GtT1mIh2/jGbRQ== + "@noble/hashes@1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.2.tgz#e9e035b9b166ca0af657a7848eb2718f0f22f183" @@ -1661,7 +1673,12 @@ resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.5.tgz#1a0377f3b9020efe2fae03290bd2a12140c95c11" integrity sha512-LTMZiiLc+V4v1Yi16TD6aX2gmtKszNye0pQgbaLqkvhIqP7nVsSaJsWloGQjJfJ8offaoP5GtX3yY5swbcJxxQ== -"@noble/secp256k1@1.7.1": +"@noble/hashes@^1.1.2": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.0.tgz#085fd70f6d7d9d109671090ccae1d3bec62554a1" + integrity sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg== + +"@noble/secp256k1@1.7.1", "@noble/secp256k1@^1.6.3": version "1.7.1" resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.1.tgz#b251c70f824ce3ca7f8dc3df08d58f005cc0507c" integrity sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw== @@ -2157,6 +2174,35 @@ resolved "https://registry.yarnpkg.com/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz#5981a8db18b56ba38ef0efb7d995b12aa7b51918" integrity sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ== +"@solana/buffer-layout@^4.0.0": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@solana/buffer-layout/-/buffer-layout-4.0.1.tgz#b996235eaec15b1e0b5092a8ed6028df77fa6c15" + integrity sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA== + dependencies: + buffer "~6.0.3" + +"@solana/web3.js@^1.74.0": + version "1.74.0" + resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.74.0.tgz#dbcbeabb830dd7cbbcf5e31404ca79c9785cbf2d" + integrity sha512-RKZyPqizPCxmpMGfpu4fuplNZEWCrhRBjjVstv5QnAJvgln1jgOfgui+rjl1ExnqDnWKg9uaZ5jtGROH/cwabg== + dependencies: + "@babel/runtime" "^7.12.5" + "@noble/ed25519" "^1.7.0" + "@noble/hashes" "^1.1.2" + "@noble/secp256k1" "^1.6.3" + "@solana/buffer-layout" "^4.0.0" + agentkeepalive "^4.2.1" + bigint-buffer "^1.1.5" + bn.js "^5.0.0" + borsh "^0.7.0" + bs58 "^4.0.1" + buffer "6.0.1" + fast-stable-stringify "^1.0.0" + jayson "^3.4.4" + node-fetch "^2.6.7" + rpc-websockets "^7.5.1" + superstruct "^0.14.2" + "@stablelib/aead@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@stablelib/aead/-/aead-1.0.1.tgz#c4b1106df9c23d1b867eb9b276d8f42d5fc4c0c3" @@ -2312,7 +2358,7 @@ resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.4.tgz#e913e8175db8307d78b4e8fa690408ba6b65dee4" integrity sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw== -"@types/connect@*": +"@types/connect@*", "@types/connect@^3.4.33": version "3.4.35" resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== @@ -2417,6 +2463,11 @@ resolved "https://registry.npmjs.org/@types/node/-/node-11.11.6.tgz" integrity sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ== +"@types/node@^12.12.54": + version "12.20.55" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240" + integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ== + "@types/normalize-package-data@^2.4.0": version "2.4.1" resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301" @@ -2472,6 +2523,13 @@ resolved "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz" integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== +"@types/ws@^7.4.4": + version "7.4.7" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" + integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww== + dependencies: + "@types/node" "*" + "@types/yargs-parser@*": version "21.0.0" resolved "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz" @@ -2604,7 +2662,7 @@ secp256k1 "^4.0.3" tiny-secp256k1 "^2.2.1" -JSONStream@^1.0.4: +JSONStream@^1.0.4, JSONStream@^1.3.5: version "1.3.5" resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== @@ -3017,6 +3075,13 @@ bigi@^1.1.0, bigi@^1.4.2: resolved "https://registry.npmjs.org/bigi/-/bigi-1.4.2.tgz" integrity sha512-ddkU+dFIuEIW8lE7ZwdIAf2UPoM90eaprg5m3YXAVVTmKlqV/9BX4A2M8BOK2yOq6/VgZFVhK6QAxJebhlbhzw== +bigint-buffer@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/bigint-buffer/-/bigint-buffer-1.1.5.tgz#d038f31c8e4534c1f8d0015209bf34b4fa6dd442" + integrity sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA== + dependencies: + bindings "^1.3.0" + bignumber.js@^9.0.0: version "9.1.1" resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.1.tgz#c4df7dc496bd849d4c9464344c1aa74228b4dac6" @@ -3039,6 +3104,13 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== +bindings@^1.3.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + bip-schnorr@=0.6.4: version "0.6.4" resolved "https://registry.npmjs.org/bip-schnorr/-/bip-schnorr-0.6.4.tgz" @@ -3137,7 +3209,7 @@ bn.js@^4.11.9: resolved "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz" integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== -bn.js@^5.0.0, bn.js@^5.2.1: +bn.js@^5.0.0, bn.js@^5.2.0, bn.js@^5.2.1: version "5.2.1" resolved "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz" integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== @@ -3160,6 +3232,15 @@ body-parser@1.20.1, body-parser@^1.20.1: type-is "~1.6.18" unpipe "1.0.0" +borsh@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/borsh/-/borsh-0.7.0.tgz#6e9560d719d86d90dc589bca60ffc8a6c51fec2a" + integrity sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA== + dependencies: + bn.js "^5.2.0" + bs58 "^4.0.0" + text-encoding-utf-8 "^1.0.2" + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" @@ -3254,6 +3335,14 @@ buffer-pipe@0.0.3: dependencies: safe-buffer "^5.1.2" +buffer@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.1.tgz#3cbea8c1463e5a0779e30b66d4c88c6ffa182ac2" + integrity sha512-rVAXBwEcEoYtxnHSO5iWyhzV/O1WMtkUYWlfdLS7FjU4PnSJJHEfHXi/uHPI5EwltmOA794gN3bm3/pzuctWjQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + buffer@^5.5.0: version "5.7.1" resolved "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz" @@ -3262,6 +3351,21 @@ buffer@^5.5.0: base64-js "^1.3.1" ieee754 "^1.1.13" +buffer@~6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + +bufferutil@^4.0.1: + version "4.0.7" + resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.7.tgz#60c0d19ba2c992dd8273d3f73772ffc894c153ad" + integrity sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw== + dependencies: + node-gyp-build "^4.3.0" + builtins@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" @@ -3591,6 +3695,11 @@ combined-stream@^1.0.8: dependencies: delayed-stream "~1.0.0" +commander@^2.20.3: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + common-ancestor-path@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz#4f7d2d1394d91b7abdf51871c62f71eadb0182a7" @@ -3902,6 +4011,11 @@ define-properties@^1.1.3, define-properties@^1.1.4: has-property-descriptors "^1.0.0" object-keys "^1.1.1" +delay@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/delay/-/delay-5.0.0.tgz#137045ef1b96e5071060dd5be60bf9334436bd1d" + integrity sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw== + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" @@ -4204,6 +4318,18 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" +es6-promise@^4.0.3: + version "4.2.8" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" + integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== + +es6-promisify@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" + integrity sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ== + dependencies: + es6-promise "^4.0.3" + escalade@^3.1.1: version "3.1.1" resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" @@ -4487,7 +4613,7 @@ ethers@^6.0.8: tslib "2.4.0" ws "8.5.0" -eventemitter3@^4.0.4: +eventemitter3@^4.0.4, eventemitter3@^4.0.7: version "4.0.7" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== @@ -4579,6 +4705,11 @@ external-editor@^3.0.3: iconv-lite "^0.4.24" tmp "^0.0.33" +eyes@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0" + integrity sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ== + fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" @@ -4616,6 +4747,11 @@ fast-levenshtein@^2.0.6: resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== +fast-stable-stringify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fast-stable-stringify/-/fast-stable-stringify-1.0.0.tgz#5c5543462b22aeeefd36d05b34e51c78cb86d313" + integrity sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag== + fast-text-encoding@^1.0.0: version "1.0.6" resolved "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.6.tgz" @@ -4649,6 +4785,11 @@ file-entry-cache@^6.0.1: dependencies: flat-cache "^3.0.4" +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + filelist@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" @@ -5315,7 +5456,7 @@ iconv-lite@^0.6.2: dependencies: safer-buffer ">= 2.1.2 < 3.0.0" -ieee754@^1.1.13: +ieee754@^1.1.13, ieee754@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== @@ -5707,6 +5848,11 @@ isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== +isomorphic-ws@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" + integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== + istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: version "3.2.0" resolved "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz" @@ -5759,6 +5905,25 @@ jake@^10.8.5: filelist "^1.0.1" minimatch "^3.0.4" +jayson@^3.4.4: + version "3.7.0" + resolved "https://registry.yarnpkg.com/jayson/-/jayson-3.7.0.tgz#b735b12d06d348639ae8230d7a1e2916cb078f25" + integrity sha512-tfy39KJMrrXJ+mFcMpxwBvFDetS8LAID93+rycFglIQM4kl3uNR3W4lBLE/FFhsoUCEox5Dt2adVpDm/XtebbQ== + dependencies: + "@types/connect" "^3.4.33" + "@types/node" "^12.12.54" + "@types/ws" "^7.4.4" + JSONStream "^1.3.5" + commander "^2.20.3" + delay "^5.0.0" + es6-promisify "^5.0.0" + eyes "^0.1.8" + isomorphic-ws "^4.0.1" + json-stringify-safe "^5.0.1" + lodash "^4.17.20" + uuid "^8.3.2" + ws "^7.4.5" + jest-changed-files@^28.1.3: version "28.1.3" resolved "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-28.1.3.tgz" @@ -7890,6 +8055,19 @@ ripemd160@^2.0.0, ripemd160@^2.0.1, ripemd160@^2.0.2: hash-base "^3.0.0" inherits "^2.0.1" +rpc-websockets@^7.5.1: + version "7.5.1" + resolved "https://registry.yarnpkg.com/rpc-websockets/-/rpc-websockets-7.5.1.tgz#e0a05d525a97e7efc31a0617f093a13a2e10c401" + integrity sha512-kGFkeTsmd37pHPMaHIgN1LVKXMi0JD782v4Ds9ZKtLlwdTKjn+CxM9A9/gLT2LaOuEcEFGL98h1QWQtlOIdW0w== + dependencies: + "@babel/runtime" "^7.17.2" + eventemitter3 "^4.0.7" + uuid "^8.3.2" + ws "^8.5.0" + optionalDependencies: + bufferutil "^4.0.1" + utf-8-validate "^5.0.2" + run-async@^2.4.0: version "2.4.1" resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" @@ -8346,6 +8524,11 @@ strong-log-transformer@^2.1.0: minimist "^1.2.0" through "^2.3.4" +superstruct@^0.14.2: + version "0.14.2" + resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-0.14.2.tgz#0dbcdf3d83676588828f1cf5ed35cda02f59025b" + integrity sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ== + supports-color@8.1.1, supports-color@^8.0.0: version "8.1.1" resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" @@ -8435,6 +8618,11 @@ test-exclude@^6.0.0: glob "^7.1.4" minimatch "^3.0.4" +text-encoding-utf-8@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz#585b62197b0ae437e3c7b5d0af27ac1021e10d13" + integrity sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg== + text-extensions@^1.0.0: version "1.9.0" resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.9.0.tgz#1853e45fee39c945ce6f6c36b2d659b5aabc2a26" @@ -8769,6 +8957,13 @@ url-template@^2.0.8: resolved "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz" integrity sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw== +utf-8-validate@^5.0.2: + version "5.0.10" + resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.10.tgz#d7d10ea39318171ca982718b6b96a8d2442571a2" + integrity sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ== + dependencies: + node-gyp-build "^4.3.0" + util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" @@ -9010,6 +9205,16 @@ ws@8.5.0: resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f" integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg== +ws@^7.4.5: + version "7.5.9" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" + integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== + +ws@^8.5.0: + version "8.13.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" + integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== + xtend@~4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"