@0xsequence/guard 0.0.0-20231027021244 → 0.0.0-20231102200515

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.
@@ -21,7 +21,7 @@ function _extends() {
21
21
  }
22
22
 
23
23
  /* eslint-disable */
24
- // sequence-guard v0.4.0 b3da61e22d917265bc35085a92b4173ea096a0c8
24
+ // sequence-guard v0.4.0 af5ad0623aec0b231a462052edaea1823f620a1e
25
25
  // --
26
26
  // Code generated by webrpc-gen@v0.12.x-dev with typescript@v0.10.0 generator. DO NOT EDIT.
27
27
  //
@@ -34,7 +34,7 @@ const WebRPCVersion = 'v1';
34
34
  const WebRPCSchemaVersion = 'v0.4.0';
35
35
 
36
36
  // Schema hash generated from your RIDL schema
37
- const WebRPCSchemaHash = 'b3da61e22d917265bc35085a92b4173ea096a0c8';
37
+ const WebRPCSchemaHash = 'af5ad0623aec0b231a462052edaea1823f620a1e';
38
38
 
39
39
  //
40
40
  // Types
@@ -134,7 +134,9 @@ class Guard {
134
134
  this.commitTOTP = (args, headers) => {
135
135
  return this.fetch(this.url('CommitTOTP'), createHTTPRequest(args, headers)).then(res => {
136
136
  return buildResponse(res).then(_data => {
137
- return {};
137
+ return {
138
+ codes: _data.codes
139
+ };
138
140
  });
139
141
  });
140
142
  };
@@ -183,35 +185,59 @@ const buildResponse = res => {
183
185
 
184
186
  const fetch = typeof global === 'object' ? global.fetch : window.fetch;
185
187
  class GuardSigner {
186
- constructor(address, url, appendSuffix = false, onError) {
187
- this.requests = new Map();
188
+ constructor(address, url, appendSuffix = false) {
188
189
  this.address = address;
189
190
  this.url = url;
190
191
  this.appendSuffix = appendSuffix;
191
- this.onError = onError;
192
192
  this.guard = new Guard(url, fetch);
193
193
  }
194
194
  async getAddress() {
195
195
  return this.address;
196
196
  }
197
- async requestSignature(id, _message, metadata, callbacks) {
197
+ async requestSignature(_id, message, metadata, callbacks) {
198
+ const {
199
+ onSignature,
200
+ onRejection
201
+ } = callbacks;
198
202
  if (!core.commons.isWalletSignRequestMetadata(metadata)) {
199
- callbacks.onRejection('Expected Sequence-like metadata');
200
- } else {
201
- // Queue the request first, this method only does that
202
- // the requesting to the API is later handled on every status change
203
- this.requests.set(id, callbacks);
203
+ onRejection('expected sequence signature request metadata');
204
+ return false;
204
205
  }
205
- return true;
206
- }
207
- notifyStatusChange(id, status, metadata) {
208
- if (!this.requests.has(id)) return;
209
- if (!core.commons.isWalletSignRequestMetadata(metadata)) {
210
- this.requests.get(id).onRejection('Expected Sequence-like metadata (status update)');
211
- return;
206
+ try {
207
+ var _metadata$parts;
208
+ const guardTotpCode = metadata.guardTotpCode;
209
+
210
+ // Building auxData, notice: this uses the old v1 format
211
+ // TODO: We should update the guard API so we can pass the metadata directly
212
+ const coder = core.universal.genericCoderFor(metadata.config.version);
213
+ const {
214
+ encoded
215
+ } = coder.signature.encodeSigners(metadata.config, (_metadata$parts = metadata.parts) != null ? _metadata$parts : new Map(), [], metadata.chainId);
216
+ const {
217
+ sig: signature
218
+ } = await this.guard.signWith({
219
+ signer: this.address,
220
+ request: {
221
+ msg: ethers.ethers.utils.hexlify(message),
222
+ auxData: this.packMsgAndSig(metadata.address, metadata.digest, encoded, metadata.chainId),
223
+ chainId: ethers.ethers.BigNumber.from(metadata.chainId).toNumber()
224
+ },
225
+ token: guardTotpCode ? {
226
+ id: AuthMethod.TOTP,
227
+ token: guardTotpCode
228
+ } : undefined
229
+ });
230
+ if (ethers.ethers.utils.arrayify(signature).length === 0) {
231
+ throw new Error('guard response contained no signature data');
232
+ }
233
+ onSignature(signature);
234
+ return true;
235
+ } catch (error) {
236
+ onRejection(`unable to request guard signature: ${error}`);
237
+ return false;
212
238
  }
213
- this.evaluateRequest(id, status.message, status, metadata);
214
239
  }
240
+ notifyStatusChange(_id, _status, _metadata) {}
215
241
  async getAuthMethods(token) {
216
242
  let response;
217
243
  if ('jwt' in token) {
@@ -263,11 +289,14 @@ class GuardSigner {
263
289
  return new URL(uri);
264
290
  }
265
291
  async commitTotp(token, jwt) {
266
- await this.guard.commitTOTP({
292
+ const {
293
+ codes
294
+ } = await this.guard.commitTOTP({
267
295
  token
268
296
  }, {
269
297
  Authorization: `BEARER ${jwt}`
270
298
  });
299
+ return codes;
271
300
  }
272
301
  async resetTotp(token) {
273
302
  const signedToken = await signUpdateAuthMethodToken(token);
@@ -281,50 +310,6 @@ class GuardSigner {
281
310
  packMsgAndSig(address, msg, sig, chainId) {
282
311
  return ethers.ethers.utils.defaultAbiCoder.encode(['address', 'uint256', 'bytes', 'bytes'], [address, chainId, msg, sig]);
283
312
  }
284
- keyOfRequest(signer, msg, auxData, chainId) {
285
- return ethers.ethers.utils.solidityKeccak256(['address', 'uint256', 'bytes', 'bytes'], [signer, chainId, msg, auxData]);
286
- }
287
- async evaluateRequest(id, message, _, metadata) {
288
- var _metadata$parts;
289
- // Building auxData, notice: this uses the old v1 format
290
- // TODO: We should update the guard API so we can pass the metadata directly
291
- const coder = core.universal.genericCoderFor(metadata.config.version);
292
- const {
293
- encoded
294
- } = coder.signature.encodeSigners(metadata.config, (_metadata$parts = metadata.parts) != null ? _metadata$parts : new Map(), [], metadata.chainId);
295
- try {
296
- var _this$requests$get;
297
- const key = this.keyOfRequest(this.address, message, encoded, metadata.chainId);
298
- const lastAttempt = (_this$requests$get = this.requests.get(id)) == null ? void 0 : _this$requests$get.lastAttempt;
299
- if (lastAttempt === key) {
300
- return;
301
- }
302
- this.requests.get(id).lastAttempt = key;
303
- const result = await this.guard.signWith({
304
- signer: this.address,
305
- request: {
306
- msg: ethers.ethers.utils.hexlify(message),
307
- auxData: this.packMsgAndSig(metadata.address, metadata.digest, encoded, metadata.chainId),
308
- chainId: ethers.ethers.BigNumber.from(metadata.chainId).toNumber() // TODO: This should be a string (in the API)
309
- },
310
-
311
- token: metadata.guardTotpCode ? {
312
- id: AuthMethod.TOTP,
313
- token: metadata.guardTotpCode
314
- } : undefined
315
- });
316
- if (ethers.ethers.utils.arrayify(result.sig).length !== 0) {
317
- this.requests.get(id).onSignature(result.sig);
318
- this.requests.delete(id);
319
- }
320
- } catch (e) {
321
- var _this$onError;
322
- // The guard signer may reject the request for a number of reasons
323
- // like for example, if it's being the first signer (it waits for other signers to sign first)
324
- // We always forward the error here and filter on client side.
325
- (_this$onError = this.onError) == null ? void 0 : _this$onError.call(this, e);
326
- }
327
- }
328
313
  suffix() {
329
314
  return this.appendSuffix ? [3] : [];
330
315
  }
@@ -21,7 +21,7 @@ function _extends() {
21
21
  }
22
22
 
23
23
  /* eslint-disable */
24
- // sequence-guard v0.4.0 b3da61e22d917265bc35085a92b4173ea096a0c8
24
+ // sequence-guard v0.4.0 af5ad0623aec0b231a462052edaea1823f620a1e
25
25
  // --
26
26
  // Code generated by webrpc-gen@v0.12.x-dev with typescript@v0.10.0 generator. DO NOT EDIT.
27
27
  //
@@ -34,7 +34,7 @@ const WebRPCVersion = 'v1';
34
34
  const WebRPCSchemaVersion = 'v0.4.0';
35
35
 
36
36
  // Schema hash generated from your RIDL schema
37
- const WebRPCSchemaHash = 'b3da61e22d917265bc35085a92b4173ea096a0c8';
37
+ const WebRPCSchemaHash = 'af5ad0623aec0b231a462052edaea1823f620a1e';
38
38
 
39
39
  //
40
40
  // Types
@@ -134,7 +134,9 @@ class Guard {
134
134
  this.commitTOTP = (args, headers) => {
135
135
  return this.fetch(this.url('CommitTOTP'), createHTTPRequest(args, headers)).then(res => {
136
136
  return buildResponse(res).then(_data => {
137
- return {};
137
+ return {
138
+ codes: _data.codes
139
+ };
138
140
  });
139
141
  });
140
142
  };
@@ -183,35 +185,59 @@ const buildResponse = res => {
183
185
 
184
186
  const fetch = typeof global === 'object' ? global.fetch : window.fetch;
185
187
  class GuardSigner {
186
- constructor(address, url, appendSuffix = false, onError) {
187
- this.requests = new Map();
188
+ constructor(address, url, appendSuffix = false) {
188
189
  this.address = address;
189
190
  this.url = url;
190
191
  this.appendSuffix = appendSuffix;
191
- this.onError = onError;
192
192
  this.guard = new Guard(url, fetch);
193
193
  }
194
194
  async getAddress() {
195
195
  return this.address;
196
196
  }
197
- async requestSignature(id, _message, metadata, callbacks) {
197
+ async requestSignature(_id, message, metadata, callbacks) {
198
+ const {
199
+ onSignature,
200
+ onRejection
201
+ } = callbacks;
198
202
  if (!core.commons.isWalletSignRequestMetadata(metadata)) {
199
- callbacks.onRejection('Expected Sequence-like metadata');
200
- } else {
201
- // Queue the request first, this method only does that
202
- // the requesting to the API is later handled on every status change
203
- this.requests.set(id, callbacks);
203
+ onRejection('expected sequence signature request metadata');
204
+ return false;
204
205
  }
205
- return true;
206
- }
207
- notifyStatusChange(id, status, metadata) {
208
- if (!this.requests.has(id)) return;
209
- if (!core.commons.isWalletSignRequestMetadata(metadata)) {
210
- this.requests.get(id).onRejection('Expected Sequence-like metadata (status update)');
211
- return;
206
+ try {
207
+ var _metadata$parts;
208
+ const guardTotpCode = metadata.guardTotpCode;
209
+
210
+ // Building auxData, notice: this uses the old v1 format
211
+ // TODO: We should update the guard API so we can pass the metadata directly
212
+ const coder = core.universal.genericCoderFor(metadata.config.version);
213
+ const {
214
+ encoded
215
+ } = coder.signature.encodeSigners(metadata.config, (_metadata$parts = metadata.parts) != null ? _metadata$parts : new Map(), [], metadata.chainId);
216
+ const {
217
+ sig: signature
218
+ } = await this.guard.signWith({
219
+ signer: this.address,
220
+ request: {
221
+ msg: ethers.ethers.utils.hexlify(message),
222
+ auxData: this.packMsgAndSig(metadata.address, metadata.digest, encoded, metadata.chainId),
223
+ chainId: ethers.ethers.BigNumber.from(metadata.chainId).toNumber()
224
+ },
225
+ token: guardTotpCode ? {
226
+ id: AuthMethod.TOTP,
227
+ token: guardTotpCode
228
+ } : undefined
229
+ });
230
+ if (ethers.ethers.utils.arrayify(signature).length === 0) {
231
+ throw new Error('guard response contained no signature data');
232
+ }
233
+ onSignature(signature);
234
+ return true;
235
+ } catch (error) {
236
+ onRejection(`unable to request guard signature: ${error}`);
237
+ return false;
212
238
  }
213
- this.evaluateRequest(id, status.message, status, metadata);
214
239
  }
240
+ notifyStatusChange(_id, _status, _metadata) {}
215
241
  async getAuthMethods(token) {
216
242
  let response;
217
243
  if ('jwt' in token) {
@@ -263,11 +289,14 @@ class GuardSigner {
263
289
  return new URL(uri);
264
290
  }
265
291
  async commitTotp(token, jwt) {
266
- await this.guard.commitTOTP({
292
+ const {
293
+ codes
294
+ } = await this.guard.commitTOTP({
267
295
  token
268
296
  }, {
269
297
  Authorization: `BEARER ${jwt}`
270
298
  });
299
+ return codes;
271
300
  }
272
301
  async resetTotp(token) {
273
302
  const signedToken = await signUpdateAuthMethodToken(token);
@@ -281,50 +310,6 @@ class GuardSigner {
281
310
  packMsgAndSig(address, msg, sig, chainId) {
282
311
  return ethers.ethers.utils.defaultAbiCoder.encode(['address', 'uint256', 'bytes', 'bytes'], [address, chainId, msg, sig]);
283
312
  }
284
- keyOfRequest(signer, msg, auxData, chainId) {
285
- return ethers.ethers.utils.solidityKeccak256(['address', 'uint256', 'bytes', 'bytes'], [signer, chainId, msg, auxData]);
286
- }
287
- async evaluateRequest(id, message, _, metadata) {
288
- var _metadata$parts;
289
- // Building auxData, notice: this uses the old v1 format
290
- // TODO: We should update the guard API so we can pass the metadata directly
291
- const coder = core.universal.genericCoderFor(metadata.config.version);
292
- const {
293
- encoded
294
- } = coder.signature.encodeSigners(metadata.config, (_metadata$parts = metadata.parts) != null ? _metadata$parts : new Map(), [], metadata.chainId);
295
- try {
296
- var _this$requests$get;
297
- const key = this.keyOfRequest(this.address, message, encoded, metadata.chainId);
298
- const lastAttempt = (_this$requests$get = this.requests.get(id)) == null ? void 0 : _this$requests$get.lastAttempt;
299
- if (lastAttempt === key) {
300
- return;
301
- }
302
- this.requests.get(id).lastAttempt = key;
303
- const result = await this.guard.signWith({
304
- signer: this.address,
305
- request: {
306
- msg: ethers.ethers.utils.hexlify(message),
307
- auxData: this.packMsgAndSig(metadata.address, metadata.digest, encoded, metadata.chainId),
308
- chainId: ethers.ethers.BigNumber.from(metadata.chainId).toNumber() // TODO: This should be a string (in the API)
309
- },
310
-
311
- token: metadata.guardTotpCode ? {
312
- id: AuthMethod.TOTP,
313
- token: metadata.guardTotpCode
314
- } : undefined
315
- });
316
- if (ethers.ethers.utils.arrayify(result.sig).length !== 0) {
317
- this.requests.get(id).onSignature(result.sig);
318
- this.requests.delete(id);
319
- }
320
- } catch (e) {
321
- var _this$onError;
322
- // The guard signer may reject the request for a number of reasons
323
- // like for example, if it's being the first signer (it waits for other signers to sign first)
324
- // We always forward the error here and filter on client side.
325
- (_this$onError = this.onError) == null ? void 0 : _this$onError.call(this, e);
326
- }
327
- }
328
313
  suffix() {
329
314
  return this.appendSuffix ? [3] : [];
330
315
  }
@@ -17,7 +17,7 @@ function _extends() {
17
17
  }
18
18
 
19
19
  /* eslint-disable */
20
- // sequence-guard v0.4.0 b3da61e22d917265bc35085a92b4173ea096a0c8
20
+ // sequence-guard v0.4.0 af5ad0623aec0b231a462052edaea1823f620a1e
21
21
  // --
22
22
  // Code generated by webrpc-gen@v0.12.x-dev with typescript@v0.10.0 generator. DO NOT EDIT.
23
23
  //
@@ -30,7 +30,7 @@ const WebRPCVersion = 'v1';
30
30
  const WebRPCSchemaVersion = 'v0.4.0';
31
31
 
32
32
  // Schema hash generated from your RIDL schema
33
- const WebRPCSchemaHash = 'b3da61e22d917265bc35085a92b4173ea096a0c8';
33
+ const WebRPCSchemaHash = 'af5ad0623aec0b231a462052edaea1823f620a1e';
34
34
 
35
35
  //
36
36
  // Types
@@ -130,7 +130,9 @@ class Guard {
130
130
  this.commitTOTP = (args, headers) => {
131
131
  return this.fetch(this.url('CommitTOTP'), createHTTPRequest(args, headers)).then(res => {
132
132
  return buildResponse(res).then(_data => {
133
- return {};
133
+ return {
134
+ codes: _data.codes
135
+ };
134
136
  });
135
137
  });
136
138
  };
@@ -179,35 +181,59 @@ const buildResponse = res => {
179
181
 
180
182
  const fetch = typeof global === 'object' ? global.fetch : window.fetch;
181
183
  class GuardSigner {
182
- constructor(address, url, appendSuffix = false, onError) {
183
- this.requests = new Map();
184
+ constructor(address, url, appendSuffix = false) {
184
185
  this.address = address;
185
186
  this.url = url;
186
187
  this.appendSuffix = appendSuffix;
187
- this.onError = onError;
188
188
  this.guard = new Guard(url, fetch);
189
189
  }
190
190
  async getAddress() {
191
191
  return this.address;
192
192
  }
193
- async requestSignature(id, _message, metadata, callbacks) {
193
+ async requestSignature(_id, message, metadata, callbacks) {
194
+ const {
195
+ onSignature,
196
+ onRejection
197
+ } = callbacks;
194
198
  if (!commons.isWalletSignRequestMetadata(metadata)) {
195
- callbacks.onRejection('Expected Sequence-like metadata');
196
- } else {
197
- // Queue the request first, this method only does that
198
- // the requesting to the API is later handled on every status change
199
- this.requests.set(id, callbacks);
199
+ onRejection('expected sequence signature request metadata');
200
+ return false;
200
201
  }
201
- return true;
202
- }
203
- notifyStatusChange(id, status, metadata) {
204
- if (!this.requests.has(id)) return;
205
- if (!commons.isWalletSignRequestMetadata(metadata)) {
206
- this.requests.get(id).onRejection('Expected Sequence-like metadata (status update)');
207
- return;
202
+ try {
203
+ var _metadata$parts;
204
+ const guardTotpCode = metadata.guardTotpCode;
205
+
206
+ // Building auxData, notice: this uses the old v1 format
207
+ // TODO: We should update the guard API so we can pass the metadata directly
208
+ const coder = universal.genericCoderFor(metadata.config.version);
209
+ const {
210
+ encoded
211
+ } = coder.signature.encodeSigners(metadata.config, (_metadata$parts = metadata.parts) != null ? _metadata$parts : new Map(), [], metadata.chainId);
212
+ const {
213
+ sig: signature
214
+ } = await this.guard.signWith({
215
+ signer: this.address,
216
+ request: {
217
+ msg: ethers.utils.hexlify(message),
218
+ auxData: this.packMsgAndSig(metadata.address, metadata.digest, encoded, metadata.chainId),
219
+ chainId: ethers.BigNumber.from(metadata.chainId).toNumber()
220
+ },
221
+ token: guardTotpCode ? {
222
+ id: AuthMethod.TOTP,
223
+ token: guardTotpCode
224
+ } : undefined
225
+ });
226
+ if (ethers.utils.arrayify(signature).length === 0) {
227
+ throw new Error('guard response contained no signature data');
228
+ }
229
+ onSignature(signature);
230
+ return true;
231
+ } catch (error) {
232
+ onRejection(`unable to request guard signature: ${error}`);
233
+ return false;
208
234
  }
209
- this.evaluateRequest(id, status.message, status, metadata);
210
235
  }
236
+ notifyStatusChange(_id, _status, _metadata) {}
211
237
  async getAuthMethods(token) {
212
238
  let response;
213
239
  if ('jwt' in token) {
@@ -259,11 +285,14 @@ class GuardSigner {
259
285
  return new URL(uri);
260
286
  }
261
287
  async commitTotp(token, jwt) {
262
- await this.guard.commitTOTP({
288
+ const {
289
+ codes
290
+ } = await this.guard.commitTOTP({
263
291
  token
264
292
  }, {
265
293
  Authorization: `BEARER ${jwt}`
266
294
  });
295
+ return codes;
267
296
  }
268
297
  async resetTotp(token) {
269
298
  const signedToken = await signUpdateAuthMethodToken(token);
@@ -277,50 +306,6 @@ class GuardSigner {
277
306
  packMsgAndSig(address, msg, sig, chainId) {
278
307
  return ethers.utils.defaultAbiCoder.encode(['address', 'uint256', 'bytes', 'bytes'], [address, chainId, msg, sig]);
279
308
  }
280
- keyOfRequest(signer, msg, auxData, chainId) {
281
- return ethers.utils.solidityKeccak256(['address', 'uint256', 'bytes', 'bytes'], [signer, chainId, msg, auxData]);
282
- }
283
- async evaluateRequest(id, message, _, metadata) {
284
- var _metadata$parts;
285
- // Building auxData, notice: this uses the old v1 format
286
- // TODO: We should update the guard API so we can pass the metadata directly
287
- const coder = universal.genericCoderFor(metadata.config.version);
288
- const {
289
- encoded
290
- } = coder.signature.encodeSigners(metadata.config, (_metadata$parts = metadata.parts) != null ? _metadata$parts : new Map(), [], metadata.chainId);
291
- try {
292
- var _this$requests$get;
293
- const key = this.keyOfRequest(this.address, message, encoded, metadata.chainId);
294
- const lastAttempt = (_this$requests$get = this.requests.get(id)) == null ? void 0 : _this$requests$get.lastAttempt;
295
- if (lastAttempt === key) {
296
- return;
297
- }
298
- this.requests.get(id).lastAttempt = key;
299
- const result = await this.guard.signWith({
300
- signer: this.address,
301
- request: {
302
- msg: ethers.utils.hexlify(message),
303
- auxData: this.packMsgAndSig(metadata.address, metadata.digest, encoded, metadata.chainId),
304
- chainId: ethers.BigNumber.from(metadata.chainId).toNumber() // TODO: This should be a string (in the API)
305
- },
306
-
307
- token: metadata.guardTotpCode ? {
308
- id: AuthMethod.TOTP,
309
- token: metadata.guardTotpCode
310
- } : undefined
311
- });
312
- if (ethers.utils.arrayify(result.sig).length !== 0) {
313
- this.requests.get(id).onSignature(result.sig);
314
- this.requests.delete(id);
315
- }
316
- } catch (e) {
317
- var _this$onError;
318
- // The guard signer may reject the request for a number of reasons
319
- // like for example, if it's being the first signer (it waits for other signers to sign first)
320
- // We always forward the error here and filter on client side.
321
- (_this$onError = this.onError) == null ? void 0 : _this$onError.call(this, e);
322
- }
323
- }
324
309
  suffix() {
325
310
  return this.appendSuffix ? [3] : [];
326
311
  }
@@ -1,6 +1,6 @@
1
1
  export declare const WebRPCVersion = "v1";
2
2
  export declare const WebRPCSchemaVersion = "v0.4.0";
3
- export declare const WebRPCSchemaHash = "b3da61e22d917265bc35085a92b4173ea096a0c8";
3
+ export declare const WebRPCSchemaHash = "af5ad0623aec0b231a462052edaea1823f620a1e";
4
4
  export interface Version {
5
5
  webrpcVersion: string;
6
6
  schemaVersion: string;
@@ -38,6 +38,10 @@ export interface AuthToken {
38
38
  id: string;
39
39
  token: string;
40
40
  }
41
+ export interface RecoveryCode {
42
+ code: string;
43
+ used: boolean;
44
+ }
41
45
  export interface Guard {
42
46
  ping(headers?: object): Promise<PingReturn>;
43
47
  version(headers?: object): Promise<VersionReturn>;
@@ -118,6 +122,7 @@ export interface CommitTOTPArgs {
118
122
  token: string;
119
123
  }
120
124
  export interface CommitTOTPReturn {
125
+ codes: Array<RecoveryCode>;
121
126
  }
122
127
  export interface ResetTOTPArgs {
123
128
  timestamp: number;
@@ -2,30 +2,27 @@ import { Account } from '@0xsequence/account';
2
2
  import { signers, Status } from '@0xsequence/signhub';
3
3
  import { TypedData } from '@0xsequence/utils';
4
4
  import { BytesLike, ethers } from 'ethers';
5
+ import { RecoveryCode } from "./guard.gen.js";
5
6
  export declare class GuardSigner implements signers.SapientSigner {
6
7
  readonly address: string;
7
8
  readonly url: string;
8
9
  readonly appendSuffix: boolean;
9
- private readonly onError?;
10
10
  private guard;
11
- private requests;
12
- constructor(address: string, url: string, appendSuffix?: boolean, onError?: ((err: Error) => void) | undefined);
11
+ constructor(address: string, url: string, appendSuffix?: boolean);
13
12
  getAddress(): Promise<string>;
14
- requestSignature(id: string, _message: BytesLike, metadata: Object, callbacks: {
13
+ requestSignature(_id: string, message: BytesLike, metadata: Object, callbacks: {
15
14
  onSignature: (signature: BytesLike) => void;
16
15
  onRejection: (error: string) => void;
17
16
  onStatus: (situation: string) => void;
18
17
  }): Promise<boolean>;
19
- notifyStatusChange(id: string, status: Status, metadata: Object): void;
18
+ notifyStatusChange(_id: string, _status: Status, _metadata: Object): void;
20
19
  getAuthMethods(token: GetAuthMethodsToken): Promise<AuthMethod[]>;
21
20
  setPin(pin: string | undefined, token: UpdateAuthMethodToken): Promise<void>;
22
21
  resetPin(token: UpdateAuthMethodToken): Promise<void>;
23
22
  createTotp(token: UpdateAuthMethodToken): Promise<URL>;
24
- commitTotp(token: string, jwt: string): Promise<void>;
23
+ commitTotp(token: string, jwt: string): Promise<RecoveryCode[]>;
25
24
  resetTotp(token: UpdateAuthMethodToken): Promise<void>;
26
25
  private packMsgAndSig;
27
- private keyOfRequest;
28
- private evaluateRequest;
29
26
  suffix(): BytesLike;
30
27
  }
31
28
  export declare enum AuthMethod {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@0xsequence/guard",
3
- "version": "0.0.0-20231027021244",
3
+ "version": "0.0.0-20231102200515",
4
4
  "description": "guard sub-package for Sequence",
5
5
  "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/guard",
6
6
  "source": "src/index.ts",
@@ -10,10 +10,10 @@
10
10
  "license": "Apache-2.0",
11
11
  "dependencies": {
12
12
  "ethers": "^5.7.2",
13
- "@0xsequence/account": "0.0.0-20231027021244",
14
- "@0xsequence/signhub": "0.0.0-20231027021244",
15
- "@0xsequence/core": "0.0.0-20231027021244",
16
- "@0xsequence/utils": "0.0.0-20231027021244"
13
+ "@0xsequence/account": "0.0.0-20231102200515",
14
+ "@0xsequence/core": "0.0.0-20231102200515",
15
+ "@0xsequence/utils": "0.0.0-20231102200515",
16
+ "@0xsequence/signhub": "0.0.0-20231102200515"
17
17
  },
18
18
  "files": [
19
19
  "src",
package/src/guard.gen.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable */
2
- // sequence-guard v0.4.0 b3da61e22d917265bc35085a92b4173ea096a0c8
2
+ // sequence-guard v0.4.0 af5ad0623aec0b231a462052edaea1823f620a1e
3
3
  // --
4
4
  // Code generated by webrpc-gen@v0.12.x-dev with typescript@v0.10.0 generator. DO NOT EDIT.
5
5
  //
@@ -12,7 +12,7 @@ export const WebRPCVersion = 'v1'
12
12
  export const WebRPCSchemaVersion = 'v0.4.0'
13
13
 
14
14
  // Schema hash generated from your RIDL schema
15
- export const WebRPCSchemaHash = 'b3da61e22d917265bc35085a92b4173ea096a0c8'
15
+ export const WebRPCSchemaHash = 'af5ad0623aec0b231a462052edaea1823f620a1e'
16
16
 
17
17
  //
18
18
  // Types
@@ -62,6 +62,11 @@ export interface AuthToken {
62
62
  token: string
63
63
  }
64
64
 
65
+ export interface RecoveryCode {
66
+ code: string
67
+ used: boolean
68
+ }
69
+
65
70
  export interface Guard {
66
71
  ping(headers?: object): Promise<PingReturn>
67
72
  version(headers?: object): Promise<VersionReturn>
@@ -148,7 +153,9 @@ export interface CommitTOTPArgs {
148
153
  token: string
149
154
  }
150
155
 
151
- export interface CommitTOTPReturn {}
156
+ export interface CommitTOTPReturn {
157
+ codes: Array<RecoveryCode>
158
+ }
152
159
  export interface ResetTOTPArgs {
153
160
  timestamp: number
154
161
  signature: string
@@ -272,7 +279,9 @@ export class Guard implements Guard {
272
279
  commitTOTP = (args: CommitTOTPArgs, headers?: object): Promise<CommitTOTPReturn> => {
273
280
  return this.fetch(this.url('CommitTOTP'), createHTTPRequest(args, headers)).then(res => {
274
281
  return buildResponse(res).then(_data => {
275
- return {}
282
+ return {
283
+ codes: <Array<RecoveryCode>>_data.codes
284
+ }
276
285
  })
277
286
  })
278
287
  }
package/src/signer.ts CHANGED
@@ -3,27 +3,17 @@ import { commons, universal } from '@0xsequence/core'
3
3
  import { signers, Status } from '@0xsequence/signhub'
4
4
  import { TypedData } from '@0xsequence/utils'
5
5
  import { BytesLike, ethers, TypedDataDomain } from 'ethers'
6
- import { AuthMethodsReturn, Guard } from './guard.gen'
6
+ import { AuthMethodsReturn, Guard, RecoveryCode } from './guard.gen'
7
7
 
8
8
  const fetch = typeof global === 'object' ? global.fetch : window.fetch
9
9
 
10
10
  export class GuardSigner implements signers.SapientSigner {
11
11
  private guard: Guard
12
- private requests: Map<
13
- string,
14
- {
15
- lastAttempt?: string
16
- onSignature: (signature: BytesLike) => void
17
- onRejection: (error: string) => void
18
- onStatus: (situation: string) => void
19
- }
20
- > = new Map()
21
12
 
22
13
  constructor(
23
14
  public readonly address: string,
24
15
  public readonly url: string,
25
16
  public readonly appendSuffix: boolean = false,
26
- private readonly onError?: (err: Error) => void
27
17
  ) {
28
18
  this.guard = new Guard(url, fetch)
29
19
  }
@@ -33,8 +23,8 @@ export class GuardSigner implements signers.SapientSigner {
33
23
  }
34
24
 
35
25
  async requestSignature(
36
- id: string,
37
- _message: BytesLike,
26
+ _id: string,
27
+ message: BytesLike,
38
28
  metadata: Object,
39
29
  callbacks: {
40
30
  onSignature: (signature: BytesLike) => void
@@ -42,26 +32,44 @@ export class GuardSigner implements signers.SapientSigner {
42
32
  onStatus: (situation: string) => void
43
33
  }
44
34
  ): Promise<boolean> {
35
+ const { onSignature, onRejection } = callbacks
36
+
45
37
  if (!commons.isWalletSignRequestMetadata(metadata)) {
46
- callbacks.onRejection('Expected Sequence-like metadata')
47
- } else {
48
- // Queue the request first, this method only does that
49
- // the requesting to the API is later handled on every status change
50
- this.requests.set(id, callbacks)
38
+ onRejection('expected sequence signature request metadata')
39
+ return false
51
40
  }
52
41
 
53
- return true
54
- }
42
+ try {
43
+ const guardTotpCode = (metadata as { guardTotpCode?: string }).guardTotpCode
55
44
 
56
- notifyStatusChange(id: string, status: Status, metadata: Object): void {
57
- if (!this.requests.has(id)) return
45
+ // Building auxData, notice: this uses the old v1 format
46
+ // TODO: We should update the guard API so we can pass the metadata directly
47
+ const coder = universal.genericCoderFor(metadata.config.version)
48
+ const { encoded } = coder.signature.encodeSigners(metadata.config, metadata.parts ?? new Map(), [], metadata.chainId)
58
49
 
59
- if (!commons.isWalletSignRequestMetadata(metadata)) {
60
- this.requests.get(id)!.onRejection('Expected Sequence-like metadata (status update)')
61
- return
50
+ const { sig: signature } = await this.guard.signWith({
51
+ signer: this.address,
52
+ request: {
53
+ msg: ethers.utils.hexlify(message),
54
+ auxData: this.packMsgAndSig(metadata.address, metadata.digest, encoded, metadata.chainId),
55
+ chainId: ethers.BigNumber.from(metadata.chainId).toNumber()
56
+ },
57
+ token: guardTotpCode ? { id: AuthMethod.TOTP, token: guardTotpCode } : undefined
58
+ })
59
+
60
+ if (ethers.utils.arrayify(signature).length === 0) {
61
+ throw new Error('guard response contained no signature data')
62
+ }
63
+
64
+ onSignature(signature)
65
+ return true
66
+ } catch (error) {
67
+ onRejection(`unable to request guard signature: ${error}`)
68
+ return false
62
69
  }
70
+ }
63
71
 
64
- this.evaluateRequest(id, status.message, status, metadata)
72
+ notifyStatusChange(_id: string, _status: Status, _metadata: Object): void {
65
73
  }
66
74
 
67
75
  async getAuthMethods(token: GetAuthMethodsToken): Promise<AuthMethod[]> {
@@ -108,8 +116,9 @@ export class GuardSigner implements signers.SapientSigner {
108
116
  return new URL(uri)
109
117
  }
110
118
 
111
- async commitTotp(token: string, jwt: string): Promise<void> {
112
- await this.guard.commitTOTP({ token }, { Authorization: `BEARER ${jwt}` })
119
+ async commitTotp(token: string, jwt: string): Promise<RecoveryCode[]> {
120
+ const { codes } = await this.guard.commitTOTP({ token }, { Authorization: `BEARER ${jwt}` })
121
+ return codes
113
122
  }
114
123
 
115
124
  async resetTotp(token: UpdateAuthMethodToken): Promise<void> {
@@ -125,57 +134,6 @@ export class GuardSigner implements signers.SapientSigner {
125
134
  return ethers.utils.defaultAbiCoder.encode(['address', 'uint256', 'bytes', 'bytes'], [address, chainId, msg, sig])
126
135
  }
127
136
 
128
- private keyOfRequest(signer: string, msg: BytesLike, auxData: BytesLike, chainId: ethers.BigNumberish): string {
129
- return ethers.utils.solidityKeccak256(['address', 'uint256', 'bytes', 'bytes'], [signer, chainId, msg, auxData])
130
- }
131
-
132
- private async evaluateRequest(
133
- id: string,
134
- message: BytesLike,
135
- _: Status,
136
- metadata: commons.WalletSignRequestMetadata & { guardTotpCode?: string }
137
- ): Promise<void> {
138
- // Building auxData, notice: this uses the old v1 format
139
- // TODO: We should update the guard API so we can pass the metadata directly
140
- const coder = universal.genericCoderFor(metadata.config.version)
141
- const { encoded } = coder.signature.encodeSigners(metadata.config, metadata.parts ?? new Map(), [], metadata.chainId)
142
-
143
- try {
144
- const key = this.keyOfRequest(this.address, message, encoded, metadata.chainId)
145
- const lastAttempt = this.requests.get(id)?.lastAttempt
146
- if (lastAttempt === key) {
147
- return
148
- }
149
-
150
- this.requests.get(id)!.lastAttempt = key
151
-
152
- const result = await this.guard.signWith({
153
- signer: this.address,
154
- request: {
155
- msg: ethers.utils.hexlify(message),
156
- auxData: this.packMsgAndSig(metadata.address, metadata.digest, encoded, metadata.chainId),
157
- chainId: ethers.BigNumber.from(metadata.chainId).toNumber() // TODO: This should be a string (in the API)
158
- },
159
- token: metadata.guardTotpCode
160
- ? {
161
- id: AuthMethod.TOTP,
162
- token: metadata.guardTotpCode
163
- }
164
- : undefined
165
- })
166
-
167
- if (ethers.utils.arrayify(result.sig).length !== 0) {
168
- this.requests.get(id)!.onSignature(result.sig)
169
- this.requests.delete(id)
170
- }
171
- } catch (e) {
172
- // The guard signer may reject the request for a number of reasons
173
- // like for example, if it's being the first signer (it waits for other signers to sign first)
174
- // We always forward the error here and filter on client side.
175
- this.onError?.(e)
176
- }
177
- }
178
-
179
137
  suffix(): BytesLike {
180
138
  return this.appendSuffix ? [3] : []
181
139
  }