bitcoincash-oauth-client 0.2.0 → 0.2.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/README.md +8 -0
- package/dist/index.browser.min.js +1 -1
- package/dist/index.cjs +35 -18
- package/dist/index.mjs +35 -18
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -258,13 +258,14 @@ function getFetch(userProvidedFetch = null) {
|
|
|
258
258
|
* @typedef {Object} Keypair
|
|
259
259
|
* @property {string} privateKey - Hex-encoded private key
|
|
260
260
|
* @property {string} publicKey - Hex-encoded compressed public key
|
|
261
|
-
* @property {string}
|
|
261
|
+
* @property {string} bitcoincash_address - Bitcoin Cash address
|
|
262
262
|
*/
|
|
263
263
|
|
|
264
264
|
/**
|
|
265
265
|
* @typedef {Object} OAuthClientOptions
|
|
266
266
|
* @property {string} [serverUrl="http://localhost:8000"] - OAuth server URL
|
|
267
267
|
* @property {string} [network="mainnet"] - Network type ("mainnet" or "testnet")
|
|
268
|
+
* @property {string} [authBasePath="/auth"] - Base path for auth endpoints (e.g., "/auth" or "/bch-auth")
|
|
268
269
|
* @property {SecureStorage} [secureStorage] - Storage interface for tokens
|
|
269
270
|
* @property {Function} [fetch] - Custom fetch implementation (optional)
|
|
270
271
|
* @property {string} [tokenKey="oauth_token"] - Key for storing access token
|
|
@@ -302,6 +303,7 @@ class BitcoinCashOAuthClient {
|
|
|
302
303
|
constructor(options = {}) {
|
|
303
304
|
this.serverUrl = options.serverUrl || "http://localhost:8000";
|
|
304
305
|
this.network = options.network || "mainnet";
|
|
306
|
+
this.authBasePath = options.authBasePath || "/auth";
|
|
305
307
|
this.secureStorage = options.secureStorage || null;
|
|
306
308
|
this.fetchImpl = options.fetch || getFetch(options.fetch);
|
|
307
309
|
this.secp256k1 = null;
|
|
@@ -372,14 +374,14 @@ class BitcoinCashOAuthClient {
|
|
|
372
374
|
const publicKeyBytes = this.secp256k1.derivePublicKeyCompressed(privateKeyBytes);
|
|
373
375
|
|
|
374
376
|
// Convert to address
|
|
375
|
-
const
|
|
376
|
-
|
|
377
|
-
this._log('Generated new keypair', {
|
|
377
|
+
const bitcoincash_address = await this.publicKeyToCashAddress(publicKeyBytes);
|
|
378
|
+
|
|
379
|
+
this._log('Generated new keypair', { bitcoincash_address });
|
|
378
380
|
|
|
379
381
|
return {
|
|
380
382
|
privateKey: this.bytesToHex(privateKeyBytes),
|
|
381
383
|
publicKey: this.bytesToHex(publicKeyBytes),
|
|
382
|
-
|
|
384
|
+
bitcoincash_address,
|
|
383
385
|
};
|
|
384
386
|
}
|
|
385
387
|
|
|
@@ -433,40 +435,55 @@ class BitcoinCashOAuthClient {
|
|
|
433
435
|
}
|
|
434
436
|
|
|
435
437
|
/**
|
|
436
|
-
* Register a new user with the server
|
|
437
|
-
* @param {string}
|
|
438
|
-
* @param {string}
|
|
438
|
+
* Register a new user with the server (signature required)
|
|
439
|
+
* @param {string} bitcoincash_address - Bitcoin Cash address
|
|
440
|
+
* @param {string} privateKeyHex - Private key for signing (hex-encoded)
|
|
441
|
+
* @param {string} publicKeyHex - Public key for signature verification (hex-encoded)
|
|
442
|
+
* @param {string} userId - User-provided ID (required)
|
|
443
|
+
* @param {number} [timestamp] - Optional Unix timestamp (defaults to now)
|
|
444
|
+
* @param {string} [domain] - Optional domain for message binding
|
|
439
445
|
* @returns {Promise<Object>} Registration result with assigned userId
|
|
440
446
|
* @throws {NetworkError} If network request fails
|
|
441
447
|
* @throws {AuthenticationError} If registration fails
|
|
442
448
|
*/
|
|
443
|
-
async register(
|
|
449
|
+
async register(bitcoincash_address, privateKeyHex, publicKeyHex, userId, timestamp = null, domain = null) {
|
|
444
450
|
try {
|
|
445
|
-
const
|
|
451
|
+
const ts = timestamp || Math.floor(Date.now() / 1000);
|
|
452
|
+
const host = domain || this._getDefaultDomain();
|
|
453
|
+
const message = this.createAuthMessage(userId, ts, host);
|
|
454
|
+
const signature = await this.signAuthMessage(message, privateKeyHex);
|
|
455
|
+
|
|
456
|
+
this._log('Registering user', { bitcoincash_address, userId, domain: host });
|
|
457
|
+
|
|
458
|
+
const response = await this.fetchImpl(`${this.serverUrl}${this.authBasePath}/register`, {
|
|
446
459
|
method: "POST",
|
|
447
460
|
headers: {
|
|
448
461
|
"Content-Type": "application/json",
|
|
449
462
|
},
|
|
450
463
|
body: JSON.stringify({
|
|
451
|
-
|
|
464
|
+
bitcoincash_address,
|
|
452
465
|
user_id: userId,
|
|
466
|
+
timestamp: ts,
|
|
467
|
+
domain: host,
|
|
468
|
+
public_key: publicKeyHex,
|
|
469
|
+
signature: signature,
|
|
453
470
|
}),
|
|
454
471
|
});
|
|
455
472
|
|
|
456
473
|
if (!response.ok) {
|
|
457
474
|
const errorData = await response.json().catch(() => ({}));
|
|
458
|
-
|
|
475
|
+
|
|
459
476
|
if (response.status === 404) {
|
|
460
477
|
throw new UserNotFoundError(errorData.detail || 'User not found');
|
|
461
478
|
}
|
|
462
|
-
|
|
479
|
+
|
|
463
480
|
throw new AuthenticationError(
|
|
464
481
|
errorData.detail || `Registration failed: ${response.statusText}`,
|
|
465
482
|
response.status
|
|
466
483
|
);
|
|
467
484
|
}
|
|
468
485
|
|
|
469
|
-
this._log('User registered successfully', {
|
|
486
|
+
this._log('User registered successfully', { bitcoincash_address, userId });
|
|
470
487
|
return await response.json();
|
|
471
488
|
} catch (error) {
|
|
472
489
|
if (error instanceof OAuthError) {
|
|
@@ -534,7 +551,7 @@ class BitcoinCashOAuthClient {
|
|
|
534
551
|
this._log('Message signed successfully');
|
|
535
552
|
|
|
536
553
|
try {
|
|
537
|
-
const response = await this.fetchImpl(`${this.serverUrl}/
|
|
554
|
+
const response = await this.fetchImpl(`${this.serverUrl}${this.authBasePath}/token`, {
|
|
538
555
|
method: "POST",
|
|
539
556
|
headers: {
|
|
540
557
|
"Content-Type": "application/json",
|
|
@@ -755,7 +772,7 @@ class BitcoinCashOAuthClient {
|
|
|
755
772
|
if (serverCheck) {
|
|
756
773
|
try {
|
|
757
774
|
this._log('Token validation: checking with server');
|
|
758
|
-
const response = await this.fetchImpl(`${this.serverUrl}/
|
|
775
|
+
const response = await this.fetchImpl(`${this.serverUrl}${this.authBasePath}/verify`, {
|
|
759
776
|
method: "POST",
|
|
760
777
|
headers: {
|
|
761
778
|
"Authorization": `Bearer ${token}`,
|
|
@@ -835,7 +852,7 @@ class BitcoinCashOAuthClient {
|
|
|
835
852
|
*/
|
|
836
853
|
async refreshToken(refreshToken) {
|
|
837
854
|
try {
|
|
838
|
-
const response = await this.fetchImpl(`${this.serverUrl}/
|
|
855
|
+
const response = await this.fetchImpl(`${this.serverUrl}${this.authBasePath}/refresh`, {
|
|
839
856
|
method: "POST",
|
|
840
857
|
headers: {
|
|
841
858
|
"Content-Type": "application/json",
|
|
@@ -904,7 +921,7 @@ class BitcoinCashOAuthClient {
|
|
|
904
921
|
this.refreshTimer = null;
|
|
905
922
|
}
|
|
906
923
|
|
|
907
|
-
const response = await this.fetchImpl(`${this.serverUrl}/
|
|
924
|
+
const response = await this.fetchImpl(`${this.serverUrl}${this.authBasePath}/revoke`, {
|
|
908
925
|
method: "POST",
|
|
909
926
|
headers: {
|
|
910
927
|
"Content-Type": "application/json",
|
package/dist/index.mjs
CHANGED
|
@@ -254,13 +254,14 @@ function getFetch(userProvidedFetch = null) {
|
|
|
254
254
|
* @typedef {Object} Keypair
|
|
255
255
|
* @property {string} privateKey - Hex-encoded private key
|
|
256
256
|
* @property {string} publicKey - Hex-encoded compressed public key
|
|
257
|
-
* @property {string}
|
|
257
|
+
* @property {string} bitcoincash_address - Bitcoin Cash address
|
|
258
258
|
*/
|
|
259
259
|
|
|
260
260
|
/**
|
|
261
261
|
* @typedef {Object} OAuthClientOptions
|
|
262
262
|
* @property {string} [serverUrl="http://localhost:8000"] - OAuth server URL
|
|
263
263
|
* @property {string} [network="mainnet"] - Network type ("mainnet" or "testnet")
|
|
264
|
+
* @property {string} [authBasePath="/auth"] - Base path for auth endpoints (e.g., "/auth" or "/bch-auth")
|
|
264
265
|
* @property {SecureStorage} [secureStorage] - Storage interface for tokens
|
|
265
266
|
* @property {Function} [fetch] - Custom fetch implementation (optional)
|
|
266
267
|
* @property {string} [tokenKey="oauth_token"] - Key for storing access token
|
|
@@ -298,6 +299,7 @@ class BitcoinCashOAuthClient {
|
|
|
298
299
|
constructor(options = {}) {
|
|
299
300
|
this.serverUrl = options.serverUrl || "http://localhost:8000";
|
|
300
301
|
this.network = options.network || "mainnet";
|
|
302
|
+
this.authBasePath = options.authBasePath || "/auth";
|
|
301
303
|
this.secureStorage = options.secureStorage || null;
|
|
302
304
|
this.fetchImpl = options.fetch || getFetch(options.fetch);
|
|
303
305
|
this.secp256k1 = null;
|
|
@@ -368,14 +370,14 @@ class BitcoinCashOAuthClient {
|
|
|
368
370
|
const publicKeyBytes = this.secp256k1.derivePublicKeyCompressed(privateKeyBytes);
|
|
369
371
|
|
|
370
372
|
// Convert to address
|
|
371
|
-
const
|
|
372
|
-
|
|
373
|
-
this._log('Generated new keypair', {
|
|
373
|
+
const bitcoincash_address = await this.publicKeyToCashAddress(publicKeyBytes);
|
|
374
|
+
|
|
375
|
+
this._log('Generated new keypair', { bitcoincash_address });
|
|
374
376
|
|
|
375
377
|
return {
|
|
376
378
|
privateKey: this.bytesToHex(privateKeyBytes),
|
|
377
379
|
publicKey: this.bytesToHex(publicKeyBytes),
|
|
378
|
-
|
|
380
|
+
bitcoincash_address,
|
|
379
381
|
};
|
|
380
382
|
}
|
|
381
383
|
|
|
@@ -429,40 +431,55 @@ class BitcoinCashOAuthClient {
|
|
|
429
431
|
}
|
|
430
432
|
|
|
431
433
|
/**
|
|
432
|
-
* Register a new user with the server
|
|
433
|
-
* @param {string}
|
|
434
|
-
* @param {string}
|
|
434
|
+
* Register a new user with the server (signature required)
|
|
435
|
+
* @param {string} bitcoincash_address - Bitcoin Cash address
|
|
436
|
+
* @param {string} privateKeyHex - Private key for signing (hex-encoded)
|
|
437
|
+
* @param {string} publicKeyHex - Public key for signature verification (hex-encoded)
|
|
438
|
+
* @param {string} userId - User-provided ID (required)
|
|
439
|
+
* @param {number} [timestamp] - Optional Unix timestamp (defaults to now)
|
|
440
|
+
* @param {string} [domain] - Optional domain for message binding
|
|
435
441
|
* @returns {Promise<Object>} Registration result with assigned userId
|
|
436
442
|
* @throws {NetworkError} If network request fails
|
|
437
443
|
* @throws {AuthenticationError} If registration fails
|
|
438
444
|
*/
|
|
439
|
-
async register(
|
|
445
|
+
async register(bitcoincash_address, privateKeyHex, publicKeyHex, userId, timestamp = null, domain = null) {
|
|
440
446
|
try {
|
|
441
|
-
const
|
|
447
|
+
const ts = timestamp || Math.floor(Date.now() / 1000);
|
|
448
|
+
const host = domain || this._getDefaultDomain();
|
|
449
|
+
const message = this.createAuthMessage(userId, ts, host);
|
|
450
|
+
const signature = await this.signAuthMessage(message, privateKeyHex);
|
|
451
|
+
|
|
452
|
+
this._log('Registering user', { bitcoincash_address, userId, domain: host });
|
|
453
|
+
|
|
454
|
+
const response = await this.fetchImpl(`${this.serverUrl}${this.authBasePath}/register`, {
|
|
442
455
|
method: "POST",
|
|
443
456
|
headers: {
|
|
444
457
|
"Content-Type": "application/json",
|
|
445
458
|
},
|
|
446
459
|
body: JSON.stringify({
|
|
447
|
-
|
|
460
|
+
bitcoincash_address,
|
|
448
461
|
user_id: userId,
|
|
462
|
+
timestamp: ts,
|
|
463
|
+
domain: host,
|
|
464
|
+
public_key: publicKeyHex,
|
|
465
|
+
signature: signature,
|
|
449
466
|
}),
|
|
450
467
|
});
|
|
451
468
|
|
|
452
469
|
if (!response.ok) {
|
|
453
470
|
const errorData = await response.json().catch(() => ({}));
|
|
454
|
-
|
|
471
|
+
|
|
455
472
|
if (response.status === 404) {
|
|
456
473
|
throw new UserNotFoundError(errorData.detail || 'User not found');
|
|
457
474
|
}
|
|
458
|
-
|
|
475
|
+
|
|
459
476
|
throw new AuthenticationError(
|
|
460
477
|
errorData.detail || `Registration failed: ${response.statusText}`,
|
|
461
478
|
response.status
|
|
462
479
|
);
|
|
463
480
|
}
|
|
464
481
|
|
|
465
|
-
this._log('User registered successfully', {
|
|
482
|
+
this._log('User registered successfully', { bitcoincash_address, userId });
|
|
466
483
|
return await response.json();
|
|
467
484
|
} catch (error) {
|
|
468
485
|
if (error instanceof OAuthError) {
|
|
@@ -530,7 +547,7 @@ class BitcoinCashOAuthClient {
|
|
|
530
547
|
this._log('Message signed successfully');
|
|
531
548
|
|
|
532
549
|
try {
|
|
533
|
-
const response = await this.fetchImpl(`${this.serverUrl}/
|
|
550
|
+
const response = await this.fetchImpl(`${this.serverUrl}${this.authBasePath}/token`, {
|
|
534
551
|
method: "POST",
|
|
535
552
|
headers: {
|
|
536
553
|
"Content-Type": "application/json",
|
|
@@ -751,7 +768,7 @@ class BitcoinCashOAuthClient {
|
|
|
751
768
|
if (serverCheck) {
|
|
752
769
|
try {
|
|
753
770
|
this._log('Token validation: checking with server');
|
|
754
|
-
const response = await this.fetchImpl(`${this.serverUrl}/
|
|
771
|
+
const response = await this.fetchImpl(`${this.serverUrl}${this.authBasePath}/verify`, {
|
|
755
772
|
method: "POST",
|
|
756
773
|
headers: {
|
|
757
774
|
"Authorization": `Bearer ${token}`,
|
|
@@ -831,7 +848,7 @@ class BitcoinCashOAuthClient {
|
|
|
831
848
|
*/
|
|
832
849
|
async refreshToken(refreshToken) {
|
|
833
850
|
try {
|
|
834
|
-
const response = await this.fetchImpl(`${this.serverUrl}/
|
|
851
|
+
const response = await this.fetchImpl(`${this.serverUrl}${this.authBasePath}/refresh`, {
|
|
835
852
|
method: "POST",
|
|
836
853
|
headers: {
|
|
837
854
|
"Content-Type": "application/json",
|
|
@@ -900,7 +917,7 @@ class BitcoinCashOAuthClient {
|
|
|
900
917
|
this.refreshTimer = null;
|
|
901
918
|
}
|
|
902
919
|
|
|
903
|
-
const response = await this.fetchImpl(`${this.serverUrl}/
|
|
920
|
+
const response = await this.fetchImpl(`${this.serverUrl}${this.authBasePath}/revoke`, {
|
|
904
921
|
method: "POST",
|
|
905
922
|
headers: {
|
|
906
923
|
"Content-Type": "application/json",
|