diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..623774f --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,30 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "chrome", + "request": "launch", + "name": "Launch Chrome against localhost", + "url": "http://localhost:3000", + "webRoot": "${workspaceRoot}/packages/ui/src" + }, + { + "name": "keypering", + "type": "node", + "request": "launch", + "cwd": "${workspaceRoot}/packages/app", + "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron", + "windows": { + "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron.cmd" + }, + "args": ["."], + "outputCapture": "std", + "env": { + "NODE_ENV": "development" + } + } + ] +} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 3694cb9..ff26234 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,27 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [0.1.0-alpha.3](https://github.com/nervosnetwork/keypering/compare/v0.1.0-alpha.2...v0.1.0-alpha.3) (2020-12-11) + + +### Bug Fixes + +* Add devnet support ([4177caa](https://github.com/nervosnetwork/keypering/commit/4177caa7bdde7fc5cc46324b6c1346538ec70eb8)) +* Fix variable has already been declared ([99e8f53](https://github.com/nervosnetwork/keypering/commit/99e8f53c27ca3dfb185d20237983cf4ec248f671)) +* remove cell deps leave null dialog ([bc4fc03](https://github.com/nervosnetwork/keypering/commit/bc4fc033855f98448f89b7ec8d257143f14fb165)) +* update indexer_url const ([2124eee](https://github.com/nervosnetwork/keypering/commit/2124eee577c5a4562ceed05390bcd80edd91df7f)) +* Use blake2b encrypt message ([1be4e29](https://github.com/nervosnetwork/keypering/commit/1be4e29e872a89d6782c702fcbb93ada45909077)) + + +### Features + +* add sign message rpc interface ([599d378](https://github.com/nervosnetwork/keypering/commit/599d378eec67c97475b8b31eba571139b43dc8b8)) +* support vscode debug ([e631353](https://github.com/nervosnetwork/keypering/commit/e6313535df81340e0dc8fad1d224efa8b109248e)) + + + + + # [0.1.0-alpha.2](https://github.com/nervosnetwork/keypering/compare/v0.1.0-alpha.1...v0.1.0-alpha.2) (2020-09-28) diff --git a/README.md b/README.md index 2e7aa32..daec1b1 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,15 @@ Keypering consists of 3 components: - [How to Develop a CKB DApp with Keypering (Video, Chinese + English Subtitles)](https://youtu.be/i-gQ0enK5cY) - [How to Develop a CKB DApp with Keypering (Slides)](https://docs.google.com/presentation/d/1bswEhjSYwZZnUCF4rRL5x5vfOVXO_kDlbjsojsG94w8/edit?usp=sharing) +# Develop in devnet + +1. Clone [perkins-tent](https://github.com/xxuejie/perkins-tent) +2. Run `docker run -e CKB_NETWORK=dev --rm -p 8114:9115 -v ~/.ckb-docker-devnet:/data xxuejie/perkins-tent` +3. Go to `~/.ckb-docker-devnet/confs/nginx.conf` change `location = /indexer_rpc` to `location = /indexer` +4. Open keypering setting page then click Rich Node RPC setting icon, set `http://localhost:8114/indexer` in devent input +5. Finish! +6. If you want to run a miner, append ` miner: ckb miner -C /data/ckb-data` to `~/.ckb-docker-devnet/confs/Procfile` + # Resources - [Keypering Manual](https://nervosnetwork.github.io/keypering/#/manual) - User Guide of Keypering diff --git a/docs/_media/screenshots/24.sign_message_rpc.png b/docs/_media/screenshots/24.sign_message_rpc.png new file mode 100644 index 0000000..fb87c90 Binary files /dev/null and b/docs/_media/screenshots/24.sign_message_rpc.png differ diff --git a/docs/_media/screenshots/25.check_signed_message.png b/docs/_media/screenshots/25.check_signed_message.png new file mode 100644 index 0000000..7af820e Binary files /dev/null and b/docs/_media/screenshots/25.check_signed_message.png differ diff --git a/docs/manual.md b/docs/manual.md index 1c86939..0de2d09 100644 --- a/docs/manual.md +++ b/docs/manual.md @@ -196,6 +196,20 @@ DApp can send JSON RPC conforming to [Keypering Agency Protocal](/protocol) to i --- +### Sign Message from DApp + +
+ Sign Message + Sign Message from DApp +
+ +
+ Check Signed Message from DApp + Check Signed Message from DApp +
+ +--- + ## Setting ![Sidebar](_media/screenshots/22.sidebar.png) diff --git a/lerna.json b/lerna.json index 031b095..56ba218 100644 --- a/lerna.json +++ b/lerna.json @@ -4,5 +4,5 @@ ], "npmClient": "yarn", "useWorkspaces": true, - "version": "0.1.0-alpha.2" + "version": "0.1.0-alpha.3" } diff --git a/packages/app/CHANGELOG.md b/packages/app/CHANGELOG.md index 84d2f5d..2a0a231 100644 --- a/packages/app/CHANGELOG.md +++ b/packages/app/CHANGELOG.md @@ -3,6 +3,26 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [0.1.0-alpha.3](https://github.com/nervosnetwork/keypering/compare/v0.1.0-alpha.2...v0.1.0-alpha.3) (2020-12-11) + + +### Bug Fixes + +* Add devnet support ([4177caa](https://github.com/nervosnetwork/keypering/commit/4177caa7bdde7fc5cc46324b6c1346538ec70eb8)) +* Fix variable has already been declared ([99e8f53](https://github.com/nervosnetwork/keypering/commit/99e8f53c27ca3dfb185d20237983cf4ec248f671)) +* remove cell deps leave null dialog ([bc4fc03](https://github.com/nervosnetwork/keypering/commit/bc4fc033855f98448f89b7ec8d257143f14fb165)) +* update indexer_url const ([2124eee](https://github.com/nervosnetwork/keypering/commit/2124eee577c5a4562ceed05390bcd80edd91df7f)) +* Use blake2b encrypt message ([1be4e29](https://github.com/nervosnetwork/keypering/commit/1be4e29e872a89d6782c702fcbb93ada45909077)) + + +### Features + +* add sign message rpc interface ([599d378](https://github.com/nervosnetwork/keypering/commit/599d378eec67c97475b8b31eba571139b43dc8b8)) + + + + + # [0.1.0-alpha.2](https://github.com/nervosnetwork/keypering/compare/v0.1.0-alpha.1...v0.1.0-alpha.2) (2020-09-28) diff --git a/packages/app/__tests__/keyper/sign.ts b/packages/app/__tests__/keyper/sign.ts new file mode 100644 index 0000000..3c4fc72 --- /dev/null +++ b/packages/app/__tests__/keyper/sign.ts @@ -0,0 +1,14 @@ +import { signMsg } from '../../src/keyper/sign' + +describe("Test signMsg", () => { + const info = { + sk: '0xe79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3', + message: 'HelloWorld', + signture: '0x97ed8c48879eed50743532bf7cc53e641c501509d2be19d06e6496dd944a21b4509136f18c8e139cc4002822b2deb5cbaff8e44b8782769af3113ff7fb8bd92700' + } + + it('signMsg', () => { + expect(signMsg(info.sk, info.message)) + .toEqual(info.signture) + }) +}) \ No newline at end of file diff --git a/packages/app/__tests__/utils/transformer/index.ts b/packages/app/__tests__/utils/transformer/index.ts index 5d9acbe..1c8d512 100644 --- a/packages/app/__tests__/utils/transformer/index.ts +++ b/packages/app/__tests__/utils/transformer/index.ts @@ -1,4 +1,4 @@ -import { shannonToCkb } from '../../../src/utils/transformer' +import { shannonToCkb, messageToHex } from '../../../src/utils/transformer' import fixtures from './fixtures.json' describe('Test transformer', () => { @@ -15,5 +15,14 @@ describe('Test transformer', () => { expect(shannonToCkb('1234567890123456789', false, '')).toBe('12345678901.23456789') }) }) -}) + describe('Test messageToHex', () => { + it('returns correct length hex', () => { + expect(messageToHex('helloCKB')).toBe('0x68656c6c6f434b42000000000000000000000000000000000000000000000000') + }) + + it('throws error', () => { + expect( () => { messageToHex("I am a string and I will longer than 32bytes") }).toThrow('Message length greater than 32 bytes') + }) + }) +}) diff --git a/packages/app/package.json b/packages/app/package.json index eec57dd..1b9773e 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "@keypering/app", - "version": "0.1.0-alpha.2", + "version": "0.1.0-alpha.3", "description": "", "author": "Keith ", "homepage": "https://nervosnetwork.github.io/keypering", @@ -32,7 +32,7 @@ "url": "https://github.com/nervosnetwork/keypering/issues" }, "devDependencies": { - "@keypering/specs": "0.1.0-alpha.2", + "@keypering/specs": "0.1.0-alpha.3", "@types/elliptic": "6.4.12", "@types/uuid": "8.0.1", "electron": "9.2.0", diff --git a/packages/app/public/dialogs/signMessage.html b/packages/app/public/dialogs/signMessage.html new file mode 100644 index 0000000..0616556 --- /dev/null +++ b/packages/app/public/dialogs/signMessage.html @@ -0,0 +1,139 @@ + + + + + + + + Signing + + + + +
+

Message Confirmation

+
Message: ...
+
Address: ...
+ +
+ + + + diff --git a/packages/app/src/keyper/sign.ts b/packages/app/src/keyper/sign.ts index ab5f542..804bbb7 100644 --- a/packages/app/src/keyper/sign.ts +++ b/packages/app/src/keyper/sign.ts @@ -3,8 +3,9 @@ import { Container } from '@nervosnetwork/keyper-container' import { SignatureAlgorithm } from '@nervosnetwork/keyper-specs' import ECPair from '@nervosnetwork/ckb-sdk-utils/lib/ecpair' import { getSetting } from '../setting' +import Blake2b from "../models/blake2b" -const sign = (sk: string, params: Omit) => { +export const signTx = (sk: string, params: Omit) => { const container = new Container([ { @@ -35,4 +36,17 @@ const sign = (sk: string, params: Omit { + const digest = signtureHash(message) + const ecPair = new ECPair(sk) + const signature = ecPair.signRecoverable(digest) + return signature +} + +const signtureHash = (message: string) => { + const magicString = 'Nervos Message:' + const buffer = Buffer.from(magicString + message, 'utf-8') + const blake2b = new Blake2b() + blake2b.updateBuffer(buffer) + return blake2b.digest() +} diff --git a/packages/app/src/models/blake2b.ts b/packages/app/src/models/blake2b.ts new file mode 100644 index 0000000..65054a6 --- /dev/null +++ b/packages/app/src/models/blake2b.ts @@ -0,0 +1,30 @@ +import { blake2b, PERSONAL, hexToBytes } from '@nervosnetwork/ckb-sdk-utils' + +export default class Blake2b { + private blake2b: any + + constructor() { + this.blake2b = blake2b(32, null, null, PERSONAL) + } + + public update = (message: string): void => { + const msg = message.startsWith('0x') ? + message : + `0x${message}` + this.blake2b.update(hexToBytes(msg)) + } + + public updateBuffer = (message: Buffer): void => { + this.blake2b.update(message) + } + + public digest = (): string => { + return `0x${this.blake2b.digest('hex')}` + } + + public static digest = (message: string): string => { + const blake2bHash = new Blake2b() + blake2bHash.update(message) + return blake2bHash.digest() + } +} \ No newline at end of file diff --git a/packages/app/src/server/controller.ts b/packages/app/src/server/controller.ts index cc190da..b5e8d9b 100644 --- a/packages/app/src/server/controller.ts +++ b/packages/app/src/server/controller.ts @@ -3,7 +3,7 @@ import CKB from '@nervosnetwork/ckb-sdk-core' import { requestAuth } from '../auth' import { getWalletIndex } from '../wallet' import { getAddresses } from '../address' -import { requestSignTx, requestSendTx } from '../tx' +import { requestSignTx, requestSendTx, requestSignMsg } from '../tx' import { getSetting } from '../setting' import { networksToRpcUrl } from '../utils/transformer' @@ -59,3 +59,10 @@ export const handleQueryAddresses = async () => { addresses } } + +export const handleSignMessage = async (params: KeyperingAgency.SignMessage.Params['params']) => { + const sig = await requestSignMsg(params.message, params.address) + return { + sig + } +} diff --git a/packages/app/src/server/routes.ts b/packages/app/src/server/routes.ts index 9445da3..2c2015a 100644 --- a/packages/app/src/server/routes.ts +++ b/packages/app/src/server/routes.ts @@ -1,6 +1,6 @@ import type { IncomingHttpHeaders } from 'http' import { KeyperingAgency } from '@keypering/specs' -import { handleAuth, handleSign, handleSend, handleSignAndSend, handleQueryAddresses } from './controller' +import { handleAuth, handleSign, handleSend, handleSignAndSend, handleQueryAddresses, handleSignMessage } from './controller' import { MethodNotFoundException } from '../exception' import useGuard from './useGuard' @@ -27,6 +27,9 @@ const routes = async (method: KeyperingAgency.Method, params: any, headers: Inco case 'sign_and_send_transaction': { return handleSignAndSend(params, referer || origin) } + case 'sign_message': { + return handleSignMessage(params) + } default: { throw new MethodNotFoundException(method || 'undefined') } diff --git a/packages/app/src/setting/networks.ts b/packages/app/src/setting/networks.ts index c789ad5..6783f9d 100644 --- a/packages/app/src/setting/networks.ts +++ b/packages/app/src/setting/networks.ts @@ -1,5 +1,5 @@ import type { Channel } from '@keypering/specs' -import { MAINNET_ID, TESTNET_ID, DEVNET_ID, RICH_NODE_MAINNET_INDEXER_URL, RICH_NODE_TESTNET_INDEXER_URL } from '../utils' +import { MAINNET_ID, TESTNET_ID, DEVNET_ID, RICH_NODE_MAINNET_INDEXER_URL, RICH_NODE_TESTNET_INDEXER_URL, RICH_NODE_DEVNET_INDEXER_URL } from '../utils' const networks = new Map([ [ MAINNET_ID, @@ -19,7 +19,7 @@ const networks = new Map([ DEVNET_ID, { name: 'devnet', - url: RICH_NODE_TESTNET_INDEXER_URL, + url: RICH_NODE_DEVNET_INDEXER_URL, } ] ]) diff --git a/packages/app/src/setting/scripts.ts b/packages/app/src/setting/scripts.ts index 2dc6cce..1418e36 100644 --- a/packages/app/src/setting/scripts.ts +++ b/packages/app/src/setting/scripts.ts @@ -3,6 +3,7 @@ import { Secp256k1LockScript } from '@nervosnetwork/keyper-container/lib/locks/s import { AnyPayLockScript } from '@nervosnetwork/keyper-container/lib/locks/anyone-can-pay' import { SECP256K1_BLAKE160_CODE_HASH, + SECP256K1_BLAKE160_DEVNET_TX_HASH, SECP256K1_BLAKE160_MAINNET_TX_HASH, SECP256K1_BLAKE160_TESTNET_TX_HASH, ANYONE_CAN_PAY_CODE_HASH, @@ -42,4 +43,16 @@ const testnetScripts: LockScript[] = [ }, ]), ] -export default { mainnetScripts, testnetScripts } + +const devnetScripts: LockScript[] = [ + new Secp256k1LockScript(SECP256K1_BLAKE160_CODE_HASH, 'type', [ + { + outPoint: { + txHash: SECP256K1_BLAKE160_DEVNET_TX_HASH, + index: '0x0', + }, + depType: 'depGroup', + }, + ]) +] +export default { mainnetScripts, testnetScripts, devnetScripts } diff --git a/packages/app/src/setting/service.ts b/packages/app/src/setting/service.ts index 3d75274..25688fc 100644 --- a/packages/app/src/setting/service.ts +++ b/packages/app/src/setting/service.ts @@ -82,11 +82,21 @@ export const getSetting = () => { } }) - const scriptsToShow = setting.networkId === MAINNET_ID - ? systemScripts.mainnetScripts - : setting.networkId === TESTNET_ID - ? systemScripts.testnetScripts - : [] + let scriptsToShow: LockScript[]; + + switch(setting.networkId) { + case MAINNET_ID: + scriptsToShow = systemScripts.mainnetScripts + break; + case TESTNET_ID: + scriptsToShow = systemScripts.testnetScripts + break; + case DEVNET_ID: + scriptsToShow = systemScripts.devnetScripts + break; + default: + scriptsToShow = [] + } scriptsToShow.forEach(script => { locks[getScriptId(script)] = { diff --git a/packages/app/src/tx/SignMessageWindow.ts b/packages/app/src/tx/SignMessageWindow.ts new file mode 100644 index 0000000..3d33b88 --- /dev/null +++ b/packages/app/src/tx/SignMessageWindow.ts @@ -0,0 +1,68 @@ +import path from 'path' +import { BrowserWindow } from 'electron' +import MainWindow from '../MainWindow' + +export default class SignMessageWindow { + #win = new BrowserWindow({ + width: 430, + height: 260, + minWidth: 430, + maxWidth: 430, + maximizable: false, + fullscreenable: false, + autoHideMenuBar: true, + titleBarStyle: 'hidden', + title: 'Signing', + show: false, + frame: false, + parent: MainWindow.id + ? BrowserWindow.fromId(MainWindow.id) + : undefined, + modal: true, + backgroundColor: '#fff', + webPreferences: { + nodeIntegration: false, + preload: path.resolve(__dirname, '..', 'preload.js'), + }, + }) + + get win() { + return this.#win + } + + #filePath = '' + #channel = '' + get channel() { + return this.#channel + } + + constructor(message: string, address: string) { + this.#filePath = path.join('file://', __dirname, '..', '..', 'public', 'dialogs', `signMessage.html?message=${message}&address=${address}`) + this.#channel = `signMsg:${address}` + this.#win.on('ready-to-show', () => { + this.#win.show() + this.#win.webContents.send(this.#channel, { message, address }) + }) + } + + public load = () => { + this.#win.loadURL(this.#filePath) + } + + public close = () => { + this.#win.close() + } + + public response = (): Promise => { + return new Promise((resolve, reject) => { + this.#win.webContents.once('ipc-message', (_e, channel, args: boolean) => { + if (channel === this.#channel && typeof args === 'boolean') { + resolve(args) + } else { + reject(args) + } + }) + this.load() + }) + } +} diff --git a/packages/app/src/tx/service.ts b/packages/app/src/tx/service.ts index b12f177..c3125d6 100644 --- a/packages/app/src/tx/service.ts +++ b/packages/app/src/tx/service.ts @@ -1,11 +1,11 @@ import fs from 'fs' import path from 'path' -import { dialog } from 'electron' import { Channel, KeyperingAgency } from '@keypering/specs' import CKB from '@nervosnetwork/ckb-sdk-core' import RequestWindow from './RequestWindow' +import SignMessageWindow from './SignMessageWindow' import PasswordWindow from '../wallet/PasswordWindow' -import { getWalletIndex, signTransaction, getKeystoreByWalletId } from '../wallet' +import { getWalletIndex, signTransaction, getKeystoreByWalletId, signMessage } from '../wallet' import { getSetting } from '../setting' import { getTxProfile } from './utils' import { getDataPath, networksToRpcUrl } from '../utils' @@ -98,13 +98,6 @@ export const requestSignTx = async (params: { throw new Error('Transaction is not found in parameter') } - if (params.tx?.cellDeps?.length) { - dialog.showMessageBox({ - type: 'warning', - title: 'Warning', - message: 'Please leave cell deps empty since Keypering provides them' - }) - } const dataToConfirm = await getTxProfile(params.tx, params.referer, params.description) const { current } = getWalletIndex() if (!current) { @@ -219,3 +212,42 @@ export const requestSendTx = async (params: { } } +export const requestSignMsg = async ( + message: string, + address: string +) => { + const { current } = getWalletIndex() + if (!current) { + throw new CurrentWalletNotSetException() + } + + try { + const signMessageWindow = new SignMessageWindow(message, address) + const approve = await signMessageWindow.response() + if (!approve) { + throw new RequestRejected() + } + + const pwdWindow = new PasswordWindow("NoRequestId", 'Sign Message') + pwdWindow.win.setParentWindow(signMessageWindow.win) + const passwordRes = await pwdWindow.response() + signMessageWindow.close() + + if (typeof passwordRes === 'string') { + const keystore = getKeystoreByWalletId(current) + const signedMsg = await signMessage({ + keystore, + password: passwordRes, + message + }) + return signedMsg + } + if (passwordRes === false) { + throw new RequestRejected() + } + return false + } catch (err) { + console.error(err) + throw err + } +} \ No newline at end of file diff --git a/packages/app/src/utils/const.ts b/packages/app/src/utils/const.ts index 9874103..99f3e6e 100644 --- a/packages/app/src/utils/const.ts +++ b/packages/app/src/utils/const.ts @@ -9,6 +9,8 @@ export const ANYONE_CAN_PAY_TESTNET_TX_HASH = '0x4f32b3e39bd1b6350d326fdfafdfe05 export const SECP256K1_BLAKE160_CODE_HASH = '0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8' export const SECP256K1_BLAKE160_TESTNET_TX_HASH = '0xf8de3bb47d055cdf460d93a2a6e1b05f7432f9777c8c474abf4eec1d4aee5d37' export const SECP256K1_BLAKE160_MAINNET_TX_HASH = '0x71a7ba8fc96349fea0ed3a5c47992e3b4084b031a42264a018e0072e8172e46c' +export const SECP256K1_BLAKE160_DEVNET_TX_HASH = '0xace5ea83c478bb866edf122ff862085789158f5cbff155b7bb5f13058555b708' -export const RICH_NODE_MAINNET_INDEXER_URL = 'https://prototype.ckbapp.dev/mainnet/indexer' -export const RICH_NODE_TESTNET_INDEXER_URL = 'https://prototype.ckbapp.dev/testnet/indexer' +export const RICH_NODE_MAINNET_INDEXER_URL = 'https://mainnet.ckbapp.dev/indexer' +export const RICH_NODE_TESTNET_INDEXER_URL = 'https://testnet.ckbapp.dev/indexer' +export const RICH_NODE_DEVNET_INDEXER_URL = 'http://localhost:8114/indexer' diff --git a/packages/app/src/utils/transformer.ts b/packages/app/src/utils/transformer.ts index 395debb..84f0811 100644 --- a/packages/app/src/utils/transformer.ts +++ b/packages/app/src/utils/transformer.ts @@ -44,4 +44,15 @@ export const networksToRpcUrl = (params: { networkId: string, networks: Record { + let hexMessage = Buffer.from(message).toString('hex') + // needs 32 bytes length, same as ckb-cli + if (hexMessage.length <= 64){ + hexMessage = hexMessage.padEnd(64, "0") + }else { + throw new Error("Message length greater than 32 bytes") + } + return `0x${hexMessage}` +} + +export default { shannonToCkb, networksToRpcUrl, messageToHex } diff --git a/packages/app/src/wallet/service.ts b/packages/app/src/wallet/service.ts index b89b263..cfa5153 100644 --- a/packages/app/src/wallet/service.ts +++ b/packages/app/src/wallet/service.ts @@ -8,7 +8,7 @@ import { getAuthList, deleteAuthList } from '../auth' import { getTxList, deleteTxFilesByWalletId } from '../tx' import { getSetting } from '../setting' import PasswordWindow from './PasswordWindow' -import signTx from '../keyper/sign' +import { signTx, signMsg } from '../keyper/sign' import { getDataPath } from '../utils' import { broadcastWalletIndex as broadcast, broadcastAuthList, broadcastTxList } from '../broadcast' import { @@ -199,12 +199,27 @@ interface SignTransactionParams { signConfig?: KeyperingAgency.SignTransaction.InputSignConfig } export const signTransaction = async ({ keystore, tx, password, signConfig, lockHash }: SignTransactionParams) => { + const sk = getChildSk(keystore, password) + const signed = await signTx(sk, { tx, lockHash, inputSignConfig: signConfig }) + return signed +} + +interface SignMessageParams { + keystore: Keystore + password: string + message: string +} +export const signMessage = async({keystore, password, message}: SignMessageParams) => { + const sk = getChildSk(keystore, password) + const signedMessage = await signMsg(sk, message) + return signedMessage +} + +const getChildSk = function(keystore: Keystore, password: string) { const xprv = decryptKeystore(keystore, password) const masterSk = xprv.slice(0, 64) const masterChainCode = xprv.slice(64) const masterKeychain = new Keychain(Buffer.from(masterSk, 'hex'), Buffer.from(masterChainCode, 'hex')) const childKeychain = masterKeychain.getFirstChildKeychain() - const sk = `0x${childKeychain.privateKey.toString('hex')}` - const signed = await signTx(sk, { tx, lockHash, inputSignConfig: signConfig }) - return signed + return `0x${childKeychain.privateKey.toString('hex')}` } diff --git a/packages/specs/CHANGELOG.md b/packages/specs/CHANGELOG.md index 51af2fc..c9f7738 100644 --- a/packages/specs/CHANGELOG.md +++ b/packages/specs/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [0.1.0-alpha.3](https://github.com/nervosnetwork/keypering/compare/v0.1.0-alpha.2...v0.1.0-alpha.3) (2020-12-11) + + +### Features + +* add sign message rpc interface ([599d378](https://github.com/nervosnetwork/keypering/commit/599d378eec67c97475b8b31eba571139b43dc8b8)) + + + + + # [0.1.0-alpha.2](https://github.com/nervosnetwork/keypering/compare/v0.1.0-alpha.1...v0.1.0-alpha.2) (2020-09-28) **Note:** Version bump only for package @keypering/specs diff --git a/packages/specs/package.json b/packages/specs/package.json index 626cb77..56a1e2c 100644 --- a/packages/specs/package.json +++ b/packages/specs/package.json @@ -1,6 +1,6 @@ { "name": "@keypering/specs", - "version": "0.1.0-alpha.2", + "version": "0.1.0-alpha.3", "description": "", "author": "Keith ", "homepage": "https://nervosnetwork.github.io/keypering/#/protocol", diff --git a/packages/specs/src/KeyperingAgency.ts b/packages/specs/src/KeyperingAgency.ts index 5980dd0..bea2383 100644 --- a/packages/specs/src/KeyperingAgency.ts +++ b/packages/specs/src/KeyperingAgency.ts @@ -10,6 +10,7 @@ export enum Method { SignTransaction = 'sign_transaction', SendTransaction = 'send_transaction', SignAndSendTransactoin = 'sign_and_send_transaction', + SignMessage = 'sign_message', } export interface ParamsBase { @@ -114,3 +115,15 @@ export namespace SignAndSendTransaction { txHash: string }> } + +export namespace SignMessage { + export type Params = ParamsBase< + Method.SignMessage, + { + message: string, + address: string + } + > + + export type Response = ResponseBase<{ sig: string }> +} diff --git a/packages/ui/CHANGELOG.md b/packages/ui/CHANGELOG.md index a6e5f7b..d50d37c 100644 --- a/packages/ui/CHANGELOG.md +++ b/packages/ui/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [0.1.0-alpha.3](https://github.com/nervosnetwork/keypering/compare/v0.1.0-alpha.2...v0.1.0-alpha.3) (2020-12-11) + +**Note:** Version bump only for package @keypering/ui + + + + + # [0.1.0-alpha.2](https://github.com/nervosnetwork/keypering/compare/v0.1.0-alpha.1...v0.1.0-alpha.2) (2020-09-28) **Note:** Version bump only for package @keypering/ui diff --git a/packages/ui/package.json b/packages/ui/package.json index e8f33dd..4a41187 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -1,6 +1,6 @@ { "name": "@keypering/ui", - "version": "0.1.0-alpha.2", + "version": "0.1.0-alpha.3", "private": true, "homepage": ".", "scripts": { @@ -29,7 +29,7 @@ "react-scripts": "3.4.1" }, "devDependencies": { - "@keypering/specs": "0.1.0-alpha.2", + "@keypering/specs": "0.1.0-alpha.3", "@nervosnetwork/ckb-types": "0.34.0", "@types/react": "16.9.45", "@types/react-dom": "16.9.0",