@towns-protocol/utils 0.0.368 → 0.0.370
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/delegate.d.ts +45 -0
- package/dist/delegate.d.ts.map +1 -0
- package/dist/delegate.js +85 -0
- package/dist/delegate.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +5 -3
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Delegate wallet authentication utilities
|
|
3
|
+
*
|
|
4
|
+
* These functions support delegate wallet signatures where a primary wallet
|
|
5
|
+
* authorizes a device/delegate wallet to sign on its behalf with an expiry time.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Creates the hash source for delegate authorization signature
|
|
9
|
+
*
|
|
10
|
+
* @param devicePublicKey - Uncompressed public key (64 or 65 bytes)
|
|
11
|
+
* @param expiryEpochMs - Expiry timestamp in milliseconds (0 = no expiry)
|
|
12
|
+
* @returns Hash source to be signed by primary wallet
|
|
13
|
+
*/
|
|
14
|
+
export declare function riverDelegateHashSrc(devicePublicKey: Uint8Array, expiryEpochMs: bigint): Uint8Array;
|
|
15
|
+
/**
|
|
16
|
+
* Converts uncompressed public key from string to Uint8Array
|
|
17
|
+
*
|
|
18
|
+
* @param publicKey - Public key string starting with '0x04' (132 chars total)
|
|
19
|
+
* @returns Public key as Uint8Array
|
|
20
|
+
*/
|
|
21
|
+
export declare function publicKeyToUint8Array(publicKey: string): Uint8Array;
|
|
22
|
+
/**
|
|
23
|
+
* Derives Ethereum address from public key
|
|
24
|
+
*
|
|
25
|
+
* @param publicKey - Uncompressed public key (64 or 65 bytes)
|
|
26
|
+
* @returns 20-byte Ethereum address
|
|
27
|
+
*/
|
|
28
|
+
export declare function publicKeyToAddress(publicKey: Uint8Array): Uint8Array;
|
|
29
|
+
/**
|
|
30
|
+
* Recovers the primary wallet address from a delegate signature
|
|
31
|
+
*
|
|
32
|
+
* This verifies that a delegate wallet was authorized by a primary wallet
|
|
33
|
+
* by recovering the primary wallet's address from the delegate authorization signature.
|
|
34
|
+
*
|
|
35
|
+
* @param params.delegatePubKey - Delegate wallet's public key (string or Uint8Array)
|
|
36
|
+
* @param params.delegateSig - Signature from primary wallet authorizing the delegate
|
|
37
|
+
* @param params.expiryEpochMs - Expiry timestamp that was signed
|
|
38
|
+
* @returns Primary wallet address (20 bytes)
|
|
39
|
+
*/
|
|
40
|
+
export declare function recoverPublicKeyFromDelegateSig(params: {
|
|
41
|
+
delegatePubKey: Uint8Array | string;
|
|
42
|
+
delegateSig: Uint8Array;
|
|
43
|
+
expiryEpochMs: bigint;
|
|
44
|
+
}): Uint8Array;
|
|
45
|
+
//# sourceMappingURL=delegate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delegate.d.ts","sourceRoot":"","sources":["../src/delegate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAkBH;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAChC,eAAe,EAAE,UAAU,EAC3B,aAAa,EAAE,MAAM,GACtB,UAAU,CAYZ;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,CAOnE;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,UAAU,GAAG,UAAU,CAMpE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,+BAA+B,CAAC,MAAM,EAAE;IACpD,cAAc,EAAE,UAAU,GAAG,MAAM,CAAA;IACnC,WAAW,EAAE,UAAU,CAAA;IACvB,aAAa,EAAE,MAAM,CAAA;CACxB,GAAG,UAAU,CAYb"}
|
package/dist/delegate.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Delegate wallet authentication utilities
|
|
3
|
+
*
|
|
4
|
+
* These functions support delegate wallet signatures where a primary wallet
|
|
5
|
+
* authorizes a device/delegate wallet to sign on its behalf with an expiry time.
|
|
6
|
+
*/
|
|
7
|
+
import { ecrecover, fromRPCSig, hashPersonalMessage } from '@ethereumjs/util';
|
|
8
|
+
import { bin_fromHexString, bin_toHexString } from './binary';
|
|
9
|
+
import { check } from './check';
|
|
10
|
+
import { keccak256 } from 'ethereum-cryptography/keccak';
|
|
11
|
+
import { abytes } from '@noble/hashes/utils';
|
|
12
|
+
// Header for delegate signature 'RIVERSIG'
|
|
13
|
+
const RIVER_SIG_HEADER = new Uint8Array([82, 73, 86, 69, 82, 83, 73, 71]);
|
|
14
|
+
function bigintToUint8Array64(num, endianMode) {
|
|
15
|
+
const buffer = new ArrayBuffer(8);
|
|
16
|
+
const view = new DataView(buffer);
|
|
17
|
+
view.setBigInt64(0, num, endianMode === 'littleEndian'); // true for little endian
|
|
18
|
+
return new Uint8Array(buffer);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Creates the hash source for delegate authorization signature
|
|
22
|
+
*
|
|
23
|
+
* @param devicePublicKey - Uncompressed public key (64 or 65 bytes)
|
|
24
|
+
* @param expiryEpochMs - Expiry timestamp in milliseconds (0 = no expiry)
|
|
25
|
+
* @returns Hash source to be signed by primary wallet
|
|
26
|
+
*/
|
|
27
|
+
export function riverDelegateHashSrc(devicePublicKey, expiryEpochMs) {
|
|
28
|
+
abytes(devicePublicKey);
|
|
29
|
+
check(expiryEpochMs >= 0, 'Expiry should be positive');
|
|
30
|
+
check(devicePublicKey.length === 64 || devicePublicKey.length === 65, 'Bad public key');
|
|
31
|
+
const expiryBytes = bigintToUint8Array64(expiryEpochMs, 'littleEndian');
|
|
32
|
+
const retVal = new Uint8Array(RIVER_SIG_HEADER.length + devicePublicKey.length + expiryBytes.length);
|
|
33
|
+
retVal.set(RIVER_SIG_HEADER);
|
|
34
|
+
retVal.set(devicePublicKey, RIVER_SIG_HEADER.length);
|
|
35
|
+
retVal.set(expiryBytes, RIVER_SIG_HEADER.length + devicePublicKey.length);
|
|
36
|
+
return retVal;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Converts uncompressed public key from string to Uint8Array
|
|
40
|
+
*
|
|
41
|
+
* @param publicKey - Public key string starting with '0x04' (132 chars total)
|
|
42
|
+
* @returns Public key as Uint8Array
|
|
43
|
+
*/
|
|
44
|
+
export function publicKeyToUint8Array(publicKey) {
|
|
45
|
+
// Uncompressed public key in string form should start with '0x04'.
|
|
46
|
+
check(typeof publicKey === 'string' && publicKey.startsWith('0x04') && publicKey.length === 132, 'Bad public key');
|
|
47
|
+
return bin_fromHexString(publicKey);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Derives Ethereum address from public key
|
|
51
|
+
*
|
|
52
|
+
* @param publicKey - Uncompressed public key (64 or 65 bytes)
|
|
53
|
+
* @returns 20-byte Ethereum address
|
|
54
|
+
*/
|
|
55
|
+
export function publicKeyToAddress(publicKey) {
|
|
56
|
+
abytes(publicKey, 64, 65);
|
|
57
|
+
if (publicKey.length === 65) {
|
|
58
|
+
publicKey = publicKey.slice(1);
|
|
59
|
+
}
|
|
60
|
+
return keccak256(publicKey).slice(-20);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Recovers the primary wallet address from a delegate signature
|
|
64
|
+
*
|
|
65
|
+
* This verifies that a delegate wallet was authorized by a primary wallet
|
|
66
|
+
* by recovering the primary wallet's address from the delegate authorization signature.
|
|
67
|
+
*
|
|
68
|
+
* @param params.delegatePubKey - Delegate wallet's public key (string or Uint8Array)
|
|
69
|
+
* @param params.delegateSig - Signature from primary wallet authorizing the delegate
|
|
70
|
+
* @param params.expiryEpochMs - Expiry timestamp that was signed
|
|
71
|
+
* @returns Primary wallet address (20 bytes)
|
|
72
|
+
*/
|
|
73
|
+
export function recoverPublicKeyFromDelegateSig(params) {
|
|
74
|
+
const { delegateSig, expiryEpochMs } = params;
|
|
75
|
+
const delegatePubKey = typeof params.delegatePubKey === 'string'
|
|
76
|
+
? publicKeyToUint8Array(params.delegatePubKey)
|
|
77
|
+
: params.delegatePubKey;
|
|
78
|
+
const hashSource = riverDelegateHashSrc(delegatePubKey, expiryEpochMs);
|
|
79
|
+
const hash = hashPersonalMessage(hashSource);
|
|
80
|
+
const { v, r, s } = fromRPCSig(('0x' + bin_toHexString(delegateSig)));
|
|
81
|
+
const recoveredCreatorPubKey = ecrecover(hash, v, r, s);
|
|
82
|
+
const recoveredCreatorAddress = Uint8Array.from(publicKeyToAddress(recoveredCreatorPubKey));
|
|
83
|
+
return recoveredCreatorAddress;
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=delegate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delegate.js","sourceRoot":"","sources":["../src/delegate.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;4EAE4E;AAC5E,cAAc,UAAU,CAAA;AACxB,cAAc,SAAS,CAAA;AACvB,cAAc,QAAQ,CAAA;AACtB,cAAc,YAAY,CAAA;AAC1B,cAAc,SAAS,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;4EAE4E;AAC5E,cAAc,UAAU,CAAA;AACxB,cAAc,SAAS,CAAA;AACvB,cAAc,YAAY,CAAA;AAC1B,cAAc,QAAQ,CAAA;AACtB,cAAc,YAAY,CAAA;AAC1B,cAAc,SAAS,CAAA"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;4EAE4E;AAC5E,cAAc,UAAU,CAAA;AACxB,cAAc,SAAS,CAAA;AACvB,cAAc,QAAQ,CAAA;AACtB,cAAc,YAAY,CAAA;AAC1B,cAAc,SAAS,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;4EAE4E;AAC5E,cAAc,UAAU,CAAA;AACxB,cAAc,SAAS,CAAA;AACvB,cAAc,YAAY,CAAA;AAC1B,cAAc,QAAQ,CAAA;AACtB,cAAc,YAAY,CAAA;AAC1B,cAAc,SAAS,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@towns-protocol/utils",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.370",
|
|
4
4
|
"packageManager": "yarn@3.8.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -19,7 +19,9 @@
|
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@bufbuild/protobuf": "^2.9.0",
|
|
22
|
-
"@
|
|
22
|
+
"@ethereumjs/util": "^10.0.0",
|
|
23
|
+
"@noble/hashes": "^1.8.0",
|
|
24
|
+
"@towns-protocol/proto": "^0.0.370",
|
|
23
25
|
"debug": "^4.3.4",
|
|
24
26
|
"ethereum-cryptography": "^3.2.0"
|
|
25
27
|
},
|
|
@@ -40,5 +42,5 @@
|
|
|
40
42
|
"publishConfig": {
|
|
41
43
|
"access": "public"
|
|
42
44
|
},
|
|
43
|
-
"gitHead": "
|
|
45
|
+
"gitHead": "a39b3d31251fbe2ec4f6c0902d9a5195974e8b9e"
|
|
44
46
|
}
|