@openzeppelin/miden-multisig-client 0.18.0 → 0.18.2
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 +176 -23
- package/dist/client.d.ts +41 -2
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +79 -2
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +7 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -4
- package/dist/index.js.map +1 -1
- package/dist/lookupAuth.d.ts.map +1 -1
- package/dist/lookupAuth.js +2 -20
- package/dist/lookupAuth.js.map +1 -1
- package/dist/multisig/authArgErrors.d.ts +27 -1
- package/dist/multisig/authArgErrors.d.ts.map +1 -1
- package/dist/multisig/authArgErrors.js +33 -0
- package/dist/multisig/authArgErrors.js.map +1 -1
- package/dist/multisig.d.ts +77 -11
- package/dist/multisig.d.ts.map +1 -1
- package/dist/multisig.js +247 -181
- package/dist/multisig.js.map +1 -1
- package/dist/proposal/metadata.d.ts.map +1 -1
- package/dist/proposal/metadata.js +2 -0
- package/dist/proposal/metadata.js.map +1 -1
- package/dist/recovery/transportDrain.d.ts +38 -30
- package/dist/recovery/transportDrain.d.ts.map +1 -1
- package/dist/recovery/transportDrain.js +113 -113
- package/dist/recovery/transportDrain.js.map +1 -1
- package/dist/session/grant.d.ts +40 -0
- package/dist/session/grant.d.ts.map +1 -0
- package/dist/session/grant.js +125 -0
- package/dist/session/grant.js.map +1 -0
- package/dist/session/key.d.ts +103 -0
- package/dist/session/key.d.ts.map +1 -0
- package/dist/session/key.js +160 -0
- package/dist/session/key.js.map +1 -0
- package/dist/session/manager.d.ts +76 -0
- package/dist/session/manager.d.ts.map +1 -0
- package/dist/session/manager.js +187 -0
- package/dist/session/manager.js.map +1 -0
- package/dist/signers/ecdsa.d.ts +5 -1
- package/dist/signers/ecdsa.d.ts.map +1 -1
- package/dist/signers/ecdsa.js +9 -0
- package/dist/signers/ecdsa.js.map +1 -1
- package/dist/signers/falcon.d.ts +5 -1
- package/dist/signers/falcon.d.ts.map +1 -1
- package/dist/signers/falcon.js +9 -0
- package/dist/signers/falcon.js.map +1 -1
- package/dist/signers/ledger.d.ts +9 -1
- package/dist/signers/ledger.d.ts.map +1 -1
- package/dist/signers/ledger.js +13 -1
- package/dist/signers/ledger.js.map +1 -1
- package/dist/signers/miden-wallet.d.ts +13 -1
- package/dist/signers/miden-wallet.d.ts.map +1 -1
- package/dist/signers/miden-wallet.js +25 -0
- package/dist/signers/miden-wallet.js.map +1 -1
- package/dist/signers/para.d.ts +5 -1
- package/dist/signers/para.d.ts.map +1 -1
- package/dist/signers/para.js +9 -0
- package/dist/signers/para.js.map +1 -1
- package/dist/transaction/authArgs.d.ts +2 -2
- package/dist/transaction/authArgs.js +2 -2
- package/dist/transaction/options.d.ts +2 -2
- package/dist/transaction/summary.d.ts +17 -61
- package/dist/transaction/summary.d.ts.map +1 -1
- package/dist/transaction/summary.js +49 -95
- package/dist/transaction/summary.js.map +1 -1
- package/dist/transaction.d.ts +1 -1
- package/dist/transaction.d.ts.map +1 -1
- package/dist/transaction.js +1 -1
- package/dist/transaction.js.map +1 -1
- package/dist/types/proposal.d.ts +11 -5
- package/dist/types/proposal.d.ts.map +1 -1
- package/dist/types/proposal.js.map +1 -1
- package/dist/utils/eip712.d.ts +26 -69
- package/dist/utils/eip712.d.ts.map +1 -1
- package/dist/utils/eip712.js +101 -8
- package/dist/utils/eip712.js.map +1 -1
- package/dist/utils/felt.d.ts +7 -1
- package/dist/utils/felt.d.ts.map +1 -1
- package/dist/utils/felt.js +18 -1
- package/dist/utils/felt.js.map +1 -1
- package/package.json +4 -4
- package/src/client.ts +97 -2
- package/src/index.ts +29 -8
- package/src/lookupAuth.ts +3 -22
- package/src/multisig/authArgErrors.ts +42 -1
- package/src/multisig.ts +318 -207
- package/src/proposal/metadata.ts +2 -0
- package/src/recovery/transportDrain.ts +118 -124
- package/src/session/grant.ts +143 -0
- package/src/session/key.ts +215 -0
- package/src/session/manager.ts +273 -0
- package/src/signers/ecdsa.ts +12 -1
- package/src/signers/falcon.ts +12 -1
- package/src/signers/ledger.ts +19 -2
- package/src/signers/miden-wallet.ts +29 -1
- package/src/signers/para.ts +12 -1
- package/src/transaction/authArgs.ts +2 -2
- package/src/transaction/options.ts +2 -2
- package/src/transaction/summary.ts +62 -110
- package/src/transaction.ts +1 -6
- package/src/types/proposal.ts +11 -5
- package/src/utils/eip712.ts +130 -10
- package/src/utils/felt.ts +19 -1
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { AuthDigest } from '../utils/digest.js';
|
|
2
|
+
import { EcdsaFormat } from '../utils/ecdsa.js';
|
|
3
|
+
import { bytesToHex } from '../utils/encoding.js';
|
|
4
|
+
import { wordToBytes } from '../utils/word.js';
|
|
5
|
+
import { sessionLogoutDigest } from './grant.js';
|
|
6
|
+
const ALGORITHM = { name: 'ECDSA', namedCurve: 'P-256' };
|
|
7
|
+
const SIGNATURE = { name: 'ECDSA', hash: 'SHA-256' };
|
|
8
|
+
function subtle() {
|
|
9
|
+
if (!globalThis.crypto?.subtle) {
|
|
10
|
+
throw new Error('Guardian sessions require WebCrypto (crypto.subtle)');
|
|
11
|
+
}
|
|
12
|
+
return globalThis.crypto.subtle;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* A P-256 session key whose private half is a non-extractable WebCrypto key:
|
|
16
|
+
* page scripts can use it to sign while it is loaded, but can never read or
|
|
17
|
+
* export it.
|
|
18
|
+
*/
|
|
19
|
+
export class WebCryptoSessionKey {
|
|
20
|
+
privateKey;
|
|
21
|
+
publicKey;
|
|
22
|
+
constructor(privateKey,
|
|
23
|
+
/** Hex SEC1-compressed public key. */
|
|
24
|
+
publicKey) {
|
|
25
|
+
this.privateKey = privateKey;
|
|
26
|
+
this.publicKey = publicKey;
|
|
27
|
+
}
|
|
28
|
+
static async generate() {
|
|
29
|
+
const pair = await subtle().generateKey(ALGORITHM, false, ['sign', 'verify']);
|
|
30
|
+
const raw = new Uint8Array(await subtle().exportKey('raw', pair.publicKey));
|
|
31
|
+
return new WebCryptoSessionKey(pair.privateKey, EcdsaFormat.compressPublicKey(bytesToHex(raw)));
|
|
32
|
+
}
|
|
33
|
+
/** Sign the 32 bytes of a word: ECDSA P-256 over SHA-256, `r || s` hex. */
|
|
34
|
+
async signWord(word) {
|
|
35
|
+
const message = new Uint8Array(wordToBytes(word));
|
|
36
|
+
const signature = await subtle().sign(SIGNATURE, this.privateKey, message);
|
|
37
|
+
return bytesToHex(new Uint8Array(signature));
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Signs Guardian requests for a wallet after its session grant was
|
|
42
|
+
* registered. Plug into `GuardianHttpClient.setSession`.
|
|
43
|
+
*/
|
|
44
|
+
export class GuardianSession {
|
|
45
|
+
key;
|
|
46
|
+
signerCommitment;
|
|
47
|
+
expiresAt;
|
|
48
|
+
storeId;
|
|
49
|
+
options;
|
|
50
|
+
constructor(key,
|
|
51
|
+
/** Commitment of the wallet that signed the grant. */
|
|
52
|
+
signerCommitment,
|
|
53
|
+
/** Unix seconds. */
|
|
54
|
+
expiresAt,
|
|
55
|
+
/** Where a `SessionKeyStore` keeps this session's key. */
|
|
56
|
+
storeId, options = {}) {
|
|
57
|
+
this.key = key;
|
|
58
|
+
this.signerCommitment = signerCommitment;
|
|
59
|
+
this.expiresAt = expiresAt;
|
|
60
|
+
this.storeId = storeId;
|
|
61
|
+
this.options = options;
|
|
62
|
+
}
|
|
63
|
+
get publicKey() {
|
|
64
|
+
return this.key.publicKey;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Forgets the stored key (best effort: a dead key left behind fails its
|
|
68
|
+
* first request after a reload and ends then) and tells the app.
|
|
69
|
+
*/
|
|
70
|
+
onEnded(reason) {
|
|
71
|
+
if (this.options.store) {
|
|
72
|
+
void forgetSessionKey(this.options.store, this).catch(() => undefined);
|
|
73
|
+
}
|
|
74
|
+
this.options.onEnded?.(reason, this);
|
|
75
|
+
}
|
|
76
|
+
signRequest(accountId, timestamp, requestPayload) {
|
|
77
|
+
return this.key.signWord(AuthDigest.fromRequest(accountId, timestamp, requestPayload));
|
|
78
|
+
}
|
|
79
|
+
signLogout(timestampMs) {
|
|
80
|
+
return this.key.signWord(sessionLogoutDigest(this.key.publicKey, timestampMs));
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Remove the stored key of `session`, unless the record already holds the key
|
|
85
|
+
* of a newer session for the same wallet and Guardian.
|
|
86
|
+
*/
|
|
87
|
+
export async function forgetSessionKey(store, session) {
|
|
88
|
+
await store.remove(session.storeId, session.publicKey);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Keeps session keys in IndexedDB so a reload does not need another wallet
|
|
92
|
+
* signature. The browser stores the `CryptoKey` object itself; it stays
|
|
93
|
+
* non-extractable.
|
|
94
|
+
*/
|
|
95
|
+
export class IndexedDbSessionKeyStore {
|
|
96
|
+
databaseName;
|
|
97
|
+
static STORE = 'sessions';
|
|
98
|
+
database = null;
|
|
99
|
+
constructor(databaseName = 'guardian-sessions') {
|
|
100
|
+
this.databaseName = databaseName;
|
|
101
|
+
}
|
|
102
|
+
async load(id) {
|
|
103
|
+
const record = await this.request('readonly', (store) => store.get(id));
|
|
104
|
+
return record ?? null;
|
|
105
|
+
}
|
|
106
|
+
async save(record) {
|
|
107
|
+
await this.request('readwrite', (store) => store.put(record));
|
|
108
|
+
}
|
|
109
|
+
async remove(id, publicKey) {
|
|
110
|
+
const database = await this.open();
|
|
111
|
+
return new Promise((resolve, reject) => {
|
|
112
|
+
const transaction = database.transaction(IndexedDbSessionKeyStore.STORE, 'readwrite');
|
|
113
|
+
const store = transaction.objectStore(IndexedDbSessionKeyStore.STORE);
|
|
114
|
+
const lookup = store.get(id);
|
|
115
|
+
lookup.onsuccess = () => {
|
|
116
|
+
if (lookup.result?.publicKey === publicKey) {
|
|
117
|
+
store.delete(id);
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
transaction.oncomplete = () => resolve();
|
|
121
|
+
transaction.onerror = () => reject(transaction.error);
|
|
122
|
+
transaction.onabort = () => reject(transaction.error);
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
async request(mode, run) {
|
|
126
|
+
const database = await this.open();
|
|
127
|
+
return new Promise((resolve, reject) => {
|
|
128
|
+
const transaction = database.transaction(IndexedDbSessionKeyStore.STORE, mode);
|
|
129
|
+
const request = run(transaction.objectStore(IndexedDbSessionKeyStore.STORE));
|
|
130
|
+
transaction.oncomplete = () => resolve(request.result);
|
|
131
|
+
transaction.onerror = () => reject(transaction.error ?? request.error);
|
|
132
|
+
transaction.onabort = () => reject(transaction.error ?? request.error);
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
/** Opens the database once; a failed open is retried on the next call. */
|
|
136
|
+
open() {
|
|
137
|
+
if (!this.database) {
|
|
138
|
+
const opening = new Promise((resolve, reject) => {
|
|
139
|
+
if (!globalThis.indexedDB) {
|
|
140
|
+
reject(new Error('IndexedDB is not available'));
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
const request = globalThis.indexedDB.open(this.databaseName, 1);
|
|
144
|
+
request.onupgradeneeded = () => {
|
|
145
|
+
request.result.createObjectStore(IndexedDbSessionKeyStore.STORE, { keyPath: 'id' });
|
|
146
|
+
};
|
|
147
|
+
request.onsuccess = () => resolve(request.result);
|
|
148
|
+
request.onerror = () => reject(request.error);
|
|
149
|
+
});
|
|
150
|
+
opening.catch(() => {
|
|
151
|
+
if (this.database === opening) {
|
|
152
|
+
this.database = null;
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
this.database = opening;
|
|
156
|
+
}
|
|
157
|
+
return this.database;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=key.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"key.js","sourceRoot":"","sources":["../../src/session/key.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,SAAS,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAW,CAAC;AAClE,MAAM,SAAS,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAW,CAAC;AAE9D,SAAS,MAAM;IACb,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACzE,CAAC;IACD,OAAO,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC;AAClC,CAAC;AAED;;;;GAIG;AACH,MAAM,OAAO,mBAAmB;IAEnB;IAEA;IAHX,YACW,UAAqB;IAC9B,sCAAsC;IAC7B,SAAiB;QAFjB,eAAU,GAAV,UAAU,CAAW;QAErB,cAAS,GAAT,SAAS,CAAQ;IACzB,CAAC;IAEJ,MAAM,CAAC,KAAK,CAAC,QAAQ;QACnB,MAAM,IAAI,GAAG,MAAM,MAAM,EAAE,CAAC,WAAW,CAAC,SAAS,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC9E,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,MAAM,MAAM,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;QAC5E,OAAO,IAAI,mBAAmB,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,iBAAiB,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAClG,CAAC;IAED,2EAA2E;IAC3E,KAAK,CAAC,QAAQ,CAAC,IAAU;QACvB,MAAM,OAAO,GAAG,IAAI,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;QAClD,MAAM,SAAS,GAAG,MAAM,MAAM,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAC3E,OAAO,UAAU,CAAC,IAAI,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;IAC/C,CAAC;CACF;AAcD;;;GAGG;AACH,MAAM,OAAO,eAAe;IAEP;IAER;IAEA;IAEA;IACQ;IARnB,YACmB,GAAwB;IACzC,sDAAsD;IAC7C,gBAAwB;IACjC,oBAAoB;IACX,SAAiB;IAC1B,0DAA0D;IACjD,OAAe,EACP,UAAkC,EAAE;QAPpC,QAAG,GAAH,GAAG,CAAqB;QAEhC,qBAAgB,GAAhB,gBAAgB,CAAQ;QAExB,cAAS,GAAT,SAAS,CAAQ;QAEjB,YAAO,GAAP,OAAO,CAAQ;QACP,YAAO,GAAP,OAAO,CAA6B;IACpD,CAAC;IAEJ,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC;IAC5B,CAAC;IAED;;;OAGG;IACH,OAAO,CAAC,MAAwB;QAC9B,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACvB,KAAK,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QACzE,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACvC,CAAC;IAED,WAAW,CACT,SAAiB,EACjB,SAAiB,EACjB,cAAkC;QAElC,OAAO,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,WAAW,CAAC,SAAS,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC,CAAC;IACzF,CAAC;IAED,UAAU,CAAC,WAAmB;QAC5B,OAAO,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC;IACjF,CAAC;CACF;AAuBD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,KAAsB,EACtB,OAA+C;IAE/C,MAAM,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;AACzD,CAAC;AAED;;;;GAIG;AACH,MAAM,OAAO,wBAAwB;IAIN;IAHrB,MAAM,CAAU,KAAK,GAAG,UAAU,CAAC;IACnC,QAAQ,GAAgC,IAAI,CAAC;IAErD,YAA6B,eAAe,mBAAmB;QAAlC,iBAAY,GAAZ,YAAY,CAAsB;IAAG,CAAC;IAEnE,KAAK,CAAC,IAAI,CAAC,EAAU;QACnB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAA+B,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE,CACpF,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CACd,CAAC;QACF,OAAO,MAAM,IAAI,IAAI,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,MAAwB;QACjC,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;IAChE,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAU,EAAE,SAAiB;QACxC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QACnC,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC3C,MAAM,WAAW,GAAG,QAAQ,CAAC,WAAW,CAAC,wBAAwB,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;YACtF,MAAM,KAAK,GAAG,WAAW,CAAC,WAAW,CAAC,wBAAwB,CAAC,KAAK,CAAC,CAAC;YACtE,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC7B,MAAM,CAAC,SAAS,GAAG,GAAG,EAAE;gBACtB,IAAK,MAAM,CAAC,MAAuC,EAAE,SAAS,KAAK,SAAS,EAAE,CAAC;oBAC7E,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBACnB,CAAC;YACH,CAAC,CAAC;YACF,WAAW,CAAC,UAAU,GAAG,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;YACzC,WAAW,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;YACtD,WAAW,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACxD,CAAC,CAAC,CAAC;IACL,CAAC;IAGO,KAAK,CAAC,OAAO,CACnB,IAAwB,EACxB,GAA0C;QAE1C,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QACnC,OAAO,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACxC,MAAM,WAAW,GAAG,QAAQ,CAAC,WAAW,CAAC,wBAAwB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YAC/E,MAAM,OAAO,GAAG,GAAG,CAAC,WAAW,CAAC,WAAW,CAAC,wBAAwB,CAAC,KAAK,CAAC,CAAC,CAAC;YAC7E,WAAW,CAAC,UAAU,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,MAAW,CAAC,CAAC;YAC5D,WAAW,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC;YACvE,WAAW,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC;QACzE,CAAC,CAAC,CAAC;IACL,CAAC;IAED,0EAA0E;IAClE,IAAI;QACV,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,MAAM,OAAO,GAAG,IAAI,OAAO,CAAc,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC3D,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC;oBAC1B,MAAM,CAAC,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC,CAAC;oBAChD,OAAO;gBACT,CAAC;gBACD,MAAM,OAAO,GAAG,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;gBAChE,OAAO,CAAC,eAAe,GAAG,GAAG,EAAE;oBAC7B,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAC,wBAAwB,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;gBACtF,CAAC,CAAC;gBACF,OAAO,CAAC,SAAS,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;gBAClD,OAAO,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAChD,CAAC,CAAC,CAAC;YACH,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE;gBACjB,IAAI,IAAI,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;oBAC9B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;gBACvB,CAAC;YACH,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;QAC1B,CAAC;QACD,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { GuardianHttpClient, SessionGrantFields, Signer } from '@openzeppelin/guardian-client';
|
|
2
|
+
import { GuardianSession, type GuardianSessionOptions, type SessionKeyStore } from './key.js';
|
|
3
|
+
/** The Guardian does not advertise sessions on `GET /status`. */
|
|
4
|
+
export declare class GuardianSessionsUnsupportedError extends Error {
|
|
5
|
+
constructor();
|
|
6
|
+
}
|
|
7
|
+
/** `confirm` returned `false`: the user declined the grant. */
|
|
8
|
+
export declare class SessionGrantDeclinedError extends Error {
|
|
9
|
+
constructor();
|
|
10
|
+
}
|
|
11
|
+
export interface StartSessionOptions extends Pick<GuardianSessionOptions, 'onEnded'> {
|
|
12
|
+
/**
|
|
13
|
+
* Requested lifetime, more than 300 seconds; capped below the Guardian's
|
|
14
|
+
* advertised maximum.
|
|
15
|
+
*/
|
|
16
|
+
ttlSeconds?: number;
|
|
17
|
+
/**
|
|
18
|
+
* The website asking for the session, shown to the user by the wallet.
|
|
19
|
+
* Defaults to the page's `location.origin` in a browser and to none
|
|
20
|
+
* elsewhere. Guardian does not check it against requests.
|
|
21
|
+
*/
|
|
22
|
+
origin?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Called with the grant before the wallet signs it; return `false` to
|
|
25
|
+
* abort. Required for raw (non-EIP-712) wallets, which show only a hash:
|
|
26
|
+
* display {@link describeSessionGrant} to the user here.
|
|
27
|
+
*/
|
|
28
|
+
confirm?: (grant: SessionGrantFields) => boolean | Promise<boolean>;
|
|
29
|
+
/** Persist the session key so a reload can `resume` without the wallet. */
|
|
30
|
+
store?: SessionKeyStore;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Start a Guardian session: `signer` signs one grant and, once the session is
|
|
34
|
+
* registered, becomes `guardian`'s signer; a non-extractable P-256 delegated
|
|
35
|
+
* signer then signs the
|
|
36
|
+
* session-eligible requests on `guardian` (reads, proposal list/get, proposal
|
|
37
|
+
* create/sign). Every other route, including `configure`, `pushDelta`,
|
|
38
|
+
* `abandonCandidate`, account lookup and `revokeAllSessions`, keeps using the
|
|
39
|
+
* wallet. A session already set on `guardian` is replaced but stays valid on
|
|
40
|
+
* the server until it expires; end it first with {@link endGuardianSession}.
|
|
41
|
+
*
|
|
42
|
+
* The grant is dated after `confirm` returns, so a slow confirmation still
|
|
43
|
+
* registers; only its start moves, the confirmed expiry stays. If storing the
|
|
44
|
+
* key fails, the registered session is logged out and the error rethrown.
|
|
45
|
+
*/
|
|
46
|
+
export declare function startGuardianSession(guardian: GuardianHttpClient, signer: Signer, options?: StartSessionOptions): Promise<GuardianSession>;
|
|
47
|
+
/**
|
|
48
|
+
* Reuse a session key persisted by `startGuardianSession` without asking the
|
|
49
|
+
* wallet again; `signer` becomes `guardian`'s signer when a session resumes.
|
|
50
|
+
* Returns `null` when none
|
|
51
|
+
* is stored or it expires within 30 seconds. A session revoked elsewhere
|
|
52
|
+
* fails its next request with `session_revoked` and ends then (`onEnded`);
|
|
53
|
+
* start a new one.
|
|
54
|
+
*/
|
|
55
|
+
export declare function resumeGuardianSession(guardian: GuardianHttpClient, signer: Signer, store: SessionKeyStore, options?: Pick<GuardianSessionOptions, 'onEnded'>): Promise<GuardianSession | null>;
|
|
56
|
+
/**
|
|
57
|
+
* Revoke `session` on the server, stop using it if it is the current one, and
|
|
58
|
+
* forget its stored key. Returns whether the server still had it active. On
|
|
59
|
+
* error nothing changes.
|
|
60
|
+
*/
|
|
61
|
+
export declare function endGuardianSession(guardian: GuardianHttpClient, session: GuardianSession, store?: SessionKeyStore): Promise<boolean>;
|
|
62
|
+
/**
|
|
63
|
+
* Revoke every session of `signer` on the Guardian with a wallet signature,
|
|
64
|
+
* including sessions started in other tabs or devices, stop using the current
|
|
65
|
+
* one, and forget its stored key (a newer key another tab stored meanwhile
|
|
66
|
+
* is kept). `signer` becomes `guardian`'s signer. Use it when a session key
|
|
67
|
+
* may be compromised: page logout alone cannot stop a script that holds the
|
|
68
|
+
* key. Returns how many sessions the server revoked.
|
|
69
|
+
*
|
|
70
|
+
* It ends sessions already registered with Guardian. A page that got a grant
|
|
71
|
+
* signed can still register it for up to about 10 minutes, and a device whose
|
|
72
|
+
* clock runs behind can miss sessions started just before; run it again 10
|
|
73
|
+
* minutes later when a key may be compromised.
|
|
74
|
+
*/
|
|
75
|
+
export declare function revokeAllGuardianSessions(guardian: GuardianHttpClient, signer: Signer, store?: SessionKeyStore): Promise<number>;
|
|
76
|
+
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/session/manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,kBAAkB,EAClB,MAAM,EACP,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,eAAe,EACf,KAAK,sBAAsB,EAC3B,KAAK,eAAe,EAIrB,MAAM,UAAU,CAAC;AAiBlB,iEAAiE;AACjE,qBAAa,gCAAiC,SAAQ,KAAK;;CAK1D;AAED,+DAA+D;AAC/D,qBAAa,yBAA0B,SAAQ,KAAK;;CAKnD;AAED,MAAM,WAAW,mBAAoB,SAAQ,IAAI,CAAC,sBAAsB,EAAE,SAAS,CAAC;IAClF;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACpE,2EAA2E;IAC3E,KAAK,CAAC,EAAE,eAAe,CAAC;CACzB;AAgBD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,kBAAkB,EAC5B,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,eAAe,CAAC,CAoF1B;AAED;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,kBAAkB,EAC5B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,eAAe,EACtB,OAAO,GAAE,IAAI,CAAC,sBAAsB,EAAE,SAAS,CAAM,GACpD,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAqBjC;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,EAAE,eAAe,EACxB,KAAK,CAAC,EAAE,eAAe,GACtB,OAAO,CAAC,OAAO,CAAC,CAMlB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,yBAAyB,CAC7C,QAAQ,EAAE,kBAAkB,EAC5B,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,eAAe,GACtB,OAAO,CAAC,MAAM,CAAC,CAQjB"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { GuardianSession, WebCryptoSessionKey, forgetSessionKey, } from './key.js';
|
|
2
|
+
/**
|
|
3
|
+
* A grant is shortened by this much below the Guardian's maximum lifetime so
|
|
4
|
+
* client clock drift cannot push it over the limit.
|
|
5
|
+
*/
|
|
6
|
+
const MAX_TTL_MARGIN_SECONDS = 60;
|
|
7
|
+
/**
|
|
8
|
+
* Guardian accepts a grant only while it is at most this old, and only if it
|
|
9
|
+
* expires more than this far in the future.
|
|
10
|
+
*/
|
|
11
|
+
const GRANT_WINDOW_SECONDS = 300;
|
|
12
|
+
/** Matches `GuardianHttpClient`: a session this close to expiry is not used. */
|
|
13
|
+
const SESSION_EXPIRY_MARGIN_SECONDS = 30;
|
|
14
|
+
/** The Guardian does not advertise sessions on `GET /status`. */
|
|
15
|
+
export class GuardianSessionsUnsupportedError extends Error {
|
|
16
|
+
constructor() {
|
|
17
|
+
super('This Guardian does not accept sessions');
|
|
18
|
+
this.name = 'GuardianSessionsUnsupportedError';
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/** `confirm` returned `false`: the user declined the grant. */
|
|
22
|
+
export class SessionGrantDeclinedError extends Error {
|
|
23
|
+
constructor() {
|
|
24
|
+
super('Session grant was declined');
|
|
25
|
+
this.name = 'SessionGrantDeclinedError';
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/** The current page's origin in a browser; empty elsewhere. */
|
|
29
|
+
function pageOrigin() {
|
|
30
|
+
const location = globalThis.location;
|
|
31
|
+
return location?.origin && location.origin !== 'null' ? location.origin : '';
|
|
32
|
+
}
|
|
33
|
+
function storeId(guardianCommitment, signerCommitment) {
|
|
34
|
+
return `${guardianCommitment.toLowerCase()}:${signerCommitment.toLowerCase()}`;
|
|
35
|
+
}
|
|
36
|
+
function nowSeconds() {
|
|
37
|
+
return Math.floor(Date.now() / 1000);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Start a Guardian session: `signer` signs one grant and, once the session is
|
|
41
|
+
* registered, becomes `guardian`'s signer; a non-extractable P-256 delegated
|
|
42
|
+
* signer then signs the
|
|
43
|
+
* session-eligible requests on `guardian` (reads, proposal list/get, proposal
|
|
44
|
+
* create/sign). Every other route, including `configure`, `pushDelta`,
|
|
45
|
+
* `abandonCandidate`, account lookup and `revokeAllSessions`, keeps using the
|
|
46
|
+
* wallet. A session already set on `guardian` is replaced but stays valid on
|
|
47
|
+
* the server until it expires; end it first with {@link endGuardianSession}.
|
|
48
|
+
*
|
|
49
|
+
* The grant is dated after `confirm` returns, so a slow confirmation still
|
|
50
|
+
* registers; only its start moves, the confirmed expiry stays. If storing the
|
|
51
|
+
* key fails, the registered session is logged out and the error rethrown.
|
|
52
|
+
*/
|
|
53
|
+
export async function startGuardianSession(guardian, signer, options = {}) {
|
|
54
|
+
if (!signer.signSessionGrant) {
|
|
55
|
+
throw new Error('This signer cannot sign Guardian session grants');
|
|
56
|
+
}
|
|
57
|
+
if (signer.requestAuthFormat !== 'eip712' && !options.confirm) {
|
|
58
|
+
throw new Error('This wallet signs a session grant as a hash: pass `confirm` and show ' +
|
|
59
|
+
'describeSessionGrant(grant) to the user first');
|
|
60
|
+
}
|
|
61
|
+
const [status, { commitment: guardianCommitment }, key] = await Promise.all([
|
|
62
|
+
guardian.getStatus(),
|
|
63
|
+
guardian.getPubkey(signer.scheme),
|
|
64
|
+
WebCryptoSessionKey.generate(),
|
|
65
|
+
]);
|
|
66
|
+
if (!status.sessions) {
|
|
67
|
+
throw new GuardianSessionsUnsupportedError();
|
|
68
|
+
}
|
|
69
|
+
const maxTtl = status.sessions.maxTtlSeconds - MAX_TTL_MARGIN_SECONDS;
|
|
70
|
+
const ttl = Math.min(options.ttlSeconds ?? maxTtl, maxTtl);
|
|
71
|
+
if (!Number.isInteger(ttl) || ttl <= GRANT_WINDOW_SECONDS) {
|
|
72
|
+
throw new Error(`Session lifetime must be a whole number of seconds above ${GRANT_WINDOW_SECONDS}`);
|
|
73
|
+
}
|
|
74
|
+
const issuedAt = nowSeconds();
|
|
75
|
+
let grant = {
|
|
76
|
+
signerCommitment: signer.commitment,
|
|
77
|
+
sessionPublicKey: key.publicKey,
|
|
78
|
+
origin: options.origin ?? pageOrigin(),
|
|
79
|
+
issuedAt,
|
|
80
|
+
expiresAt: issuedAt + ttl,
|
|
81
|
+
guardianCommitment,
|
|
82
|
+
network: status.environment,
|
|
83
|
+
};
|
|
84
|
+
if (options.confirm) {
|
|
85
|
+
if (!(await options.confirm(grant))) {
|
|
86
|
+
throw new SessionGrantDeclinedError();
|
|
87
|
+
}
|
|
88
|
+
grant = { ...grant, issuedAt: Math.max(issuedAt, nowSeconds()) };
|
|
89
|
+
if (grant.expiresAt - grant.issuedAt <= GRANT_WINDOW_SECONDS) {
|
|
90
|
+
throw new Error('The session grant was confirmed too late; start the session again');
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
const signature = await signer.signSessionGrant(grant);
|
|
94
|
+
if (nowSeconds() - grant.issuedAt > GRANT_WINDOW_SECONDS) {
|
|
95
|
+
throw new Error(`The wallet took more than ${GRANT_WINDOW_SECONDS} seconds to sign the session grant; ` +
|
|
96
|
+
'start the session again');
|
|
97
|
+
}
|
|
98
|
+
await guardian.createSession({
|
|
99
|
+
scheme: signer.scheme,
|
|
100
|
+
...(signer.requestAuthFormat === 'eip712' ? { authFormat: 'eip712' } : {}),
|
|
101
|
+
...(signer.scheme === 'ecdsa' ? { publicKey: signer.publicKey } : {}),
|
|
102
|
+
signature,
|
|
103
|
+
grant,
|
|
104
|
+
});
|
|
105
|
+
const session = new GuardianSession(key, signer.commitment, grant.expiresAt, storeId(guardianCommitment, signer.commitment), { store: options.store, onEnded: options.onEnded });
|
|
106
|
+
if (options.store) {
|
|
107
|
+
try {
|
|
108
|
+
await options.store.save({
|
|
109
|
+
id: session.storeId,
|
|
110
|
+
privateKey: key.privateKey,
|
|
111
|
+
publicKey: key.publicKey,
|
|
112
|
+
expiresAt: grant.expiresAt,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
const unreachable = new GuardianSession(key, signer.commitment, grant.expiresAt, session.storeId);
|
|
117
|
+
await guardian.revokeSession(unreachable).catch(() => false);
|
|
118
|
+
throw error;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
guardian.setSigner(signer);
|
|
122
|
+
guardian.setSession(session);
|
|
123
|
+
return session;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Reuse a session key persisted by `startGuardianSession` without asking the
|
|
127
|
+
* wallet again; `signer` becomes `guardian`'s signer when a session resumes.
|
|
128
|
+
* Returns `null` when none
|
|
129
|
+
* is stored or it expires within 30 seconds. A session revoked elsewhere
|
|
130
|
+
* fails its next request with `session_revoked` and ends then (`onEnded`);
|
|
131
|
+
* start a new one.
|
|
132
|
+
*/
|
|
133
|
+
export async function resumeGuardianSession(guardian, signer, store, options = {}) {
|
|
134
|
+
const { commitment: guardianCommitment } = await guardian.getPubkey(signer.scheme);
|
|
135
|
+
const id = storeId(guardianCommitment, signer.commitment);
|
|
136
|
+
const record = await store.load(id);
|
|
137
|
+
if (!record) {
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
if (record.expiresAt - SESSION_EXPIRY_MARGIN_SECONDS <= nowSeconds()) {
|
|
141
|
+
await store.remove(id, record.publicKey);
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
const session = new GuardianSession(new WebCryptoSessionKey(record.privateKey, record.publicKey), signer.commitment, record.expiresAt, id, { store, onEnded: options.onEnded });
|
|
145
|
+
guardian.setSigner(signer);
|
|
146
|
+
guardian.setSession(session);
|
|
147
|
+
return session;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Revoke `session` on the server, stop using it if it is the current one, and
|
|
151
|
+
* forget its stored key. Returns whether the server still had it active. On
|
|
152
|
+
* error nothing changes.
|
|
153
|
+
*/
|
|
154
|
+
export async function endGuardianSession(guardian, session, store) {
|
|
155
|
+
const revoked = await guardian.revokeSession(session);
|
|
156
|
+
if (store) {
|
|
157
|
+
await forgetSessionKey(store, session);
|
|
158
|
+
}
|
|
159
|
+
return revoked;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Revoke every session of `signer` on the Guardian with a wallet signature,
|
|
163
|
+
* including sessions started in other tabs or devices, stop using the current
|
|
164
|
+
* one, and forget its stored key (a newer key another tab stored meanwhile
|
|
165
|
+
* is kept). `signer` becomes `guardian`'s signer. Use it when a session key
|
|
166
|
+
* may be compromised: page logout alone cannot stop a script that holds the
|
|
167
|
+
* key. Returns how many sessions the server revoked.
|
|
168
|
+
*
|
|
169
|
+
* It ends sessions already registered with Guardian. A page that got a grant
|
|
170
|
+
* signed can still register it for up to about 10 minutes, and a device whose
|
|
171
|
+
* clock runs behind can miss sessions started just before; run it again 10
|
|
172
|
+
* minutes later when a key may be compromised.
|
|
173
|
+
*/
|
|
174
|
+
export async function revokeAllGuardianSessions(guardian, signer, store) {
|
|
175
|
+
guardian.setSigner(signer);
|
|
176
|
+
const stored = store ? await storedKey(guardian, signer, store) : null;
|
|
177
|
+
const revoked = await guardian.revokeAllSessions();
|
|
178
|
+
if (store && stored) {
|
|
179
|
+
await forgetSessionKey(store, { storeId: stored.id, publicKey: stored.publicKey });
|
|
180
|
+
}
|
|
181
|
+
return revoked;
|
|
182
|
+
}
|
|
183
|
+
async function storedKey(guardian, signer, store) {
|
|
184
|
+
const { commitment: guardianCommitment } = await guardian.getPubkey(signer.scheme);
|
|
185
|
+
return store.load(storeId(guardianCommitment, signer.commitment));
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/session/manager.ts"],"names":[],"mappings":"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"}
|
package/dist/signers/ecdsa.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { RequestAuthPayload } from '@openzeppelin/guardian-client';
|
|
1
|
+
import type { RequestAuthPayload, SessionGrantFields } from '@openzeppelin/guardian-client';
|
|
2
2
|
import { AuthSecretKey, type MidenClient } from '@miden-sdk/miden-sdk';
|
|
3
3
|
import type { Signer, SignatureScheme } from '../types.js';
|
|
4
4
|
export declare class EcdsaSigner implements Signer {
|
|
@@ -16,6 +16,10 @@ export declare class EcdsaSigner implements Signer {
|
|
|
16
16
|
* Account-less; used directly by `recoverByKey`.
|
|
17
17
|
*/
|
|
18
18
|
signLookupMessage(keyCommitmentHex: string, timestampMs: number): Promise<string>;
|
|
19
|
+
/** Sign a session grant as its raw RPO digest. */
|
|
20
|
+
signSessionGrant(grant: SessionGrantFields): Promise<string>;
|
|
21
|
+
/** Sign a session revoke-all as its raw RPO digest. */
|
|
22
|
+
signSessionRevokeAll(signerCommitment: string, timestampMs: number): Promise<string>;
|
|
19
23
|
bindAccountKey(midenClient: MidenClient, accountId: string): Promise<void>;
|
|
20
24
|
private signWord;
|
|
21
25
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ecdsa.d.ts","sourceRoot":"","sources":["../../src/signers/ecdsa.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"ecdsa.d.ts","sourceRoot":"","sources":["../../src/signers/ecdsa.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAC5F,OAAO,EAAa,aAAa,EAAE,KAAK,WAAW,EAAa,MAAM,sBAAsB,CAAC;AAC7F,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAM3D,qBAAa,WAAY,YAAW,MAAM;IACxC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAW;IAC3C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgB;IAC1C,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAO;gBAE/B,SAAS,EAAE,aAAa;IAS9B,0BAA0B,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAKjF,WAAW,CACf,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,kBAAkB,GACjC,OAAO,CAAC,MAAM,CAAC;IAKZ,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAK5D;;;OAGG;IACG,iBAAiB,CAAC,gBAAgB,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAKvF,kDAAkD;IAC5C,gBAAgB,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC;IAIlE,uDAAuD;IACjD,oBAAoB,CAAC,gBAAgB,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAIpF,cAAc,CAAC,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAchF,OAAO,CAAC,QAAQ;CAMjB"}
|
package/dist/signers/ecdsa.js
CHANGED
|
@@ -2,6 +2,7 @@ import { AccountId } from '@miden-sdk/miden-sdk';
|
|
|
2
2
|
import { bytesToHex, normalizeHexWord } from '../utils/encoding.js';
|
|
3
3
|
import { AuthDigest } from '../utils/digest.js';
|
|
4
4
|
import { lookupAuthDigest } from '../lookupAuth.js';
|
|
5
|
+
import { sessionGrantDigest, sessionRevokeAllDigest } from '../session/grant.js';
|
|
5
6
|
export class EcdsaSigner {
|
|
6
7
|
commitment;
|
|
7
8
|
publicKey;
|
|
@@ -36,6 +37,14 @@ export class EcdsaSigner {
|
|
|
36
37
|
const digest = lookupAuthDigest(timestampMs, keyCommitmentHex);
|
|
37
38
|
return this.signWord(digest);
|
|
38
39
|
}
|
|
40
|
+
/** Sign a session grant as its raw RPO digest. */
|
|
41
|
+
async signSessionGrant(grant) {
|
|
42
|
+
return this.signWord(sessionGrantDigest(grant));
|
|
43
|
+
}
|
|
44
|
+
/** Sign a session revoke-all as its raw RPO digest. */
|
|
45
|
+
async signSessionRevokeAll(signerCommitment, timestampMs) {
|
|
46
|
+
return this.signWord(sessionRevokeAllDigest(signerCommitment, timestampMs));
|
|
47
|
+
}
|
|
39
48
|
async bindAccountKey(midenClient, accountId) {
|
|
40
49
|
const targetAccountId = AccountId.fromHex(accountId);
|
|
41
50
|
const existingAccountId = await midenClient.keystore.getAccountId(this.publicKeyCommitment);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ecdsa.js","sourceRoot":"","sources":["../../src/signers/ecdsa.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAA8C,MAAM,sBAAsB,CAAC;AAE7F,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"ecdsa.js","sourceRoot":"","sources":["../../src/signers/ecdsa.ts"],"names":[],"mappings":"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"}
|
package/dist/signers/falcon.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { RequestAuthPayload } from '@openzeppelin/guardian-client';
|
|
1
|
+
import type { RequestAuthPayload, SessionGrantFields } from '@openzeppelin/guardian-client';
|
|
2
2
|
import { AuthSecretKey, type MidenClient } from '@miden-sdk/miden-sdk';
|
|
3
3
|
import type { Signer, SignatureScheme } from '../types.js';
|
|
4
4
|
export declare class FalconSigner implements Signer {
|
|
@@ -16,6 +16,10 @@ export declare class FalconSigner implements Signer {
|
|
|
16
16
|
* Account-less; used directly by `recoverByKey`.
|
|
17
17
|
*/
|
|
18
18
|
signLookupMessage(keyCommitmentHex: string, timestampMs: number): Promise<string>;
|
|
19
|
+
/** Sign a session grant as its raw RPO digest. */
|
|
20
|
+
signSessionGrant(grant: SessionGrantFields): Promise<string>;
|
|
21
|
+
/** Sign a session revoke-all as its raw RPO digest. */
|
|
22
|
+
signSessionRevokeAll(signerCommitment: string, timestampMs: number): Promise<string>;
|
|
19
23
|
bindAccountKey(midenClient: MidenClient, accountId: string): Promise<void>;
|
|
20
24
|
private signWord;
|
|
21
25
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"falcon.d.ts","sourceRoot":"","sources":["../../src/signers/falcon.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"falcon.d.ts","sourceRoot":"","sources":["../../src/signers/falcon.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAC5F,OAAO,EAAa,aAAa,EAAE,KAAK,WAAW,EAAa,MAAM,sBAAsB,CAAC;AAC7F,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAM3D,qBAAa,YAAa,YAAW,MAAM;IACzC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAY;IAC5C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgB;IAC1C,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAO;gBAE/B,SAAS,EAAE,aAAa;IAU9B,0BAA0B,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAKjF,WAAW,CACf,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,kBAAkB,GACjC,OAAO,CAAC,MAAM,CAAC;IAKZ,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAK5D;;;OAGG;IACG,iBAAiB,CAAC,gBAAgB,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAKvF,kDAAkD;IAC5C,gBAAgB,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC;IAIlE,uDAAuD;IACjD,oBAAoB,CAAC,gBAAgB,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAIpF,cAAc,CAAC,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAchF,OAAO,CAAC,QAAQ;CAMjB"}
|
package/dist/signers/falcon.js
CHANGED
|
@@ -2,6 +2,7 @@ import { AccountId } from '@miden-sdk/miden-sdk';
|
|
|
2
2
|
import { bytesToHex } from '../utils/encoding.js';
|
|
3
3
|
import { AuthDigest } from '../utils/digest.js';
|
|
4
4
|
import { lookupAuthDigest } from '../lookupAuth.js';
|
|
5
|
+
import { sessionGrantDigest, sessionRevokeAllDigest } from '../session/grant.js';
|
|
5
6
|
export class FalconSigner {
|
|
6
7
|
commitment;
|
|
7
8
|
publicKey;
|
|
@@ -37,6 +38,14 @@ export class FalconSigner {
|
|
|
37
38
|
const digest = lookupAuthDigest(timestampMs, keyCommitmentHex);
|
|
38
39
|
return this.signWord(digest);
|
|
39
40
|
}
|
|
41
|
+
/** Sign a session grant as its raw RPO digest. */
|
|
42
|
+
async signSessionGrant(grant) {
|
|
43
|
+
return this.signWord(sessionGrantDigest(grant));
|
|
44
|
+
}
|
|
45
|
+
/** Sign a session revoke-all as its raw RPO digest. */
|
|
46
|
+
async signSessionRevokeAll(signerCommitment, timestampMs) {
|
|
47
|
+
return this.signWord(sessionRevokeAllDigest(signerCommitment, timestampMs));
|
|
48
|
+
}
|
|
40
49
|
async bindAccountKey(midenClient, accountId) {
|
|
41
50
|
const targetAccountId = AccountId.fromHex(accountId);
|
|
42
51
|
const existingAccountId = await midenClient.keystore.getAccountId(this.publicKeyCommitment);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"falcon.js","sourceRoot":"","sources":["../../src/signers/falcon.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAA8C,MAAM,sBAAsB,CAAC;AAE7F,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"falcon.js","sourceRoot":"","sources":["../../src/signers/falcon.ts"],"names":[],"mappings":"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"}
|
package/dist/signers/ledger.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { RequestAuthPayload, Signer } from '@openzeppelin/guardian-client';
|
|
1
|
+
import type { RequestAuthPayload, SessionGrantFields, Signer } from '@openzeppelin/guardian-client';
|
|
2
2
|
export interface Eip1193SignerProvider {
|
|
3
3
|
request(args: {
|
|
4
4
|
method: string;
|
|
@@ -19,6 +19,14 @@ export declare class Eip712Signer implements Signer {
|
|
|
19
19
|
signRequest(accountId: string, timestamp: number, requestPayload: RequestAuthPayload): Promise<string>;
|
|
20
20
|
signLookupMessage(keyCommitmentHex: string, timestampMs: number): Promise<string>;
|
|
21
21
|
signCommitment(commitmentHex: string): Promise<string>;
|
|
22
|
+
/**
|
|
23
|
+
* Sign a session grant as readable `GuardianSession` typed
|
|
24
|
+
* data, so the device shows the Guardian, network and expiry rather than a
|
|
25
|
+
* hash. Devices without registered display metadata need "Verbose EIP-712".
|
|
26
|
+
*/
|
|
27
|
+
signSessionGrant(grant: SessionGrantFields): Promise<string>;
|
|
28
|
+
/** Sign a session revoke-all as readable `GuardianSessionRevokeAll` typed data. */
|
|
29
|
+
signSessionRevokeAll(signerCommitment: string, timestampMs: number): Promise<string>;
|
|
22
30
|
private signTypedData;
|
|
23
31
|
}
|
|
24
32
|
export { Eip712Signer as LedgerSigner };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ledger.d.ts","sourceRoot":"","sources":["../../src/signers/ledger.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"ledger.d.ts","sourceRoot":"","sources":["../../src/signers/ledger.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AAkBpG,MAAM,WAAW,qBAAqB;IACpC,OAAO,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,OAAO,EAAE,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACxE;AAED,qBAAa,YAAa,YAAW,MAAM;IAmCvC,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAlC3B,QAAQ,CAAC,MAAM,WAAW;IAC1B,QAAQ,CAAC,iBAAiB,YAAY;IACtC,QAAQ,CAAC,qBAAqB,YAAY;IAC1C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;WAEZ,OAAO,CAAC,QAAQ,EAAE,qBAAqB,GAAG,OAAO,CAAC,YAAY,CAAC;gBA2BzD,QAAQ,EAAE,qBAAqB,EAChD,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM;IAoBjB,0BAA0B,IAAI,OAAO,CAAC,MAAM,CAAC;IAIvC,WAAW,CACf,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,kBAAkB,GACjC,OAAO,CAAC,MAAM,CAAC;IAKZ,iBAAiB,CAAC,gBAAgB,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAKjF,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAK5D;;;;OAIG;IACG,gBAAgB,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC;IAIlE,mFAAmF;IAC7E,oBAAoB,CAAC,gBAAgB,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAI5E,aAAa;CAkB5B;AAED,OAAO,EAAE,YAAY,IAAI,YAAY,EAAE,CAAC"}
|
package/dist/signers/ledger.js
CHANGED
|
@@ -4,7 +4,7 @@ import { AuthDigest } from '../utils/digest.js';
|
|
|
4
4
|
import { lookupAuthDigest } from '../lookupAuth.js';
|
|
5
5
|
import { EcdsaFormat } from '../utils/ecdsa.js';
|
|
6
6
|
import { bytesToHex, hexToBytes } from '../utils/encoding.js';
|
|
7
|
-
import { guardianKeyDiscoveryTypedData, guardianLookupTypedData, guardianRequestTypedData, midenTransactionTypedData, typedDataDigest, } from '../utils/eip712.js';
|
|
7
|
+
import { guardianKeyDiscoveryTypedData, guardianLookupTypedData, guardianRequestTypedData, guardianSessionRevokeAllTypedData, guardianSessionTypedData, midenTransactionTypedData, typedDataDigest, } from '../utils/eip712.js';
|
|
8
8
|
import { tryComputeEcdsaCommitmentHex } from '../utils/signature.js';
|
|
9
9
|
import { wordToBytes } from '../utils/word.js';
|
|
10
10
|
export class Eip712Signer {
|
|
@@ -73,6 +73,18 @@ export class Eip712Signer {
|
|
|
73
73
|
const commitment = AuthDigest.fromCommitmentHex(commitmentHex);
|
|
74
74
|
return this.signTypedData(midenTransactionTypedData(wordToBytes(commitment)));
|
|
75
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* Sign a session grant as readable `GuardianSession` typed
|
|
78
|
+
* data, so the device shows the Guardian, network and expiry rather than a
|
|
79
|
+
* hash. Devices without registered display metadata need "Verbose EIP-712".
|
|
80
|
+
*/
|
|
81
|
+
async signSessionGrant(grant) {
|
|
82
|
+
return this.signTypedData(guardianSessionTypedData(grant));
|
|
83
|
+
}
|
|
84
|
+
/** Sign a session revoke-all as readable `GuardianSessionRevokeAll` typed data. */
|
|
85
|
+
async signSessionRevokeAll(signerCommitment, timestampMs) {
|
|
86
|
+
return this.signTypedData(guardianSessionRevokeAllTypedData(signerCommitment, timestampMs));
|
|
87
|
+
}
|
|
76
88
|
async signTypedData(data) {
|
|
77
89
|
const result = await this.provider.request({
|
|
78
90
|
method: 'eth_signTypedData_v4',
|