Skip to content

Commit

Permalink
feat: Support Nostr (#295)
Browse files Browse the repository at this point in the history
* feat: Adding Nostr api

* feat: Nostr example

* fix: Nostr type

* chore: limit version

* chore: message

* chore: update version

* feat: Adding NostrSignSchnorr Method

* chore: upgrade version
  • Loading branch information
originalix authored Dec 19, 2023
1 parent c0c2cfa commit 7285a87
Show file tree
Hide file tree
Showing 31 changed files with 898 additions and 40 deletions.
10 changes: 5 additions & 5 deletions packages/connect-examples/expo-example/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "expo-example",
"version": "0.3.33",
"version": "0.3.34",
"scripts": {
"start": "expo start --dev-client",
"android": "expo run:android",
Expand All @@ -11,10 +11,10 @@
"dependencies": {
"@expo/webpack-config": "^18.1.3",
"@noble/hashes": "^1.3.2",
"@onekeyfe/hd-ble-sdk": "^0.3.33",
"@onekeyfe/hd-common-connect-sdk": "^0.3.33",
"@onekeyfe/hd-core": "^0.3.33",
"@onekeyfe/hd-web-sdk": "^0.3.33",
"@onekeyfe/hd-ble-sdk": "^0.3.34",
"@onekeyfe/hd-common-connect-sdk": "^0.3.34",
"@onekeyfe/hd-core": "^0.3.34",
"@onekeyfe/hd-web-sdk": "^0.3.34",
"@onekeyfe/react-native-ble-plx": "3.0.0",
"@react-native-async-storage/async-storage": "1.18.2",
"@react-native-picker/picker": "2.4.10",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ const playgroundConfig = [
title: 'TRON API',
data: require('../data/tron').default,
},
{
title: 'Nostr API',
data: require('../data/nostr').default,
},
];

const PlaygroundManager = () => (
Expand Down
120 changes: 120 additions & 0 deletions packages/connect-examples/expo-example/src/data/nostr.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import { type PlaygroundProps } from '../components/Playground';

const api: PlaygroundProps[] = [
{
method: 'nostrGetPublicKey',
description: 'Get a Nostr public key for your account.',
presupposes: [
{
title: 'Get Nostr Public Key',
value: {
path: "m/44'/1237'/0'/0/0",
showOnOneKey: true,
},
},
{
title: 'Batch Get Public Key',
value: {
bundle: [
{
path: "m/44'/1237'/0'/0/0",
showOnOneKey: false,
},
{
path: "m/44'/1237'/1'/0/0",
showOnOneKey: false,
},
{
path: "m/44'/1237'/2'/0/0",
showOnOneKey: false,
},
{
path: "m/44'/1237'/3'/0/0",
showOnOneKey: false,
},
],
},
},
],
},
{
method: 'nostrSignEvent',
description: 'Sign a Nostr event.',
presupposes: [
{
title: 'Sign simple note',
value: {
path: "m/44'/1237'/0'/0/0",
event: {
kind: 1,
content: 'Hello world',
tags: [],
created_at: 1702268010,
},
},
},
{
title: 'Sign other nostr event',
value: {
path: "m/44'/1237'/0'/0/0",
event: {
id: '6ea5ad0c84597800da1326d1c23c7c29777faa6a750dcb358e0a228dc666c3a4',
pubkey: '0b3df6d98a46e9c9204bb9302303f7956461feda90bf00b153892bb9e9d454c8',
content: '',
kind: 22242,
created_at: 1702521824,
tags: [
['challenge', '4b1fd2cc-a212-4fb3-a844-bc82ecd005eb'],
['relay', 'wss://nostr.wine/'],
],
},
},
},
],
},
{
method: 'nostrEncryptMessage',
description: 'Encrypt message',
presupposes: [
{
title: 'Encrypt message',
value: {
path: "m/44'/1237'/0'/0/0",
pubkey: '2118c65161c7d68b4bdbe1374f658532670057ab1bb0c99937d0ff7cff45cb5e',
plaintext: 'Hello world',
showOnOneKey: false,
},
},
],
},
{
method: 'nostrDecryptMessage',
description: 'Decrypt message',
presupposes: [
{
title: 'Decrypt message',
value: {
path: "m/44'/1237'/0'/0/0",
pubkey: '2118c65161c7d68b4bdbe1374f658532670057ab1bb0c99937d0ff7cff45cb5e',
ciphertext: 'VpWFJ7JDFv16jL7pBZ1shw==?iv=$1tPpwGD3Ic1RTVXJx1ZG7Q==',
showOnOneKey: false,
},
},
],
},
{
method: 'nostrSignSchnorr',
description: 'Sign schnorr',
presupposes: [
{
title: 'Sign schnorr',
value: {
path: "m/44'/1237'/0'/0/0",
hash: '2118c65161c7d68b4bdbe1374f658532670057ab1bb0c99937d0ff7cff45cb5e',
},
},
],
},
];

export default api;
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ export const getHardwareSDKInstance = memoizee(
console.log(HardwareSDK);

if (Platform.OS === 'web') {
settings.connectSrc = 'https://jssdk.onekey.so/0.3.33/';
// settings.connectSrc = 'https://localhost:8087/';
settings.connectSrc = 'https://jssdk.onekey.so/0.3.34/';
settings.env = 'web';
settings.preRelease = false;
// HardwareLowLevelSDK = await importLowLevelSDK();
Expand Down
6 changes: 3 additions & 3 deletions packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@onekeyfe/hd-core",
"version": "0.3.33",
"version": "0.3.34",
"description": "> TODO: description",
"author": "OneKey",
"homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
Expand All @@ -25,8 +25,8 @@
"url": "https://github.com/OneKeyHQ/hardware-js-sdk/issues"
},
"dependencies": {
"@onekeyfe/hd-shared": "^0.3.33",
"@onekeyfe/hd-transport": "^0.3.33",
"@onekeyfe/hd-shared": "^0.3.34",
"@onekeyfe/hd-transport": "^0.3.34",
"axios": "^0.27.2",
"bignumber.js": "^9.0.2",
"bytebuffer": "^5.0.1",
Expand Down
6 changes: 6 additions & 0 deletions packages/core/src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,9 @@ export { default as kaspaSignTransaction } from './kaspa/KaspaSignTransaction';

export { default as nexaGetAddress } from './nexa/NexaGetAddress';
export { default as nexaSignTransaction } from './nexa/NexaSignTransaction';

export { default as nostrGetPublicKey } from './nostr/NostrGetPublicKey';
export { default as nostrSignEvent } from './nostr/NostrSignEvent';
export { default as nostrEncryptMessage } from './nostr/NostrEncryptMessage';
export { default as nostrDecryptMessage } from './nostr/NostrDecryptMessage';
export { default as nostrSignSchnorr } from './nostr/NostrSignSchnorr';
56 changes: 56 additions & 0 deletions packages/core/src/api/nostr/NostrDecryptMessage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { NostrDecryptMessage as DecryptMessage } from '@onekeyfe/hd-transport';
import { UI_REQUEST } from '../../constants/ui-request';
import { serializedPath, validatePath } from '../helpers/pathUtils';
import { BaseMethod } from '../BaseMethod';
import { validateParams } from '../helpers/paramsValidator';

export default class NostrDecryptMessage extends BaseMethod<DecryptMessage> {
hasBundle = false;

init() {
this.checkDeviceId = true;
this.notAllowDeviceMode = [...this.notAllowDeviceMode, UI_REQUEST.INITIALIZE];

const { payload } = this;
validateParams(payload, [
{ name: 'path', required: true },
{ name: 'pubkey', required: true, type: 'string' },
{ name: 'ciphertext', required: true, type: 'string' },
{ name: 'showOnOneKey', type: 'boolean' },
]);
const addressN = validatePath(payload.path, 5);

this.params = {
address_n: addressN,
pubkey: payload.pubkey,
msg: payload.ciphertext,
show_display: payload.showOnOneKey ?? true,
};
}

getVersionRange() {
return {
model_mini: {
min: '3.6.0',
},
model_touch: {
min: '4.6.0',
},
};
}

async run() {
const { message } = await this.device.commands.typedCall(
'NostrDecryptMessage',
'NostrDecryptedMessage',
this.params
);

return {
path: serializedPath(this.params.address_n),
pubkey: this.params.pubkey,
ciphertext: this.params.msg,
decryptedMessage: message.msg,
};
}
}
56 changes: 56 additions & 0 deletions packages/core/src/api/nostr/NostrEncryptMessage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { NostrEncryptMessage as EncryptMessage } from '@onekeyfe/hd-transport';
import { UI_REQUEST } from '../../constants/ui-request';
import { serializedPath, validatePath } from '../helpers/pathUtils';
import { BaseMethod } from '../BaseMethod';
import { validateParams } from '../helpers/paramsValidator';

export default class NostrEncryptMessage extends BaseMethod<EncryptMessage> {
hasBundle = false;

init() {
this.checkDeviceId = true;
this.notAllowDeviceMode = [...this.notAllowDeviceMode, UI_REQUEST.INITIALIZE];

const { payload } = this;
validateParams(payload, [
{ name: 'path', required: true },
{ name: 'pubkey', required: true, type: 'string' },
{ name: 'plaintext', required: true, type: 'string' },
{ name: 'showOnOneKey', type: 'boolean' },
]);
const addressN = validatePath(payload.path, 5);

this.params = {
address_n: addressN,
pubkey: payload.pubkey,
msg: payload.plaintext,
show_display: payload.showOnOneKey ?? true,
};
}

getVersionRange() {
return {
model_mini: {
min: '3.6.0',
},
model_touch: {
min: '4.6.0',
},
};
}

async run() {
const { message } = await this.device.commands.typedCall(
'NostrEncryptMessage',
'NostrEncryptedMessage',
this.params
);

return {
path: serializedPath(this.params.address_n),
pubkey: this.params.pubkey,
plaintext: this.params.msg,
encryptedMessage: message.msg,
};
}
}
71 changes: 71 additions & 0 deletions packages/core/src/api/nostr/NostrGetPublicKey.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { NostrGetPublicKey as GetPublicKey } from '@onekeyfe/hd-transport';
import { UI_REQUEST } from '../../constants/ui-request';
import { serializedPath, validatePath } from '../helpers/pathUtils';
import { BaseMethod } from '../BaseMethod';
import { validateParams } from '../helpers/paramsValidator';
import { BTCGetAddressParams } from '../../types/api/btcGetAddress';
import { NostrPublicKey } from '../../types/api/nostrGetPublicKey';

export default class NostrGetPublicKey extends BaseMethod<GetPublicKey[]> {
hasBundle = false;

init() {
this.checkDeviceId = true;
this.notAllowDeviceMode = [...this.notAllowDeviceMode, UI_REQUEST.INITIALIZE];

this.hasBundle = Object.prototype.hasOwnProperty.call(this.payload, 'bundle');
const payload = this.hasBundle ? this.payload : { bundle: [this.payload] };

validateParams(payload, [{ name: 'bundle', type: 'array' }]);

this.params = [];

payload.bundle.forEach((batch: BTCGetAddressParams) => {
const addressN = validatePath(batch.path, 1);

validateParams(batch, [
{ name: 'path', required: true },
{ name: 'showOnOneKey', type: 'boolean' },
]);

const showOnOneKey = batch.showOnOneKey ?? true;

this.params.push({
address_n: addressN,
show_display: showOnOneKey,
});
});
}

getVersionRange() {
return {
model_mini: {
min: '3.6.0',
},
model_touch: {
min: '4.6.0',
},
};
}

async run() {
const responses: NostrPublicKey[] = [];

for (let i = 0; i < this.params.length; i++) {
const param = this.params[i];

const res = await this.device.commands.typedCall('NostrGetPublicKey', 'NostrPublicKey', {
...param,
});

const response = {
path: serializedPath(param.address_n),
...res.message,
};

responses.push(response);
}

return Promise.resolve(this.hasBundle ? responses : responses[0]);
}
}
Loading

0 comments on commit 7285a87

Please sign in to comment.