@onekeyfe/hd-core 0.2.50 → 0.2.52
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/FirmwareUpdateV2.d.ts.map +1 -1
- package/dist/api/index.d.ts +2 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/kaspa/KaspaGetAddress.d.ts +17 -0
- package/dist/api/kaspa/KaspaGetAddress.d.ts.map +1 -0
- package/dist/api/kaspa/KaspaSignTransaction.d.ts +19 -0
- package/dist/api/kaspa/KaspaSignTransaction.d.ts.map +1 -0
- package/dist/api/kaspa/helpers/BufferWriter.d.ts +28 -0
- package/dist/api/kaspa/helpers/BufferWriter.d.ts.map +1 -0
- package/dist/api/kaspa/helpers/HashWriter.d.ts +22 -0
- package/dist/api/kaspa/helpers/HashWriter.d.ts.map +1 -0
- package/dist/api/kaspa/helpers/SignatureType.d.ts +8 -0
- package/dist/api/kaspa/helpers/SignatureType.d.ts.map +1 -0
- package/dist/api/kaspa/helpers/TransferSerialize.d.ts +9 -0
- package/dist/api/kaspa/helpers/TransferSerialize.d.ts.map +1 -0
- package/dist/index.d.ts +63 -5
- package/dist/index.js +474 -8
- package/dist/inject.d.ts.map +1 -1
- package/dist/types/api/export.d.ts +2 -0
- package/dist/types/api/export.d.ts.map +1 -1
- package/dist/types/api/index.d.ts +4 -0
- package/dist/types/api/index.d.ts.map +1 -1
- package/dist/types/api/kaspaGetAddress.d.ts +16 -0
- package/dist/types/api/kaspaGetAddress.d.ts.map +1 -0
- package/dist/types/api/kaspaSignTransaction.d.ts +35 -0
- package/dist/types/api/kaspaSignTransaction.d.ts.map +1 -0
- package/dist/types/api/suiGetAddress.d.ts +2 -2
- package/dist/types/api/suiGetAddress.d.ts.map +1 -1
- package/dist/types/settings.d.ts +1 -0
- package/dist/types/settings.d.ts.map +1 -1
- package/dist/utils/deviceFeaturesUtils.d.ts +1 -1
- package/dist/utils/deviceFeaturesUtils.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/api/FirmwareUpdateV2.ts +5 -1
- package/src/api/index.ts +3 -0
- package/src/api/kaspa/KaspaGetAddress.ts +77 -0
- package/src/api/kaspa/KaspaSignTransaction.ts +157 -0
- package/src/api/kaspa/helpers/BufferWriter.ts +177 -0
- package/src/api/kaspa/helpers/HashWriter.ts +72 -0
- package/src/api/kaspa/helpers/SignatureType.ts +7 -0
- package/src/api/kaspa/helpers/TransferSerialize.ts +143 -0
- package/src/data-manager/DataManager.ts +1 -1
- package/src/device/DevicePool.ts +6 -6
- package/src/inject.ts +5 -0
- package/src/types/api/export.ts +8 -0
- package/src/types/api/index.ts +9 -0
- package/src/types/api/kaspaGetAddress.ts +25 -0
- package/src/types/api/kaspaSignTransaction.ts +43 -0
- package/src/types/api/suiGetAddress.ts +2 -2
- package/src/types/settings.ts +1 -0
- package/src/utils/deviceFeaturesUtils.ts +4 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
2
|
+
import {
|
|
3
|
+
KaspaSignTransactionParams,
|
|
4
|
+
KaspaSignInputParams,
|
|
5
|
+
KaspaSignOutputParams,
|
|
6
|
+
} from '../../../types';
|
|
7
|
+
import { SignatureType } from './SignatureType';
|
|
8
|
+
import { HashWriter } from './HashWriter';
|
|
9
|
+
|
|
10
|
+
export function zeroHash() {
|
|
11
|
+
return Buffer.alloc(32);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function zeroSubnetworkID() {
|
|
15
|
+
return Buffer.alloc(20);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function isSighashAnyoneCanPay(sighashType: number) {
|
|
19
|
+
// eslint-disable-next-line no-bitwise
|
|
20
|
+
return (sighashType & SignatureType.SIGHASH_ANYONECANPAY) === SignatureType.SIGHASH_ANYONECANPAY;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function isSighashSingle(sighashType: number) {
|
|
24
|
+
// eslint-disable-next-line no-bitwise
|
|
25
|
+
return (sighashType & 31) === SignatureType.SIGHASH_SINGLE;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function isSighashNone(sighashType: number) {
|
|
29
|
+
// eslint-disable-next-line no-bitwise
|
|
30
|
+
return (sighashType & 31) === SignatureType.SIGHASH_NONE;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function hashOutpoint(hashWriter: HashWriter, input: KaspaSignInputParams) {
|
|
34
|
+
hashWriter.writeHash(Buffer.from(input.prevTxId, 'hex'));
|
|
35
|
+
hashWriter.writeUInt32LE(input.outputIndex);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function getPreviousOutputsHash(
|
|
39
|
+
transaction: KaspaSignTransactionParams,
|
|
40
|
+
sighashType: SignatureType
|
|
41
|
+
) {
|
|
42
|
+
if (isSighashAnyoneCanPay(sighashType)) {
|
|
43
|
+
return zeroHash();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const hashWriter = new HashWriter();
|
|
47
|
+
transaction.inputs.forEach(input => hashOutpoint(hashWriter, input));
|
|
48
|
+
return hashWriter.finalize();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function getSequencesHash(transaction: KaspaSignTransactionParams, sighashType: SignatureType) {
|
|
52
|
+
if (
|
|
53
|
+
isSighashSingle(sighashType) ||
|
|
54
|
+
isSighashAnyoneCanPay(sighashType) ||
|
|
55
|
+
isSighashNone(sighashType)
|
|
56
|
+
) {
|
|
57
|
+
return zeroHash();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const hashWriter = new HashWriter();
|
|
61
|
+
transaction.inputs.forEach(input => hashWriter.writeUInt64LE(input.sequenceNumber));
|
|
62
|
+
return hashWriter.finalize();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function getSigOpCountsHash(transaction: KaspaSignTransactionParams, sighashType: SignatureType) {
|
|
66
|
+
if (isSighashAnyoneCanPay(sighashType)) {
|
|
67
|
+
return zeroHash();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const hashWriter = new HashWriter();
|
|
71
|
+
transaction.inputs.forEach(input => hashWriter.writeUInt8(input.sigOpCount!));
|
|
72
|
+
return hashWriter.finalize();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function hashTxOut(hashWriter: HashWriter, output: KaspaSignOutputParams) {
|
|
76
|
+
hashWriter.writeUInt64LE(output.satoshis);
|
|
77
|
+
hashWriter.writeUInt16LE(0); // TODO: USE REAL SCRIPT VERSION
|
|
78
|
+
hashWriter.writeVarBytes(Buffer.from(output.script, 'hex'));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function getOutputsHash(
|
|
82
|
+
transaction: KaspaSignTransactionParams,
|
|
83
|
+
inputNumber: number,
|
|
84
|
+
sighashType: SignatureType
|
|
85
|
+
) {
|
|
86
|
+
if (isSighashNone(sighashType)) {
|
|
87
|
+
return zeroHash();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// SigHashSingle: If the relevant output exists - return its hash, otherwise return zero-hash
|
|
91
|
+
if (isSighashSingle(sighashType)) {
|
|
92
|
+
if (inputNumber >= transaction.outputs.length) {
|
|
93
|
+
return zeroHash();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const hashWriter = new HashWriter();
|
|
97
|
+
return hashWriter.finalize();
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const hashWriter = new HashWriter();
|
|
101
|
+
transaction.outputs.forEach(output => hashTxOut(hashWriter, output));
|
|
102
|
+
return hashWriter.finalize();
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Returns a buffer of length 32 bytes with the hash that needs to be signed
|
|
107
|
+
* for OP_CHECKSIG.
|
|
108
|
+
*
|
|
109
|
+
* @name serialize
|
|
110
|
+
* @param {Transaction} transaction the transaction to sign
|
|
111
|
+
* @param {number} sighashType the type of the hash
|
|
112
|
+
* @param {number} inputNumber the input index for the signature
|
|
113
|
+
* @param {Script} subscript the script that will be signed
|
|
114
|
+
* @param {satoshisBN} input's amount (for ForkId signatures)
|
|
115
|
+
*
|
|
116
|
+
*/
|
|
117
|
+
export function serialize(transaction: KaspaSignTransactionParams, inputNumber: number) {
|
|
118
|
+
const hashWriter = new HashWriter();
|
|
119
|
+
|
|
120
|
+
hashWriter.writeUInt16LE(transaction.version);
|
|
121
|
+
hashWriter.writeHash(getPreviousOutputsHash(transaction, transaction.sigHashType!));
|
|
122
|
+
hashWriter.writeHash(getSequencesHash(transaction, transaction.sigHashType!));
|
|
123
|
+
hashWriter.writeHash(getSigOpCountsHash(transaction, transaction.sigHashType!));
|
|
124
|
+
|
|
125
|
+
const input = transaction.inputs[inputNumber];
|
|
126
|
+
hashOutpoint(hashWriter, input);
|
|
127
|
+
hashWriter.writeUInt16LE(0); // TODO: USE REAL SCRIPT VERSION
|
|
128
|
+
hashWriter.writeVarBytes(Buffer.from(input.output.script, 'hex'));
|
|
129
|
+
hashWriter.writeUInt64LE(input.output.satoshis);
|
|
130
|
+
hashWriter.writeUInt64LE(input.sequenceNumber);
|
|
131
|
+
hashWriter.writeUInt8(transaction.sigOpCount ?? 1); // sigOpCount
|
|
132
|
+
hashWriter.writeHash(getOutputsHash(transaction, inputNumber, transaction.sigHashType!));
|
|
133
|
+
hashWriter.writeUInt64LE(transaction.lockTime);
|
|
134
|
+
hashWriter.writeHash(zeroSubnetworkID()); // TODO: USE REAL SUBNETWORK ID
|
|
135
|
+
hashWriter.writeUInt64LE(0); // TODO: USE REAL GAS
|
|
136
|
+
hashWriter.writeHash(zeroHash()); // TODO: USE REAL PAYLOAD HASH
|
|
137
|
+
hashWriter.writeUInt8(transaction.sigHashType!);
|
|
138
|
+
|
|
139
|
+
return {
|
|
140
|
+
hash: hashWriter.finalize(),
|
|
141
|
+
raw: hashWriter.toBuffer(),
|
|
142
|
+
};
|
|
143
|
+
}
|
|
@@ -22,7 +22,7 @@ import type {
|
|
|
22
22
|
} from '../types';
|
|
23
23
|
import { getReleaseChangelog, getReleaseStatus, findLatestRelease } from '../utils/release';
|
|
24
24
|
|
|
25
|
-
type FirmwareField = 'firmware' | 'firmware-v3';
|
|
25
|
+
type FirmwareField = 'firmware' | 'firmware-v2' | 'firmware-v3';
|
|
26
26
|
|
|
27
27
|
export default class DataManager {
|
|
28
28
|
static deviceMap: DeviceTypeMap = {
|
package/src/device/DevicePool.ts
CHANGED
|
@@ -89,7 +89,7 @@ export class DevicePool extends EventEmitter {
|
|
|
89
89
|
connectId?: string,
|
|
90
90
|
initOptions?: InitOptions
|
|
91
91
|
) {
|
|
92
|
-
Log.debug('get device list: connectId: ', connectId);
|
|
92
|
+
// Log.debug('get device list: connectId: ', connectId);
|
|
93
93
|
|
|
94
94
|
const devices: Record<string, Device> = {};
|
|
95
95
|
const deviceList = [];
|
|
@@ -101,7 +101,7 @@ export class DevicePool extends EventEmitter {
|
|
|
101
101
|
if (device) {
|
|
102
102
|
const exist = descriptorList.find(d => d.path === device.originalDescriptor.path);
|
|
103
103
|
if (exist) {
|
|
104
|
-
Log.debug('find existed Device: ', connectId);
|
|
104
|
+
// Log.debug('find existed Device: ', connectId);
|
|
105
105
|
device.updateDescriptor(exist, true);
|
|
106
106
|
devices[connectId] = device;
|
|
107
107
|
deviceList.push(device);
|
|
@@ -128,15 +128,15 @@ export class DevicePool extends EventEmitter {
|
|
|
128
128
|
deviceList.push(device);
|
|
129
129
|
}
|
|
130
130
|
// Log.debug('get devices result : ', devices, deviceList);
|
|
131
|
-
console.log('device poll -> connected: ', this.connectedPool);
|
|
132
|
-
console.log('device poll -> disconnected: ', this.disconnectPool);
|
|
131
|
+
// console.log('device poll -> connected: ', this.connectedPool);
|
|
132
|
+
// console.log('device poll -> disconnected: ', this.disconnectPool);
|
|
133
133
|
await this._checkDevicePool(initOptions);
|
|
134
134
|
return { devices, deviceList };
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
static clearDeviceCache(connectId?: string) {
|
|
138
|
-
Log.debug('clear device pool cache: connectId', connectId);
|
|
139
|
-
Log.debug('clear device pool cache: ', this.devicesCache);
|
|
138
|
+
// Log.debug('clear device pool cache: connectId', connectId);
|
|
139
|
+
// Log.debug('clear device pool cache: ', this.devicesCache);
|
|
140
140
|
if (connectId) {
|
|
141
141
|
delete this.devicesCache[connectId];
|
|
142
142
|
}
|
package/src/inject.ts
CHANGED
|
@@ -230,6 +230,11 @@ export const inject = ({
|
|
|
230
230
|
call({ ...params, connectId, deviceId, method: 'polkadotGetAddress' }),
|
|
231
231
|
polkadotSignTransaction: (connectId, deviceId, params) =>
|
|
232
232
|
call({ ...params, connectId, deviceId, method: 'polkadotSignTransaction' }),
|
|
233
|
+
|
|
234
|
+
kaspaGetAddress: (connectId, deviceId, params) =>
|
|
235
|
+
call({ ...params, connectId, deviceId, method: 'kaspaGetAddress' }),
|
|
236
|
+
kaspaSignTransaction: (connectId, deviceId, params) =>
|
|
237
|
+
call({ ...params, connectId, deviceId, method: 'kaspaSignTransaction' }),
|
|
233
238
|
};
|
|
234
239
|
return api;
|
|
235
240
|
};
|
package/src/types/api/export.ts
CHANGED
|
@@ -123,3 +123,11 @@ export type { FilecoinSignTransactionParams, FilecoinSignedTx } from './filecoin
|
|
|
123
123
|
|
|
124
124
|
export type { PolkadotAddress, PolkadotGetAddressParams } from './polkadotGetAddress';
|
|
125
125
|
export type { PolkadotSignedTx, PolkadotSignTransactionParams } from './polkadotSignTransaction';
|
|
126
|
+
|
|
127
|
+
export type { KaspaAddress, KaspaGetAddressParams } from './kaspaGetAddress';
|
|
128
|
+
export type {
|
|
129
|
+
KaspaSignature,
|
|
130
|
+
KaspaSignTransactionParams,
|
|
131
|
+
KaspaSignInputParams,
|
|
132
|
+
KaspaSignOutputParams,
|
|
133
|
+
} from './kaspaSignTransaction';
|
package/src/types/api/index.ts
CHANGED
|
@@ -104,6 +104,9 @@ import { filecoinSignTransaction } from './filecoinSignTransaction';
|
|
|
104
104
|
import { polkadotGetAddress } from './polkadotGetAddress';
|
|
105
105
|
import { polkadotSignTransaction } from './polkadotSignTransaction';
|
|
106
106
|
|
|
107
|
+
import { kaspaGetAddress } from './kaspaGetAddress';
|
|
108
|
+
import { kaspaSignTransaction } from './kaspaSignTransaction';
|
|
109
|
+
|
|
107
110
|
export * from './export';
|
|
108
111
|
|
|
109
112
|
export type CoreApi = {
|
|
@@ -277,4 +280,10 @@ export type CoreApi = {
|
|
|
277
280
|
*/
|
|
278
281
|
polkadotGetAddress: typeof polkadotGetAddress;
|
|
279
282
|
polkadotSignTransaction: typeof polkadotSignTransaction;
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Kaspa function
|
|
286
|
+
*/
|
|
287
|
+
kaspaGetAddress: typeof kaspaGetAddress;
|
|
288
|
+
kaspaSignTransaction: typeof kaspaSignTransaction;
|
|
280
289
|
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { KaspaAddress as HardwareKaspaAddress } from '@onekeyfe/hd-transport';
|
|
2
|
+
import type { CommonParams, Response } from '../params';
|
|
3
|
+
|
|
4
|
+
export type KaspaAddress = {
|
|
5
|
+
path: string;
|
|
6
|
+
} & HardwareKaspaAddress;
|
|
7
|
+
|
|
8
|
+
export type KaspaGetAddressParams = {
|
|
9
|
+
path: string | number[];
|
|
10
|
+
prefix?: string;
|
|
11
|
+
scheme?: string;
|
|
12
|
+
showOnOneKey?: boolean;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export declare function kaspaGetAddress(
|
|
16
|
+
connectId: string,
|
|
17
|
+
deviceId: string,
|
|
18
|
+
params: CommonParams & KaspaGetAddressParams
|
|
19
|
+
): Response<KaspaAddress>;
|
|
20
|
+
|
|
21
|
+
export declare function kaspaGetAddress(
|
|
22
|
+
connectId: string,
|
|
23
|
+
deviceId: string,
|
|
24
|
+
params: CommonParams & { bundle?: KaspaGetAddressParams[] }
|
|
25
|
+
): Response<Array<KaspaAddress>>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { SignatureType } from '../../api/kaspa/helpers/SignatureType';
|
|
2
|
+
import type { CommonParams, Response } from '../params';
|
|
3
|
+
|
|
4
|
+
export type KaspaSignature = {
|
|
5
|
+
index: number;
|
|
6
|
+
signature: string;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export type KaspaSignInputParams = {
|
|
10
|
+
path: string | number[];
|
|
11
|
+
prevTxId: string;
|
|
12
|
+
outputIndex: number;
|
|
13
|
+
sequenceNumber: number | string;
|
|
14
|
+
output: {
|
|
15
|
+
satoshis: number | string;
|
|
16
|
+
script: string;
|
|
17
|
+
};
|
|
18
|
+
sigOpCount?: number;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export type KaspaSignOutputParams = {
|
|
22
|
+
satoshis: number | string;
|
|
23
|
+
script: string;
|
|
24
|
+
scriptVersion: number;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export type KaspaSignTransactionParams = {
|
|
28
|
+
version: number;
|
|
29
|
+
inputs: KaspaSignInputParams[];
|
|
30
|
+
outputs: KaspaSignOutputParams[];
|
|
31
|
+
lockTime: number | string;
|
|
32
|
+
sigHashType?: SignatureType;
|
|
33
|
+
sigOpCount?: number;
|
|
34
|
+
subNetworkID?: string;
|
|
35
|
+
scheme?: string;
|
|
36
|
+
prefix?: string;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export declare function kaspaSignTransaction(
|
|
40
|
+
connectId: string,
|
|
41
|
+
deviceId: string,
|
|
42
|
+
params: CommonParams & KaspaSignTransactionParams
|
|
43
|
+
): Response<KaspaSignature[]>;
|
|
@@ -14,11 +14,11 @@ export type SuiGetAddressParams = {
|
|
|
14
14
|
export declare function suiGetAddress(
|
|
15
15
|
connectId: string,
|
|
16
16
|
deviceId: string,
|
|
17
|
-
params: CommonParams &
|
|
17
|
+
params: CommonParams & SuiGetAddressParams
|
|
18
18
|
): Response<SuiAddress>;
|
|
19
19
|
|
|
20
20
|
export declare function suiGetAddress(
|
|
21
21
|
connectId: string,
|
|
22
22
|
deviceId: string,
|
|
23
|
-
params: CommonParams & { bundle?:
|
|
23
|
+
params: CommonParams & { bundle?: SuiGetAddressParams[] }
|
|
24
24
|
): Response<Array<SuiAddress>>;
|
package/src/types/settings.ts
CHANGED
|
@@ -180,6 +180,10 @@ export const getFirmwareUpdateField = (features: Features, updateType: 'firmware
|
|
|
180
180
|
return 'ble';
|
|
181
181
|
}
|
|
182
182
|
|
|
183
|
+
if (deviceType === 'classic') {
|
|
184
|
+
return 'firmware-v2';
|
|
185
|
+
}
|
|
186
|
+
|
|
183
187
|
if (deviceType === 'touch') {
|
|
184
188
|
if (semver.lt(deviceFirmwareVersion.join('.'), '3.4.0')) return 'firmware';
|
|
185
189
|
return 'firmware-v3';
|