Skip to content

Commit

Permalink
feat: add bdk wallet create function (#81)
Browse files Browse the repository at this point in the history
  • Loading branch information
Pianochicken authored and kidneyweakx committed Sep 27, 2023
1 parent 9a25b08 commit a0f21b9
Show file tree
Hide file tree
Showing 12 changed files with 173 additions and 16 deletions.
3 changes: 2 additions & 1 deletion .nycrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"statements": 0,
"include": [
"src/fabric/service/**.ts",
"src/quorum/service/**.ts"
"src/quorum/service/**.ts",
"src/wallet/service/**.ts"
],
"exclude":[
"src/fabric/service/Service.abstract.ts",
Expand Down
19 changes: 19 additions & 0 deletions docs/wallet/COMMANDS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Wallet 指令文件

(English version)(Work In Progress)

## 目錄

- [Wallet](#wallet)

## Wallet

### `bdk wallet create`

Description: 產生 Wallet 的相關資訊

| Options | Type | Description | Required | Default |
| --------------------- | :-----: | ------------------------------ | :------: | ------- |
| --help | boolean | Show help | | |
| --version | boolean | Show version number | | |
| -i, --interactive | boolean | 是否使用 Cathay BDK 互動式問答 | | |
14 changes: 14 additions & 0 deletions docs/wallet/EXAMPLE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# 使用範例
(English version)(Work In Progress)

## 目錄
- [建立 Wallet](#建立-wallet)

## 建立 Wallet

```bash
# 輸入指令,啟動 Wallet 互動式介面
bdk wallet create -i
```

選擇欲建立的 Wallet 類型(預設為 ethereum),確認輸入後即可獲得 `wallet address``private key`,請自行妥善保管,若不使用互動模式,則預設為建立 `Ethereum Wallet`
1 change: 1 addition & 0 deletions src/bdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const argv = yargs
})
.commandDir('fabric')
.commandDir('quorum')
.commandDir('wallet')
.commandDir('hello')
.commandDir('ui')
.strict()
Expand Down
9 changes: 6 additions & 3 deletions src/quorum/command/network/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { NetworkCreateType } from '../../model/type/network.type'
import config from '../../config'
import { defaultNetworkConfig } from '../../model/defaultNetworkConfig'
import ora from 'ora'
import Wallet from '../../../wallet/service/wallet'
import { WalletType } from '../../../wallet/model/type/wallet.type'

export const command = 'create'

Expand All @@ -24,6 +26,7 @@ export const builder = (yargs: Argv<OptType>) => {

export const handler = async (argv: Arguments<OptType>) => {
const network = new Network(config)
const wallet = new Wallet()
// check bdkPath files exist or not (include useless file e.g. .DS_Store)
const confirm: boolean = await (async () => {
network.createBdkFolder()
Expand Down Expand Up @@ -102,10 +105,10 @@ export const handler = async (argv: Arguments<OptType>) => {

walletAddress = address
} else {
const { address, privateKey } = await network.createWalletAddress()
const { address, privateKey } = wallet.createWalletAddress(WalletType.ETHEREUM)
walletAddress = address
ora().stopAndPersist({
text: `Your wallet address: 0x${walletAddress}`,
text: `Your ${WalletType.ETHEREUM} wallet address: 0x${walletAddress}`,
symbol: '🔑',
})
ora().stopAndPersist({
Expand All @@ -121,7 +124,7 @@ export const handler = async (argv: Arguments<OptType>) => {

return { chainId, validatorNumber, memberNumber, alloc }
} else {
const { address, privateKey } = await network.createWalletAddress()
const { address, privateKey } = wallet.createWalletAddress(WalletType.ETHEREUM)
return defaultNetworkConfig(address, privateKey)
}
})()
Expand Down
11 changes: 0 additions & 11 deletions src/quorum/service/network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -500,17 +500,6 @@ export default class Network extends AbstractService {
return { privateKey, publicKey, address }
}

/** @ignore */
public createWalletAddress () {
// TODO: use Shawn's code generate key
const nodekey = ethers.Wallet.createRandom()
const privateKey = nodekey.privateKey.replace(/^0x/, '')
const publicKey = nodekey.publicKey.replace(/^0x04/, '')
const address = nodekey.address.replace(/^0x/, '').toLowerCase()

return { privateKey, publicKey, address }
}

/** @ignore */
public createBdkFolder () {
return this.bdkFile.createBdkFolder()
Expand Down
51 changes: 51 additions & 0 deletions src/wallet/command/create.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import prompts from 'prompts'
import { Argv, Arguments } from 'yargs'
import Wallet from '../service/wallet'
import { onCancel } from '../../util/error'
import { WalletCreateType, WalletType } from '../model/type/wallet.type'
import ora from 'ora'

export const command = 'create'

export const desc = '產生 Wallet 的相關資訊'

interface OptType {
interactive: boolean
}

export const builder = (yargs: Argv<OptType>) => {
return yargs
.example('bdk wallet create --interactive', 'Cathay BDK 互動式問答')
.option('interactive', { type: 'boolean', description: '是否使用 Cathay BDK 互動式問答', alias: 'i' })
}

export const handler = async (argv: Arguments<OptType>) => {
const wallet = new Wallet()

let type: WalletType

if (argv.interactive) {
const walletOption = [
{ title: 'ethereum', value: WalletType.ETHEREUM },
]

const { walletType } = await prompts([{
type: 'select',
name: 'walletType',
message: 'What type of wallet you want to create?',
choices: walletOption,
}], { onCancel })
type = walletType
} else {
type = WalletType.ETHEREUM
}

const walletCreateConfig: WalletCreateType = {
type: type,
}

const spinner = ora('Wallet Create ...').start()
const result = await wallet.create(walletCreateConfig)
spinner.succeed(`Wallet Create Result:\n ${result}`)
spinner.succeed('Wallet Create Successfully!')
}
9 changes: 9 additions & 0 deletions src/wallet/model/type/wallet.type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export enum WalletType {
ETHEREUM = 'ethereum'
}
/**
* @requires ethereum - [string] ethereum
*/
export interface WalletCreateType {
type: WalletType
}
34 changes: 34 additions & 0 deletions src/wallet/service/wallet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@

import { ethers } from 'ethers'
import { WalletCreateType, WalletType } from '../model/type/wallet.type'

export default class Wallet {
/**
* @description 建立 quorum network
*/
public create (walletCreateConfig: WalletCreateType) {
const { address, privateKey } = this.createWalletAddress(walletCreateConfig.type)
const walletAddress = address
const result = `🔑 Your ${walletCreateConfig.type} wallet address: 0x${walletAddress}\n 🔑 Wallet private key: ${privateKey}`
return result
}

/** @ignore */
public createWalletAddress (type: WalletType) {
let nodekey: ethers.Wallet
let privateKey: string
let publicKey: string
let address: string

switch (type) {
case WalletType.ETHEREUM:
nodekey = ethers.Wallet.createRandom()
privateKey = nodekey.privateKey.replace(/^0x/, '')
publicKey = nodekey.publicKey.replace(/^0x04/, '')
address = nodekey.address.replace(/^0x/, '').toLowerCase()
break
}

return { privateKey, publicKey, address }
}
}
11 changes: 11 additions & 0 deletions src/wallet/wallet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Argv } from 'yargs'

export const command = 'wallet'

export const desc = '管理 Wallet 的指令'

export const builder = (yargs: Argv) => {
return yargs.commandDir('../wallet/command').demandCommand()
}

export const handler = {}
5 changes: 4 additions & 1 deletion test/quorum/service/network.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import fs from 'fs'
import { resolve } from 'path'
import { sleep, TimeLimitError } from '../../../src/util'
import { JoinNodeType } from '../../../src/quorum/model/type/network.type'
import Wallet from '../../../src/wallet/service/wallet'
import { WalletType } from '../../../src/wallet/model/type/wallet.type'

describe.skip('Quorum.Network.Service', function () {
this.timeout(1000000)
Expand All @@ -18,7 +20,8 @@ describe.skip('Quorum.Network.Service', function () {
const filePath = resolve(`${bdkPath}/bdk-quorum-network`)

const network = new Network(config)
const { address } = network.createWalletAddress()
const wallet = new Wallet()
const { address } = wallet.createWalletAddress(WalletType.ETHEREUM)
const networkCreateConfig = {
validatorNumber: 2,
memberNumber: 2,
Expand Down
22 changes: 22 additions & 0 deletions test/wallet/service/create.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* global describe, it */
import assert from 'assert'
import Wallet from '../../../src/wallet/service/wallet'
import { WalletCreateType, WalletType } from '../../../src/wallet/model/type/wallet.type'

// write a test for the wallet class
describe('Wallet.Create', function () {
this.timeout(1000)
const wallet = new Wallet()

// create a new ethereum wallet
describe('Wallet.Create', () => {
it('should create a ethereum wallet with address and private key', () => {
const WalletCreateType: WalletCreateType = {
type: WalletType.ETHEREUM,
}
const result = wallet.create(WalletCreateType)

assert(result.length > 0, 'Wallet create error')
})
})
})

0 comments on commit a0f21b9

Please sign in to comment.