@bsv/sdk 1.3.9 → 1.3.10
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/cjs/package.json +1 -1
- package/dist/cjs/src/auth/Peer.js.map +1 -1
- package/dist/cjs/src/auth/utils/createNonce.js +9 -3
- package/dist/cjs/src/auth/utils/createNonce.js.map +1 -1
- package/dist/cjs/src/auth/utils/verifyNonce.js +3 -2
- package/dist/cjs/src/auth/utils/verifyNonce.js.map +1 -1
- package/dist/cjs/src/overlay-tools/OverlayAdminTokenTemplate.js.map +1 -1
- package/dist/cjs/src/wallet/ProtoWallet.js.map +1 -1
- package/dist/cjs/src/wallet/WalletClient.js.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/src/auth/Peer.js.map +1 -1
- package/dist/esm/src/auth/utils/createNonce.js +9 -3
- package/dist/esm/src/auth/utils/createNonce.js.map +1 -1
- package/dist/esm/src/auth/utils/verifyNonce.js +3 -2
- package/dist/esm/src/auth/utils/verifyNonce.js.map +1 -1
- package/dist/esm/src/overlay-tools/OverlayAdminTokenTemplate.js.map +1 -1
- package/dist/esm/src/wallet/ProtoWallet.js.map +1 -1
- package/dist/esm/src/wallet/WalletClient.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/types/src/auth/Peer.d.ts.map +1 -1
- package/dist/types/src/auth/utils/createNonce.d.ts +4 -3
- package/dist/types/src/auth/utils/createNonce.d.ts.map +1 -1
- package/dist/types/src/auth/utils/verifyNonce.d.ts +3 -2
- package/dist/types/src/auth/utils/verifyNonce.d.ts.map +1 -1
- package/dist/types/src/overlay-tools/OverlayAdminTokenTemplate.d.ts.map +1 -1
- package/dist/types/src/wallet/ProtoWallet.d.ts.map +1 -1
- package/dist/types/src/wallet/WalletClient.d.ts.map +1 -1
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/dist/umd/bundle.js +1 -1
- package/docs/auth.md +12 -5
- package/package.json +1 -1
- package/src/auth/Peer.ts +21 -21
- package/src/auth/utils/__tests/cryptononce.test.ts +42 -7
- package/src/auth/utils/createNonce.ts +10 -4
- package/src/auth/utils/verifyNonce.ts +4 -3
- package/src/overlay-tools/OverlayAdminTokenTemplate.ts +4 -4
- package/src/wallet/ProtoWallet.ts +10 -10
- package/src/wallet/WalletClient.ts +30 -30
package/docs/auth.md
CHANGED
|
@@ -1129,13 +1129,13 @@ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](
|
|
|
1129
1129
|
|
|
1130
1130
|
### Function: createNonce
|
|
1131
1131
|
|
|
1132
|
-
Creates a nonce derived from a
|
|
1132
|
+
Creates a nonce derived from a wallet
|
|
1133
1133
|
|
|
1134
1134
|
```ts
|
|
1135
|
-
export async function createNonce(wallet: WalletInterface): Promise<string>
|
|
1135
|
+
export async function createNonce(wallet: WalletInterface, counterparty: WalletCounterparty = "self"): Promise<string>
|
|
1136
1136
|
```
|
|
1137
1137
|
|
|
1138
|
-
See also: [WalletInterface](#interface-walletinterface)
|
|
1138
|
+
See also: [WalletCounterparty](#type-walletcounterparty), [WalletInterface](#interface-walletinterface)
|
|
1139
1139
|
|
|
1140
1140
|
<details>
|
|
1141
1141
|
|
|
@@ -1145,6 +1145,11 @@ Returns
|
|
|
1145
1145
|
|
|
1146
1146
|
A random nonce derived with a wallet
|
|
1147
1147
|
|
|
1148
|
+
Argument Details
|
|
1149
|
+
|
|
1150
|
+
+ **counterparty**
|
|
1151
|
+
+ The counterparty to the nonce creation. Defaults to 'self'.
|
|
1152
|
+
|
|
1148
1153
|
</details>
|
|
1149
1154
|
|
|
1150
1155
|
Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
|
|
@@ -1155,10 +1160,10 @@ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](
|
|
|
1155
1160
|
Verifies a nonce derived from a wallet
|
|
1156
1161
|
|
|
1157
1162
|
```ts
|
|
1158
|
-
export async function verifyNonce(nonce: string, wallet: WalletInterface): Promise<boolean>
|
|
1163
|
+
export async function verifyNonce(nonce: string, wallet: WalletInterface, counterparty: WalletCounterparty = "self"): Promise<boolean>
|
|
1159
1164
|
```
|
|
1160
1165
|
|
|
1161
|
-
See also: [WalletInterface](#interface-walletinterface)
|
|
1166
|
+
See also: [WalletCounterparty](#type-walletcounterparty), [WalletInterface](#interface-walletinterface)
|
|
1162
1167
|
|
|
1163
1168
|
<details>
|
|
1164
1169
|
|
|
@@ -1172,6 +1177,8 @@ Argument Details
|
|
|
1172
1177
|
|
|
1173
1178
|
+ **nonce**
|
|
1174
1179
|
+ A nonce to verify as a base64 string.
|
|
1180
|
+
+ **counterparty**
|
|
1181
|
+
+ The counterparty to the nonce creation. Defaults to 'self'.
|
|
1175
1182
|
|
|
1176
1183
|
</details>
|
|
1177
1184
|
|
package/package.json
CHANGED
package/src/auth/Peer.ts
CHANGED
|
@@ -39,7 +39,7 @@ export class Peer {
|
|
|
39
39
|
* @param {SessionManager} [sessionManager] - Optional SessionManager to be used for managing peer sessions.
|
|
40
40
|
* @param {boolean} [autoPersistLastSession] - Whether to auto-persist the session with the last-interacted-with peer. Defaults to true.
|
|
41
41
|
*/
|
|
42
|
-
constructor(
|
|
42
|
+
constructor (
|
|
43
43
|
wallet: WalletInterface,
|
|
44
44
|
transport: Transport,
|
|
45
45
|
certificatesToRequest?: RequestedCertificateSet,
|
|
@@ -66,7 +66,7 @@ export class Peer {
|
|
|
66
66
|
* @returns {Promise<void>}
|
|
67
67
|
* @throws Will throw an error if the message fails to send.
|
|
68
68
|
*/
|
|
69
|
-
async toPeer(message: number[], identityKey?: string, maxWaitTime?: number): Promise<void> {
|
|
69
|
+
async toPeer (message: number[], identityKey?: string, maxWaitTime?: number): Promise<void> {
|
|
70
70
|
if (this.autoPersistLastSession && this.lastInteractedWithPeer && typeof identityKey !== 'string') {
|
|
71
71
|
identityKey = this.lastInteractedWithPeer
|
|
72
72
|
}
|
|
@@ -111,7 +111,7 @@ export class Peer {
|
|
|
111
111
|
* @returns {Promise<void>} Resolves if the certificate request message is successfully sent.
|
|
112
112
|
* @throws Will throw an error if the peer session is not authenticated or if sending the request fails.
|
|
113
113
|
*/
|
|
114
|
-
async requestCertificates(certificatesToRequest: RequestedCertificateSet, identityKey?: string, maxWaitTime = 10000): Promise<void> {
|
|
114
|
+
async requestCertificates (certificatesToRequest: RequestedCertificateSet, identityKey?: string, maxWaitTime = 10000): Promise<void> {
|
|
115
115
|
const peerSession = await this.getAuthenticatedSession(identityKey, maxWaitTime)
|
|
116
116
|
|
|
117
117
|
// Prepare the general message
|
|
@@ -152,7 +152,7 @@ export class Peer {
|
|
|
152
152
|
* @returns {Promise<PeerSession>} - A promise that resolves with an authenticated `PeerSession`.
|
|
153
153
|
* @throws {Error} - Throws an error if the transport is not connected or if the handshake fails.
|
|
154
154
|
*/
|
|
155
|
-
async getAuthenticatedSession(identityKey?: string, maxWaitTime?: number): Promise<PeerSession> {
|
|
155
|
+
async getAuthenticatedSession (identityKey?: string, maxWaitTime?: number): Promise<PeerSession> {
|
|
156
156
|
if (!this.transport) {
|
|
157
157
|
throw new Error('Peer transport is not connected!')
|
|
158
158
|
}
|
|
@@ -175,7 +175,7 @@ export class Peer {
|
|
|
175
175
|
* @param {(senderPublicKey: string, payload: number[]) => void} callback - The function to call when a general message is received.
|
|
176
176
|
* @returns {number} The ID of the callback listener.
|
|
177
177
|
*/
|
|
178
|
-
listenForGeneralMessages(callback: (senderPublicKey: string, payload: number[]) => void): number {
|
|
178
|
+
listenForGeneralMessages (callback: (senderPublicKey: string, payload: number[]) => void): number {
|
|
179
179
|
const callbackID = this.callbackIdCounter++
|
|
180
180
|
this.onGeneralMessageReceivedCallbacks.set(callbackID, callback)
|
|
181
181
|
return callbackID
|
|
@@ -186,7 +186,7 @@ export class Peer {
|
|
|
186
186
|
*
|
|
187
187
|
* @param {number} callbackID - The ID of the callback to remove.
|
|
188
188
|
*/
|
|
189
|
-
stopListeningForGeneralMessages(callbackID: number): void {
|
|
189
|
+
stopListeningForGeneralMessages (callbackID: number): void {
|
|
190
190
|
this.onGeneralMessageReceivedCallbacks.delete(callbackID)
|
|
191
191
|
}
|
|
192
192
|
|
|
@@ -196,7 +196,7 @@ export class Peer {
|
|
|
196
196
|
* @param {(certs: VerifiableCertificate[]) => void} callback - The function to call when certificates are received.
|
|
197
197
|
* @returns {number} The ID of the callback listener.
|
|
198
198
|
*/
|
|
199
|
-
listenForCertificatesReceived(callback: (senderPublicKey: string, certs: VerifiableCertificate[]) => void): number {
|
|
199
|
+
listenForCertificatesReceived (callback: (senderPublicKey: string, certs: VerifiableCertificate[]) => void): number {
|
|
200
200
|
const callbackID = this.callbackIdCounter++
|
|
201
201
|
this.onCertificatesReceivedCallbacks.set(callbackID, callback)
|
|
202
202
|
return callbackID
|
|
@@ -207,7 +207,7 @@ export class Peer {
|
|
|
207
207
|
*
|
|
208
208
|
* @param {number} callbackID - The ID of the certificates received callback to cancel.
|
|
209
209
|
*/
|
|
210
|
-
stopListeningForCertificatesReceived(callbackID: number): void {
|
|
210
|
+
stopListeningForCertificatesReceived (callbackID: number): void {
|
|
211
211
|
this.onCertificatesReceivedCallbacks.delete(callbackID)
|
|
212
212
|
}
|
|
213
213
|
|
|
@@ -217,7 +217,7 @@ export class Peer {
|
|
|
217
217
|
* @param {(requestedCertificates: RequestedCertificateSet) => void} callback - The function to call when a certificate request is received
|
|
218
218
|
* @returns {number} The ID of the callback listener.
|
|
219
219
|
*/
|
|
220
|
-
listenForCertificatesRequested(callback: (senderPublicKey: string, requestedCertificates: RequestedCertificateSet) => void): number {
|
|
220
|
+
listenForCertificatesRequested (callback: (senderPublicKey: string, requestedCertificates: RequestedCertificateSet) => void): number {
|
|
221
221
|
const callbackID = this.callbackIdCounter++
|
|
222
222
|
this.onCertificateRequestReceivedCallbacks.set(callbackID, callback)
|
|
223
223
|
return callbackID
|
|
@@ -228,7 +228,7 @@ export class Peer {
|
|
|
228
228
|
*
|
|
229
229
|
* @param {number} callbackID - The ID of the requested certificates callback to cancel.
|
|
230
230
|
*/
|
|
231
|
-
stopListeningForCertificatesRequested(callbackID: number): void {
|
|
231
|
+
stopListeningForCertificatesRequested (callbackID: number): void {
|
|
232
232
|
this.onCertificateRequestReceivedCallbacks.delete(callbackID)
|
|
233
233
|
}
|
|
234
234
|
|
|
@@ -239,7 +239,7 @@ export class Peer {
|
|
|
239
239
|
* @param {string} [identityKey] - The identity public key of the peer.
|
|
240
240
|
* @returns {Promise<string>} A promise that resolves to the session nonce.
|
|
241
241
|
*/
|
|
242
|
-
private async initiateHandshake(identityKey?: string, maxWaitTime = 10000): Promise<string> {
|
|
242
|
+
private async initiateHandshake (identityKey?: string, maxWaitTime = 10000): Promise<string> {
|
|
243
243
|
const sessionNonce = await createNonce(this.wallet) // Initial request nonce
|
|
244
244
|
this.sessionManager.addSession({
|
|
245
245
|
isAuthenticated: false,
|
|
@@ -265,7 +265,7 @@ export class Peer {
|
|
|
265
265
|
* @param {string} sessionNonce - The session nonce created in the initial request.
|
|
266
266
|
* @returns {Promise<string>} A promise that resolves with the session nonce when the initial response is received.
|
|
267
267
|
*/
|
|
268
|
-
private async waitForInitialResponse(sessionNonce: string, maxWaitTime = 10000): Promise<string> {
|
|
268
|
+
private async waitForInitialResponse (sessionNonce: string, maxWaitTime = 10000): Promise<string> {
|
|
269
269
|
return await new Promise((resolve, reject) => {
|
|
270
270
|
const callbackID = this.listenForInitialResponse(sessionNonce, (sessionNonce) => {
|
|
271
271
|
clearTimeout(timeoutHandle)
|
|
@@ -288,7 +288,7 @@ export class Peer {
|
|
|
288
288
|
* @param {(sessionNonce: string) => void} callback - The callback to invoke when the initial response is received.
|
|
289
289
|
* @returns {number} The ID of the callback listener.
|
|
290
290
|
*/
|
|
291
|
-
private listenForInitialResponse(sessionNonce: string, callback: (sessionNonce: string) => void) {
|
|
291
|
+
private listenForInitialResponse (sessionNonce: string, callback: (sessionNonce: string) => void) {
|
|
292
292
|
const callbackID = this.callbackIdCounter++
|
|
293
293
|
this.onInitialResponseReceivedCallbacks.set(callbackID, { callback, sessionNonce })
|
|
294
294
|
return callbackID
|
|
@@ -300,7 +300,7 @@ export class Peer {
|
|
|
300
300
|
* @private
|
|
301
301
|
* @param {number} callbackID - The ID of the callback to remove.
|
|
302
302
|
*/
|
|
303
|
-
private stopListeningForInitialResponses(callbackID: number) {
|
|
303
|
+
private stopListeningForInitialResponses (callbackID: number) {
|
|
304
304
|
this.onInitialResponseReceivedCallbacks.delete(callbackID)
|
|
305
305
|
}
|
|
306
306
|
|
|
@@ -310,7 +310,7 @@ export class Peer {
|
|
|
310
310
|
* @param {AuthMessage} message - The incoming message to process.
|
|
311
311
|
* @returns {Promise<void>}
|
|
312
312
|
*/
|
|
313
|
-
private async handleIncomingMessage(message: AuthMessage): Promise<void> {
|
|
313
|
+
private async handleIncomingMessage (message: AuthMessage): Promise<void> {
|
|
314
314
|
if (!message.version || message.version !== AUTH_VERSION) {
|
|
315
315
|
console.error(`Invalid message auth version! Received: ${message.version}, expected: ${AUTH_VERSION}`)
|
|
316
316
|
return
|
|
@@ -343,7 +343,7 @@ export class Peer {
|
|
|
343
343
|
* @param {AuthMessage} message - The incoming initial request message.
|
|
344
344
|
* @returns {Promise<void>}
|
|
345
345
|
*/
|
|
346
|
-
async processInitialRequest(message: AuthMessage) {
|
|
346
|
+
async processInitialRequest (message: AuthMessage) {
|
|
347
347
|
if (!message.identityKey || !message.initialNonce) {
|
|
348
348
|
throw new Error('Missing required fields in initialResponse message.')
|
|
349
349
|
}
|
|
@@ -406,7 +406,7 @@ export class Peer {
|
|
|
406
406
|
* @returns {Promise<void>}
|
|
407
407
|
* @throws Will throw an error if nonce verification or signature verification fails.
|
|
408
408
|
*/
|
|
409
|
-
private async processInitialResponse(message: AuthMessage) {
|
|
409
|
+
private async processInitialResponse (message: AuthMessage) {
|
|
410
410
|
const validNonce = await verifyNonce(message.yourNonce, this.wallet)
|
|
411
411
|
if (!validNonce) {
|
|
412
412
|
throw new Error(`Initial response nonce verification failed from peer: ${message.identityKey}`)
|
|
@@ -478,7 +478,7 @@ export class Peer {
|
|
|
478
478
|
* @param {AuthMessage} message - The certificate request message received from the peer.
|
|
479
479
|
* @throws {Error} Throws an error if nonce verification fails, or the message signature is invalid.
|
|
480
480
|
*/
|
|
481
|
-
private async processCertificateRequest(message: AuthMessage) {
|
|
481
|
+
private async processCertificateRequest (message: AuthMessage) {
|
|
482
482
|
const validNonce = await verifyNonce(message.yourNonce, this.wallet)
|
|
483
483
|
if (!validNonce) {
|
|
484
484
|
throw new Error(`Unable to verify nonce for certificate request message from: ${message.identityKey}`)
|
|
@@ -520,7 +520,7 @@ export class Peer {
|
|
|
520
520
|
*
|
|
521
521
|
* @throws {Error} Throws an error if the peer session could not be authenticated or if message signing fails.
|
|
522
522
|
*/
|
|
523
|
-
async sendCertificateResponse(
|
|
523
|
+
async sendCertificateResponse (
|
|
524
524
|
verifierIdentityKey: string,
|
|
525
525
|
certificates: VerifiableCertificate[]
|
|
526
526
|
) {
|
|
@@ -559,7 +559,7 @@ export class Peer {
|
|
|
559
559
|
* @returns {Promise<void>}
|
|
560
560
|
* @throws Will throw an error if nonce verification or signature verification fails.
|
|
561
561
|
*/
|
|
562
|
-
private async processCertificateResponse(
|
|
562
|
+
private async processCertificateResponse (
|
|
563
563
|
message: AuthMessage
|
|
564
564
|
) {
|
|
565
565
|
const validNonce = await verifyNonce(message.yourNonce, this.wallet)
|
|
@@ -597,7 +597,7 @@ export class Peer {
|
|
|
597
597
|
* @returns {Promise<void>}
|
|
598
598
|
* @throws Will throw an error if nonce verification or signature verification fails.
|
|
599
599
|
*/
|
|
600
|
-
private async processGeneralMessage(message: AuthMessage) {
|
|
600
|
+
private async processGeneralMessage (message: AuthMessage) {
|
|
601
601
|
const validNonce = await verifyNonce(message.yourNonce, this.wallet)
|
|
602
602
|
if (!validNonce) {
|
|
603
603
|
throw new Error(`Unable to verify nonce for general message from: ${message.identityKey}`)
|
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
import { PrivateKey } from '../../../../dist/cjs/src/primitives/index.js'
|
|
2
|
-
import { ProtoWallet } from '../../../../dist/cjs/src/wallet/
|
|
3
|
-
import {
|
|
1
|
+
import { PrivateKey, Random, Utils } from '../../../../dist/cjs/src/primitives/index.js'
|
|
2
|
+
import { ProtoWallet } from '../../../../dist/cjs/src/wallet/ProtoWallet.js'
|
|
3
|
+
import { WalletInterface } from '../../../../dist/cjs/src/wallet/Wallet.interfaces.js'
|
|
4
4
|
import { createNonce } from '../../../../dist/cjs/src/auth/utils/createNonce.js'
|
|
5
5
|
import { verifyNonce } from '../../../../dist/cjs/src/auth/utils/verifyNonce.js'
|
|
6
|
+
import { hash256 } from '../../../../dist/cjs/src/primitives/Hash.js'
|
|
6
7
|
|
|
7
8
|
describe('createNonce', () => {
|
|
8
|
-
let mockWallet:
|
|
9
|
+
let mockWallet: WalletInterface
|
|
9
10
|
|
|
10
11
|
beforeEach(() => {
|
|
11
12
|
mockWallet = {
|
|
12
13
|
createHmac: jest.fn().mockResolvedValue({ hmac: new Uint8Array(16) }),
|
|
13
|
-
} as unknown as
|
|
14
|
+
} as unknown as WalletInterface
|
|
14
15
|
})
|
|
15
16
|
|
|
16
17
|
afterEach(() => {
|
|
@@ -31,13 +32,13 @@ describe('createNonce', () => {
|
|
|
31
32
|
})
|
|
32
33
|
|
|
33
34
|
describe('verifyNonce', () => {
|
|
34
|
-
let mockWallet:
|
|
35
|
+
let mockWallet: WalletInterface
|
|
35
36
|
|
|
36
37
|
beforeEach(() => {
|
|
37
38
|
mockWallet = {
|
|
38
39
|
createHmac: jest.fn().mockResolvedValue({ hmac: new Uint8Array(16) }),
|
|
39
40
|
verifyHmac: jest.fn().mockResolvedValue({ valid: true }),
|
|
40
|
-
} as unknown as
|
|
41
|
+
} as unknown as WalletInterface
|
|
41
42
|
})
|
|
42
43
|
|
|
43
44
|
afterEach(() => {
|
|
@@ -81,4 +82,38 @@ describe('verifyNonce', () => {
|
|
|
81
82
|
|
|
82
83
|
expect(isValid).toEqual(true)
|
|
83
84
|
})
|
|
85
|
+
|
|
86
|
+
it('SerialNumber use-case', async () => {
|
|
87
|
+
const clientWallet = new ProtoWallet(PrivateKey.fromRandom())
|
|
88
|
+
const serverWallet = new ProtoWallet(PrivateKey.fromRandom())
|
|
89
|
+
|
|
90
|
+
// Client creates a random nonce that the server can verify
|
|
91
|
+
const clientNonce = await createNonce(clientWallet, (await serverWallet.getPublicKey({ identityKey: true })).publicKey)
|
|
92
|
+
// The server verifies the client created the nonce provided
|
|
93
|
+
await verifyNonce(clientNonce, serverWallet, (await clientWallet.getPublicKey({ identityKey: true })).publicKey)
|
|
94
|
+
// Server creates a random nonce that the client can verify
|
|
95
|
+
const serverNonce = await createNonce(serverWallet, (await clientWallet.getPublicKey({ identityKey: true })).publicKey)
|
|
96
|
+
// The server compute a serial number from the client and server nonce
|
|
97
|
+
const { hmac: serialNumber } = await serverWallet.createHmac({
|
|
98
|
+
data: clientNonce + serverNonce,
|
|
99
|
+
protocolID: [2, 'certificate creation'],
|
|
100
|
+
keyID: serverNonce + clientNonce,
|
|
101
|
+
counterparty: (await clientWallet.getPublicKey({ identityKey: true })).publicKey
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
// Client verifies server's nonce
|
|
105
|
+
await verifyNonce(serverNonce, clientWallet, (await serverWallet.getPublicKey({ identityKey: true })).publicKey)
|
|
106
|
+
|
|
107
|
+
// Client verifies the server included their nonce
|
|
108
|
+
const { valid } = await clientWallet.verifyHmac({
|
|
109
|
+
hmac: serialNumber,
|
|
110
|
+
data: clientNonce + serverNonce,
|
|
111
|
+
protocolID: [2, 'certificate creation'],
|
|
112
|
+
keyID: serverNonce + clientNonce,
|
|
113
|
+
counterparty: (await serverWallet.getPublicKey({ identityKey: true })).publicKey,
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
console.log(Utils.toBase64(serialNumber))
|
|
117
|
+
expect(valid).toEqual(true)
|
|
118
|
+
})
|
|
84
119
|
})
|
|
@@ -1,15 +1,21 @@
|
|
|
1
|
-
import { Utils, Random, WalletInterface } from '../../../mod.js'
|
|
1
|
+
import { Utils, Random, WalletInterface, WalletCounterparty } from '../../../mod.js'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Creates a nonce derived from a
|
|
4
|
+
* Creates a nonce derived from a wallet
|
|
5
5
|
* @param wallet
|
|
6
|
+
* @param counterparty - The counterparty to the nonce creation. Defaults to 'self'.
|
|
6
7
|
* @returns A random nonce derived with a wallet
|
|
7
8
|
*/
|
|
8
|
-
export async function createNonce(wallet: WalletInterface): Promise<string> {
|
|
9
|
+
export async function createNonce(wallet: WalletInterface, counterparty: WalletCounterparty = 'self'): Promise<string> {
|
|
9
10
|
// Generate 16 random bytes for the first half of the data
|
|
10
11
|
const firstHalf = Random(16)
|
|
11
12
|
// Create an sha256 HMAC
|
|
12
|
-
const { hmac } = await wallet.createHmac({
|
|
13
|
+
const { hmac } = await wallet.createHmac({
|
|
14
|
+
protocolID: [2, 'server hmac'],
|
|
15
|
+
keyID: Utils.toUTF8(firstHalf),
|
|
16
|
+
data: firstHalf,
|
|
17
|
+
counterparty
|
|
18
|
+
})
|
|
13
19
|
// Concatenate firstHalf and secondHalf as the nonce bytes
|
|
14
20
|
const nonceBytes = [...firstHalf, ...hmac]
|
|
15
21
|
return Utils.toBase64(nonceBytes)
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { Utils, WalletInterface } from '../../../mod.js'
|
|
1
|
+
import { Utils, WalletCounterparty, WalletInterface } from '../../../mod.js'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Verifies a nonce derived from a wallet
|
|
5
5
|
* @param nonce - A nonce to verify as a base64 string.
|
|
6
6
|
* @param wallet
|
|
7
|
+
* @param counterparty - The counterparty to the nonce creation. Defaults to 'self'.
|
|
7
8
|
* @returns The status of the validation
|
|
8
9
|
*/
|
|
9
|
-
export async function verifyNonce(nonce: string, wallet: WalletInterface): Promise<boolean> {
|
|
10
|
+
export async function verifyNonce(nonce: string, wallet: WalletInterface, counterparty: WalletCounterparty = 'self'): Promise<boolean> {
|
|
10
11
|
// Convert nonce from base64 string to Uint8Array
|
|
11
12
|
const buffer = Utils.toArray(nonce, 'base64')
|
|
12
13
|
|
|
@@ -20,7 +21,7 @@ export async function verifyNonce(nonce: string, wallet: WalletInterface): Promi
|
|
|
20
21
|
hmac,
|
|
21
22
|
protocolID: [2, 'server hmac'],
|
|
22
23
|
keyID: Utils.toUTF8(data),
|
|
23
|
-
counterparty
|
|
24
|
+
counterparty
|
|
24
25
|
})
|
|
25
26
|
|
|
26
27
|
return valid
|
|
@@ -15,7 +15,7 @@ export default class OverlayAdminTokenTemplate implements ScriptTemplate {
|
|
|
15
15
|
* @param script Locking script comprising a SHIP or SLAP token to decode
|
|
16
16
|
* @returns Decoded SHIP or SLAP advertisement
|
|
17
17
|
*/
|
|
18
|
-
static decode(script: LockingScript): { protocol: 'SHIP' | 'SLAP', identityKey: string, domain: string, topicOrService: string } {
|
|
18
|
+
static decode (script: LockingScript): { protocol: 'SHIP' | 'SLAP', identityKey: string, domain: string, topicOrService: string } {
|
|
19
19
|
const result = PushDrop.decode(script)
|
|
20
20
|
if (result.fields.length < 4) {
|
|
21
21
|
throw new Error('Invalid SHIP/SLAP advertisement!')
|
|
@@ -39,7 +39,7 @@ export default class OverlayAdminTokenTemplate implements ScriptTemplate {
|
|
|
39
39
|
* Constructs a new Overlay Admin template instance
|
|
40
40
|
* @param wallet Wallet to use for locking and unlocking
|
|
41
41
|
*/
|
|
42
|
-
constructor(wallet: WalletInterface) {
|
|
42
|
+
constructor (wallet: WalletInterface) {
|
|
43
43
|
this.pushDrop = new PushDrop(wallet)
|
|
44
44
|
}
|
|
45
45
|
|
|
@@ -50,7 +50,7 @@ export default class OverlayAdminTokenTemplate implements ScriptTemplate {
|
|
|
50
50
|
* @param topicOrService Topic or service to advertise
|
|
51
51
|
* @returns Locking script comprising the advertisement token
|
|
52
52
|
*/
|
|
53
|
-
async lock(protocol: 'SHIP' | 'SLAP', domain: string, topicOrService: string): Promise<LockingScript> {
|
|
53
|
+
async lock (protocol: 'SHIP' | 'SLAP', domain: string, topicOrService: string): Promise<LockingScript> {
|
|
54
54
|
const { publicKey: identityKey } = await this.pushDrop.wallet.getPublicKey({ identityKey: true })
|
|
55
55
|
return await this.pushDrop.lock(
|
|
56
56
|
[
|
|
@@ -70,7 +70,7 @@ export default class OverlayAdminTokenTemplate implements ScriptTemplate {
|
|
|
70
70
|
* @param protocol SHIP or SLAP, depending on the token to unlock
|
|
71
71
|
* @returns Script unlocker capable of unlocking the advertisement token
|
|
72
72
|
*/
|
|
73
|
-
unlock(protocol: 'SHIP' | 'SLAP'): {
|
|
73
|
+
unlock (protocol: 'SHIP' | 'SLAP'): {
|
|
74
74
|
sign: (tx: Transaction, inputIndex: number) => Promise<UnlockingScript>
|
|
75
75
|
estimateLength: (tx: Transaction, inputIndex: number) => Promise<number>
|
|
76
76
|
} {
|
|
@@ -35,14 +35,14 @@ import {
|
|
|
35
35
|
export class ProtoWallet {
|
|
36
36
|
keyDeriver: KeyDeriverApi
|
|
37
37
|
|
|
38
|
-
constructor(rootKeyOrKeyDeriver: PrivateKey | 'anyone' | KeyDeriverApi) {
|
|
38
|
+
constructor (rootKeyOrKeyDeriver: PrivateKey | 'anyone' | KeyDeriverApi) {
|
|
39
39
|
if (typeof (rootKeyOrKeyDeriver as KeyDeriver).identityKey !== 'string') {
|
|
40
40
|
rootKeyOrKeyDeriver = new KeyDeriver(rootKeyOrKeyDeriver as PrivateKey | 'anyone')
|
|
41
41
|
}
|
|
42
42
|
this.keyDeriver = rootKeyOrKeyDeriver as KeyDeriver
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
async getPublicKey(
|
|
45
|
+
async getPublicKey (
|
|
46
46
|
args: GetPublicKeyArgs
|
|
47
47
|
): Promise<{ publicKey: PubKeyHex }> {
|
|
48
48
|
if (args.identityKey) {
|
|
@@ -64,7 +64,7 @@ export class ProtoWallet {
|
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
async revealCounterpartyKeyLinkage(
|
|
67
|
+
async revealCounterpartyKeyLinkage (
|
|
68
68
|
args: RevealCounterpartyKeyLinkageArgs
|
|
69
69
|
): Promise<RevealCounterpartyKeyLinkageResult> {
|
|
70
70
|
const { publicKey: identityKey } = await this.getPublicKey({ identityKey: true })
|
|
@@ -98,7 +98,7 @@ export class ProtoWallet {
|
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
async revealSpecificKeyLinkage(
|
|
101
|
+
async revealSpecificKeyLinkage (
|
|
102
102
|
args: RevealSpecificKeyLinkageArgs
|
|
103
103
|
): Promise<RevealSpecificKeyLinkageResult> {
|
|
104
104
|
const { publicKey: identityKey } = await this.getPublicKey({ identityKey: true })
|
|
@@ -131,7 +131,7 @@ export class ProtoWallet {
|
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
-
async encrypt(
|
|
134
|
+
async encrypt (
|
|
135
135
|
args: WalletEncryptArgs
|
|
136
136
|
): Promise<WalletEncryptResult> {
|
|
137
137
|
const key = this.keyDeriver.deriveSymmetricKey(
|
|
@@ -142,7 +142,7 @@ export class ProtoWallet {
|
|
|
142
142
|
return { ciphertext: key.encrypt(args.plaintext) as number[] }
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
-
async decrypt(
|
|
145
|
+
async decrypt (
|
|
146
146
|
args: WalletDecryptArgs
|
|
147
147
|
): Promise<WalletDecryptResult> {
|
|
148
148
|
const key = this.keyDeriver.deriveSymmetricKey(
|
|
@@ -153,7 +153,7 @@ export class ProtoWallet {
|
|
|
153
153
|
return { plaintext: key.decrypt(args.ciphertext) as number[] }
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
-
async createHmac(
|
|
156
|
+
async createHmac (
|
|
157
157
|
args: CreateHmacArgs
|
|
158
158
|
): Promise<CreateHmacResult> {
|
|
159
159
|
const key = this.keyDeriver.deriveSymmetricKey(
|
|
@@ -164,7 +164,7 @@ export class ProtoWallet {
|
|
|
164
164
|
return { hmac: Hash.sha256hmac(key.toArray(), args.data) }
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
-
async verifyHmac(
|
|
167
|
+
async verifyHmac (
|
|
168
168
|
args: VerifyHmacArgs
|
|
169
169
|
): Promise<VerifyHmacResult> {
|
|
170
170
|
const key = this.keyDeriver.deriveSymmetricKey(
|
|
@@ -181,7 +181,7 @@ export class ProtoWallet {
|
|
|
181
181
|
return { valid }
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
-
async createSignature(
|
|
184
|
+
async createSignature (
|
|
185
185
|
args: CreateSignatureArgs
|
|
186
186
|
): Promise<CreateSignatureResult> {
|
|
187
187
|
if (!args.hashToDirectlySign && !args.data) {
|
|
@@ -196,7 +196,7 @@ export class ProtoWallet {
|
|
|
196
196
|
return { signature: ECDSA.sign(new BigNumber(hash), key, true).toDER() as number[] }
|
|
197
197
|
}
|
|
198
198
|
|
|
199
|
-
async verifySignature(
|
|
199
|
+
async verifySignature (
|
|
200
200
|
args: VerifySignatureArgs
|
|
201
201
|
): Promise<VerifySignatureResult> {
|
|
202
202
|
if (!args.hashToDirectlyVerify && !args.data) {
|