Skip to content

Commit

Permalink
jellyfish-wallet-classic (#454)
Browse files Browse the repository at this point in the history
* Added classic wallet implementation

* Remove bip from readme

* Address codecov
  • Loading branch information
monstrobishi authored Jul 9, 2021
1 parent dc897c7 commit 43e3158
Show file tree
Hide file tree
Showing 12 changed files with 189 additions and 0 deletions.
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
/packages/jellyfish-transaction-signature/ @fuxingloh @ivan-zynesis
/packages/jellyfish-wallet/ @fuxingloh @ivan-zynesis @monstrobishi
/packages/jellyfish-wallet-mnemonic/ @fuxingloh @ivan-zynesis
/packages/jellyfish-wallet-classic/ @fuxingloh @ivan-zynesis @monstrobishi
/packages/testcontainers/ @fuxingloh
/packages/testing/ @fuxingloh @canonbrother

Expand Down
1 change: 1 addition & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ module.exports = {
'@defichain/jellyfish-transaction-builder': '<rootDir>/packages/jellyfish-transaction-builder/src',
'@defichain/jellyfish-transaction': '<rootDir>/packages/jellyfish-transaction/src',
'@defichain/jellyfish-wallet-mnemonic': '<rootDir>/packages/jellyfish-wallet-mnemonic/src',
'@defichain/jellyfish-wallet-classic': '<rootDir>/packages/jellyfish-wallet-classic/src',
'@defichain/jellyfish-wallet': '<rootDir>/packages/jellyfish-wallet/src',
'@defichain/testcontainers': '<rootDir>/packages/testcontainers/src',
'@defichain/testing': '<rootDir>/packages/testing/src'
Expand Down
6 changes: 6 additions & 0 deletions packages/jellyfish-wallet-classic/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[![npm](https://img.shields.io/npm/v/@defichain/jellyfish-wallet-classic)](https://www.npmjs.com/package/@defichain/jellyfish-wallet-classic/v/latest)
[![npm@next](https://img.shields.io/npm/v/@defichain/jellyfish-wallet-classic/next)](https://www.npmjs.com/package/@defichain/jellyfish-wallet-classic/v/next)

# @defichain/jellyfish-wallet-classic

WalletClassic implements a simple, single elliptic pair wallet.
48 changes: 48 additions & 0 deletions packages/jellyfish-wallet-classic/__tests__/wallet_classic.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { WIF } from '@defichain/jellyfish-crypto'
import { BigNumber } from 'bignumber.js'
import { GenesisKeys } from '@defichain/testcontainers'
import { WalletClassic } from '../src'

describe('WalletClassic', () => {
let wallet: WalletClassic

beforeAll(() => {
wallet = new WalletClassic(WIF.asEllipticPair(GenesisKeys[GenesisKeys.length - 1].owner.privKey))
})

it('should get public key', async () => {
const pubKey = await wallet.publicKey()
expect(pubKey.length).toStrictEqual(33)
expect(pubKey.toString('hex')).toStrictEqual('022b60b1d1ec292c4de571baaf9a776137fac1b69da89e9a4274880aa71b9d4890')
})

it('should get private key', async () => {
const privKey = await wallet.privateKey()
expect(privKey.length).toStrictEqual(32)
expect(privKey.toString('hex')).toStrictEqual('cf057c882aaa83a1461881812e9f1e9c7656e988a0847c2fbfb5b78bc7cdef5d')
})

it('should sign and verify', async () => {
const hash = Buffer.from('e9071e75e25b8a1e298a72f0d2e9f4f95a0f5cdf86a533cda597eb402ed13b3a', 'hex')

const signature = await wallet.sign(hash)
expect(signature.toString('hex')).toStrictEqual('304402201832b770f7c0d8a124ab60552350c4347609dcd369c0cb39771300457a1abf4f022026da1f4bfeaf46c57ef230166ecd5b425d656c6321842cbcce98a54bec2153a9')

const valid = await wallet.verify(hash, signature)
expect(valid).toStrictEqual(true)
})

it('should sign transaction and fail because invalid', async () => {
return await expect(async () => await wallet.signTx({
version: 0,
vin: [],
vout: [],
lockTime: 0
}, [{
value: new BigNumber(0),
script: { stack: [] },
tokenId: 0
}])
).rejects.toThrow()
})
})
12 changes: 12 additions & 0 deletions packages/jellyfish-wallet-classic/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module.exports = {
testEnvironment: 'node',
testMatch: [
'**/__tests__/**/*.test.ts'
],
transform: {
'^.+\\.ts$': 'ts-jest'
},
verbose: true,
clearMocks: true,
testTimeout: 120000
}
41 changes: 41 additions & 0 deletions packages/jellyfish-wallet-classic/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"private": false,
"name": "@defichain/jellyfish-wallet-classic",
"version": "0.0.0",
"description": "A collection of TypeScript + JavaScript tools and libraries for DeFi Blockchain developers to build decentralized finance on Bitcoin",
"keywords": [
"DeFiChain",
"DeFi",
"Blockchain",
"API",
"Bitcoin"
],
"repository": "DeFiCh/jellyfish",
"bugs": "https://github.com/DeFiCh/jellyfish/issues",
"license": "MIT",
"contributors": [
{
"name": "DeFiChain Foundation",
"email": "[email protected]",
"url": "https://defichain.com/"
},
{
"name": "DeFi Blockchain Contributors"
},
{
"name": "DeFi Jellyfish Contributors"
}
],
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
"dist"
],
"scripts": {
"build": "tsc -b ./tsconfig.build.json"
},
"dependencies": {
"@defichain/jellyfish-wallet": "0.0.0",
"@defichain/jellyfish-transaction": "0.0.0"
}
}
65 changes: 65 additions & 0 deletions packages/jellyfish-wallet-classic/src/classic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { WalletEllipticPair } from '@defichain/jellyfish-wallet'
import { EllipticPair } from '@defichain/jellyfish-crypto'
import {
Transaction,
Vout,
TransactionSegWit
} from '@defichain/jellyfish-transaction'
import { SignInputOption, TransactionSigner } from '@defichain/jellyfish-transaction-signature'

/**
* WalletClassic extends WalletEllipticPair with a simple classic implementation.
*
* Single elliptic pair wallet.
*/
export class WalletClassic implements WalletEllipticPair {
constructor (public readonly ellipticPair: EllipticPair) {
}

/**
* @return {Promise<Buffer>} compressed public key
*/
async publicKey (): Promise<Buffer> {
return await this.ellipticPair.publicKey()
}

/**
* @return {Promise<Buffer>} privateKey
*/
async privateKey (): Promise<Buffer> {
return await this.ellipticPair.privateKey()
}

/**
* @param {Buffer} hash to sign
* @return {Buffer} signature in DER format, SIGHASHTYPE not included
* @see https://tools.ietf.org/html/rfc6979
* @see https://github.com/bitcoin/bitcoin/pull/13666
*/
async sign (hash: Buffer): Promise<Buffer> {
return await this.ellipticPair.sign(hash)
}

/**
* @param {Buffer} hash to verify with signature
* @param {Buffer} derSignature of the hash in encoded with DER, SIGHASHTYPE must not be included
* @return {boolean} validity of signature of the hash
*/
async verify (hash: Buffer, derSignature: Buffer): Promise<boolean> {
return await this.ellipticPair.verify(hash, derSignature)
}

/**
* WalletClassic transaction signing.
*
* @param {Transaction} transaction to sign
* @param {Vout[]} prevouts of the transaction to fund this transaction
* @return {TransactionSegWit} a signed transaction
*/
async signTx (transaction: Transaction, prevouts: Vout[]): Promise<TransactionSegWit> {
const inputs: SignInputOption[] = prevouts.map(prevout => {
return { prevout: prevout, ellipticPair: this }
})
return TransactionSigner.sign(transaction, inputs)
}
}
1 change: 1 addition & 0 deletions packages/jellyfish-wallet-classic/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './classic'
10 changes: 10 additions & 0 deletions packages/jellyfish-wallet-classic/tsconfig.build.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"extends": "../../tsconfig.build.json",
"include": [
"./src/**/*"
],
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src",
}
}
1 change: 1 addition & 0 deletions tsconfig.build.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
{"path": "./packages/jellyfish-transaction-signature/tsconfig.build.json"},
{"path": "./packages/jellyfish-wallet/tsconfig.build.json"},
{"path": "./packages/jellyfish-wallet-mnemonic/tsconfig.build.json"},
{"path": "./packages/jellyfish-wallet-classic/tsconfig.build.json"},
{"path": "./packages/testcontainers/tsconfig.build.json"},
{"path": "./packages/testing/tsconfig.build.json"}
]
Expand Down
2 changes: 2 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"@defichain/jellyfish-transaction-signature": ["jellyfish-transaction-signature/src"],
"@defichain/jellyfish-wallet": ["jellyfish-wallet/src"],
"@defichain/jellyfish-wallet-mnemonic": ["jellyfish-wallet-mnemonic/src"],
"@defichain/jellyfish-wallet-classic": ["jellyfish-wallet-classic/src"],
"@defichain/testcontainers": ["testcontainers/src"],
"@defichain/testing": ["testing/src"],

Expand All @@ -28,6 +29,7 @@
"@defichain/jellyfish-transaction-signature/*": ["jellyfish-transaction-signature/src/*"],
"@defichain/jellyfish-wallet/*": ["jellyfish-wallet/src/*"],
"@defichain/jellyfish-wallet-mnemonic/*": ["jellyfish-wallet-mnemonic/src/*"],
"@defichain/jellyfish-wallet-classic/*": ["jellyfish-wallet-classic/src/*"],
"@defichain/testcontainers/*": ["testcontainers/src/*"],
"@defichain/testing/*": ["testing/src/*"],
}
Expand Down
1 change: 1 addition & 0 deletions website/docs/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,6 @@ Package | Description
`@defichain/jellyfish-transaction-signature` | Stateless utility library to perform transaction signing.
`@defichain/jellyfish-wallet` | Jellyfish wallet is a managed wallet, where account can get discovered from an HD seed.
`@defichain/jellyfish-wallet-mnemonic` | MnemonicHdNode implements the WalletHdNode from jellyfish-wallet; a CoinType-agnostic HD Wallet for noncustodial DeFi.
`@defichain/jellyfish-wallet-classic` | WalletClassic implements a simple, single elliptic pair wallet.
`@defichain/testcontainers` | Provides a lightweight, throw away instances for DeFiD node provisioned automatically in a Docker container.
`@defichain/testing` | Provides rich test fixture setup functions for effective and effortless testing.

0 comments on commit 43e3158

Please sign in to comment.