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
+
+
+
+
+
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
+
+
+
+
+
+
+
+
+
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",