@0xsequence/guard 2.3.35 → 3.0.0-beta.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/.turbo/turbo-build.log +5 -0
- package/CHANGELOG.md +2954 -0
- package/LICENSE +0 -17
- package/README.md +1 -2
- package/dist/{declarations/src → client}/guard.gen.d.ts +47 -6
- package/dist/client/guard.gen.d.ts.map +1 -0
- package/dist/client/guard.gen.js +552 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/local.d.ts +14 -0
- package/dist/local.d.ts.map +1 -0
- package/dist/local.js +13 -0
- package/dist/sequence.d.ts +14 -0
- package/dist/sequence.d.ts.map +1 -0
- package/dist/sequence.js +44 -0
- package/dist/types.d.ts +11 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +9 -0
- package/package.json +23 -19
- package/src/{guard.gen.ts → client/guard.gen.ts} +190 -117
- package/src/index.ts +6 -2
- package/src/local.ts +23 -0
- package/src/sequence.ts +56 -0
- package/src/types.ts +27 -0
- package/test/sequence.test.ts +189 -0
- package/tsconfig.json +10 -0
- package/dist/0xsequence-guard.cjs.d.ts +0 -2
- package/dist/0xsequence-guard.cjs.dev.js +0 -768
- package/dist/0xsequence-guard.cjs.js +0 -7
- package/dist/0xsequence-guard.cjs.prod.js +0 -768
- package/dist/0xsequence-guard.esm.js +0 -758
- package/dist/declarations/src/index.d.ts +0 -2
- package/dist/declarations/src/signer.d.ts +0 -66
- package/src/signer.ts +0 -308
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { Account } from '@0xsequence/account';
|
|
2
|
-
import { commons } from '@0xsequence/core';
|
|
3
|
-
import { signers, Status } from '@0xsequence/signhub';
|
|
4
|
-
import { TypedData } from '@0xsequence/utils';
|
|
5
|
-
import { ethers } from 'ethers';
|
|
6
|
-
import { RecoveryCode as GuardRecoveryCode } from "./guard.gen.js";
|
|
7
|
-
export declare class GuardSigner implements signers.SapientSigner {
|
|
8
|
-
readonly address: string;
|
|
9
|
-
readonly url: string;
|
|
10
|
-
readonly appendSuffix: boolean;
|
|
11
|
-
readonly projectAccessKey?: string | undefined;
|
|
12
|
-
private guard;
|
|
13
|
-
constructor(address: string, url: string, appendSuffix?: boolean, projectAccessKey?: string | undefined);
|
|
14
|
-
_fetch: (input: RequestInfo, init?: RequestInit) => Promise<Response>;
|
|
15
|
-
getAddress(): Promise<string>;
|
|
16
|
-
buildDeployTransaction(_metadata: object): Promise<commons.transaction.TransactionBundle | undefined>;
|
|
17
|
-
predecorateSignedTransactions(_metadata: object): Promise<commons.transaction.SignedTransactionBundle[]>;
|
|
18
|
-
decorateTransactions(bundle: commons.transaction.IntendedTransactionBundle, _metadata: object): Promise<commons.transaction.IntendedTransactionBundle>;
|
|
19
|
-
sign(message: ethers.BytesLike, metadata: object): Promise<ethers.BytesLike>;
|
|
20
|
-
notifyStatusChange(_id: string, _status: Status, _metadata: object): void;
|
|
21
|
-
getAuthMethods(proof: OwnershipProof): Promise<{
|
|
22
|
-
methods: AuthMethod[];
|
|
23
|
-
active: boolean;
|
|
24
|
-
}>;
|
|
25
|
-
setPin(pin: string | undefined, proof: AuthUpdateProof): Promise<void>;
|
|
26
|
-
resetPin(proof: AuthUpdateProof): Promise<void>;
|
|
27
|
-
createTotp(proof: AuthUpdateProof): Promise<URL>;
|
|
28
|
-
commitTotp(token: string, jwt: string): Promise<RecoveryCode[]>;
|
|
29
|
-
resetTotp(proof: AuthUpdateProof): Promise<void>;
|
|
30
|
-
reset2fa(recoveryCode: string, proof: OwnershipProof): Promise<void>;
|
|
31
|
-
getRecoveryCodes(proof: AuthUpdateProof): Promise<RecoveryCode[]>;
|
|
32
|
-
resetRecoveryCodes(proof: AuthUpdateProof): Promise<RecoveryCode[]>;
|
|
33
|
-
private packMsgAndSig;
|
|
34
|
-
suffix(): ethers.BytesLike;
|
|
35
|
-
}
|
|
36
|
-
export type RecoveryCode = GuardRecoveryCode;
|
|
37
|
-
export declare enum AuthMethod {
|
|
38
|
-
PIN = "PIN",
|
|
39
|
-
TOTP = "TOTP"
|
|
40
|
-
}
|
|
41
|
-
export type SignedOwnershipProof = {
|
|
42
|
-
walletAddress: string;
|
|
43
|
-
timestamp: Date;
|
|
44
|
-
signerAddress: string;
|
|
45
|
-
signature: string;
|
|
46
|
-
};
|
|
47
|
-
export type OwnershipProof = SignedOwnershipProof | {
|
|
48
|
-
jwt: string;
|
|
49
|
-
} | {
|
|
50
|
-
walletAddress: string;
|
|
51
|
-
signer: ethers.Signer | signers.SapientSigner;
|
|
52
|
-
};
|
|
53
|
-
export declare function isSignedOwnershipProof(proof: OwnershipProof): proof is SignedOwnershipProof;
|
|
54
|
-
export declare function signOwnershipProof(proof: Exclude<OwnershipProof, {
|
|
55
|
-
jwt: string;
|
|
56
|
-
}>): Promise<SignedOwnershipProof>;
|
|
57
|
-
export type AuthUpdateProof = {
|
|
58
|
-
jwt: string;
|
|
59
|
-
} & ({
|
|
60
|
-
timestamp: Date;
|
|
61
|
-
signature: string;
|
|
62
|
-
} | {
|
|
63
|
-
wallet: Account;
|
|
64
|
-
});
|
|
65
|
-
export declare function getOwnershipProofTypedData(wallet: string, timestamp: Date): TypedData;
|
|
66
|
-
export declare function getAuthUpdateProofTypedData(timestamp: Date): TypedData;
|
package/src/signer.ts
DELETED
|
@@ -1,308 +0,0 @@
|
|
|
1
|
-
import { Account } from '@0xsequence/account'
|
|
2
|
-
import { commons, universal } from '@0xsequence/core'
|
|
3
|
-
import { signers, Status } from '@0xsequence/signhub'
|
|
4
|
-
import { encodeTypedDataDigest, TypedData } from '@0xsequence/utils'
|
|
5
|
-
import { ethers } from 'ethers'
|
|
6
|
-
import { AuthMethodsReturn, Guard, RecoveryCode as GuardRecoveryCode } from './guard.gen'
|
|
7
|
-
|
|
8
|
-
export class GuardSigner implements signers.SapientSigner {
|
|
9
|
-
private guard: Guard
|
|
10
|
-
|
|
11
|
-
constructor(
|
|
12
|
-
public readonly address: string,
|
|
13
|
-
public readonly url: string,
|
|
14
|
-
public readonly appendSuffix: boolean = false,
|
|
15
|
-
public readonly projectAccessKey?: string
|
|
16
|
-
) {
|
|
17
|
-
this.guard = new Guard(url, this._fetch)
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
_fetch = (input: RequestInfo, init?: RequestInit): Promise<Response> => {
|
|
21
|
-
const headers: { [key: string]: any } = {}
|
|
22
|
-
|
|
23
|
-
const projectAccessKey = this.projectAccessKey
|
|
24
|
-
|
|
25
|
-
if (projectAccessKey && projectAccessKey.length > 0) {
|
|
26
|
-
headers['X-Access-Key'] = projectAccessKey
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// before the request is made
|
|
30
|
-
init!.headers = { ...init!.headers, ...headers }
|
|
31
|
-
|
|
32
|
-
return fetch(input, init)
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
async getAddress(): Promise<string> {
|
|
36
|
-
return this.address
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
async buildDeployTransaction(_metadata: object): Promise<commons.transaction.TransactionBundle | undefined> {
|
|
40
|
-
return undefined
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
async predecorateSignedTransactions(_metadata: object): Promise<commons.transaction.SignedTransactionBundle[]> {
|
|
44
|
-
return []
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
async decorateTransactions(
|
|
48
|
-
bundle: commons.transaction.IntendedTransactionBundle,
|
|
49
|
-
_metadata: object
|
|
50
|
-
): Promise<commons.transaction.IntendedTransactionBundle> {
|
|
51
|
-
return bundle
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
async sign(message: ethers.BytesLike, metadata: object): Promise<ethers.BytesLike> {
|
|
55
|
-
if (!commons.isWalletSignRequestMetadata(metadata)) {
|
|
56
|
-
throw new Error('expected sequence signature request metadata')
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
const guardTotpCode = (metadata as { guardTotpCode?: string }).guardTotpCode
|
|
60
|
-
|
|
61
|
-
// Building auxData, notice: this uses the old v1 format
|
|
62
|
-
// TODO: We should update the guard API so we can pass the metadata directly
|
|
63
|
-
const coder = universal.genericCoderFor(metadata.config.version)
|
|
64
|
-
const { encoded } = coder.signature.encodeSigners(metadata.config, metadata.parts ?? new Map(), [], metadata.chainId)
|
|
65
|
-
|
|
66
|
-
return (
|
|
67
|
-
await this.guard.signWith({
|
|
68
|
-
signer: this.address,
|
|
69
|
-
request: {
|
|
70
|
-
msg: ethers.hexlify(message),
|
|
71
|
-
auxData: this.packMsgAndSig(metadata.address, metadata.digest, encoded, metadata.chainId),
|
|
72
|
-
chainId: Number(metadata.chainId)
|
|
73
|
-
},
|
|
74
|
-
token: guardTotpCode ? { id: AuthMethod.TOTP, token: guardTotpCode } : undefined
|
|
75
|
-
})
|
|
76
|
-
).sig
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
notifyStatusChange(_id: string, _status: Status, _metadata: object): void {}
|
|
80
|
-
|
|
81
|
-
async getAuthMethods(proof: OwnershipProof): Promise<{ methods: AuthMethod[]; active: boolean }> {
|
|
82
|
-
let response: AuthMethodsReturn
|
|
83
|
-
|
|
84
|
-
if ('jwt' in proof) {
|
|
85
|
-
response = await this.guard.authMethods({}, { Authorization: `BEARER ${proof.jwt}` })
|
|
86
|
-
} else {
|
|
87
|
-
const signedProof = await signOwnershipProof(proof)
|
|
88
|
-
|
|
89
|
-
response = await this.guard.authMethods({
|
|
90
|
-
proof: {
|
|
91
|
-
wallet: signedProof.walletAddress,
|
|
92
|
-
timestamp: signedProof.timestamp.getTime(),
|
|
93
|
-
signer: signedProof.signerAddress,
|
|
94
|
-
signature: signedProof.signature
|
|
95
|
-
}
|
|
96
|
-
})
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
return { ...response, methods: response.methods.map(parseAuthMethod) }
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
async setPin(pin: string | undefined, proof: AuthUpdateProof): Promise<void> {
|
|
103
|
-
const signedProof = await signAuthUpdateProof(proof)
|
|
104
|
-
|
|
105
|
-
if (pin === undefined) {
|
|
106
|
-
await this.guard.resetPIN(
|
|
107
|
-
{ timestamp: signedProof.timestamp.getTime(), signature: signedProof.signature },
|
|
108
|
-
{ Authorization: `BEARER ${proof.jwt}` }
|
|
109
|
-
)
|
|
110
|
-
} else {
|
|
111
|
-
await this.guard.setPIN(
|
|
112
|
-
{ pin, timestamp: signedProof.timestamp.getTime(), signature: signedProof.signature },
|
|
113
|
-
{ Authorization: `BEARER ${proof.jwt}` }
|
|
114
|
-
)
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
resetPin(proof: AuthUpdateProof): Promise<void> {
|
|
119
|
-
return this.setPin(undefined, proof)
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
async createTotp(proof: AuthUpdateProof): Promise<URL> {
|
|
123
|
-
const signedProof = await signAuthUpdateProof(proof)
|
|
124
|
-
|
|
125
|
-
const { uri } = await this.guard.createTOTP(
|
|
126
|
-
{ timestamp: signedProof.timestamp.getTime(), signature: signedProof.signature },
|
|
127
|
-
{ Authorization: `BEARER ${proof.jwt}` }
|
|
128
|
-
)
|
|
129
|
-
|
|
130
|
-
return new URL(uri)
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
async commitTotp(token: string, jwt: string): Promise<RecoveryCode[]> {
|
|
134
|
-
const { codes } = await this.guard.commitTOTP({ token }, { Authorization: `BEARER ${jwt}` })
|
|
135
|
-
return codes
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
async resetTotp(proof: AuthUpdateProof): Promise<void> {
|
|
139
|
-
const signedProof = await signAuthUpdateProof(proof)
|
|
140
|
-
|
|
141
|
-
await this.guard.resetTOTP(
|
|
142
|
-
{ timestamp: signedProof.timestamp.getTime(), signature: signedProof.signature },
|
|
143
|
-
{ Authorization: `BEARER ${proof.jwt}` }
|
|
144
|
-
)
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
async reset2fa(recoveryCode: string, proof: OwnershipProof): Promise<void> {
|
|
148
|
-
if ('jwt' in proof) {
|
|
149
|
-
await this.guard.reset2FA({ code: recoveryCode }, { Authorization: `BEARER ${proof.jwt}` })
|
|
150
|
-
} else {
|
|
151
|
-
const signedProof = await signOwnershipProof(proof)
|
|
152
|
-
|
|
153
|
-
await this.guard.reset2FA({
|
|
154
|
-
code: recoveryCode,
|
|
155
|
-
proof: {
|
|
156
|
-
wallet: signedProof.walletAddress,
|
|
157
|
-
timestamp: signedProof.timestamp.getTime(),
|
|
158
|
-
signer: signedProof.signerAddress,
|
|
159
|
-
signature: signedProof.signature
|
|
160
|
-
}
|
|
161
|
-
})
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
async getRecoveryCodes(proof: AuthUpdateProof): Promise<RecoveryCode[]> {
|
|
166
|
-
const signedProof = await signAuthUpdateProof(proof)
|
|
167
|
-
|
|
168
|
-
const { codes } = await this.guard.recoveryCodes(
|
|
169
|
-
{ timestamp: signedProof.timestamp.getTime(), signature: signedProof.signature },
|
|
170
|
-
{ Authorization: `BEARER ${proof.jwt}` }
|
|
171
|
-
)
|
|
172
|
-
|
|
173
|
-
return codes
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
async resetRecoveryCodes(proof: AuthUpdateProof): Promise<RecoveryCode[]> {
|
|
177
|
-
const signedProof = await signAuthUpdateProof(proof)
|
|
178
|
-
|
|
179
|
-
const { codes } = await this.guard.resetRecoveryCodes(
|
|
180
|
-
{ timestamp: signedProof.timestamp.getTime(), signature: signedProof.signature },
|
|
181
|
-
{ Authorization: `BEARER ${proof.jwt}` }
|
|
182
|
-
)
|
|
183
|
-
|
|
184
|
-
return codes
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
private packMsgAndSig(address: string, msg: ethers.BytesLike, sig: ethers.BytesLike, chainId: ethers.BigNumberish): string {
|
|
188
|
-
return ethers.AbiCoder.defaultAbiCoder().encode(['address', 'uint256', 'bytes', 'bytes'], [address, chainId, msg, sig])
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
suffix(): ethers.BytesLike {
|
|
192
|
-
return new Uint8Array(this.appendSuffix ? [3] : [])
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
export type RecoveryCode = GuardRecoveryCode
|
|
197
|
-
|
|
198
|
-
export enum AuthMethod {
|
|
199
|
-
PIN = 'PIN',
|
|
200
|
-
TOTP = 'TOTP'
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
function parseAuthMethod(method: string): AuthMethod {
|
|
204
|
-
switch (method) {
|
|
205
|
-
case AuthMethod.PIN:
|
|
206
|
-
case AuthMethod.TOTP:
|
|
207
|
-
return method
|
|
208
|
-
default:
|
|
209
|
-
throw new Error(`unknown auth method '${method}'`)
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
export type SignedOwnershipProof = {
|
|
214
|
-
walletAddress: string
|
|
215
|
-
timestamp: Date
|
|
216
|
-
signerAddress: string
|
|
217
|
-
signature: string
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
export type OwnershipProof =
|
|
221
|
-
| SignedOwnershipProof
|
|
222
|
-
| { jwt: string }
|
|
223
|
-
| {
|
|
224
|
-
walletAddress: string
|
|
225
|
-
signer: ethers.Signer | signers.SapientSigner
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
export function isSignedOwnershipProof(proof: OwnershipProof): proof is SignedOwnershipProof {
|
|
229
|
-
return 'signerAddress' in proof && typeof proof.signerAddress === 'string'
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
export async function signOwnershipProof(proof: Exclude<OwnershipProof, { jwt: string }>): Promise<SignedOwnershipProof> {
|
|
233
|
-
if (isSignedOwnershipProof(proof)) {
|
|
234
|
-
return proof
|
|
235
|
-
} else {
|
|
236
|
-
const signer = signers.isSapientSigner(proof.signer) ? proof.signer : new signers.SignerWrapper(proof.signer)
|
|
237
|
-
const signerAddress = await signer.getAddress()
|
|
238
|
-
const timestamp = new Date()
|
|
239
|
-
const typedData = getOwnershipProofTypedData(proof.walletAddress, timestamp)
|
|
240
|
-
const digest = encodeTypedDataDigest(typedData)
|
|
241
|
-
|
|
242
|
-
return {
|
|
243
|
-
walletAddress: proof.walletAddress,
|
|
244
|
-
timestamp,
|
|
245
|
-
signerAddress,
|
|
246
|
-
signature: ethers.hexlify(await signer.sign(digest, {}))
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
export type AuthUpdateProof = { jwt: string } & ({ timestamp: Date; signature: string } | { wallet: Account })
|
|
252
|
-
|
|
253
|
-
async function signAuthUpdateProof(proof: AuthUpdateProof): Promise<{ jwt: string; timestamp: Date; signature: string }> {
|
|
254
|
-
if ('wallet' in proof) {
|
|
255
|
-
const timestamp = new Date()
|
|
256
|
-
const typedData = getAuthUpdateProofTypedData(timestamp)
|
|
257
|
-
|
|
258
|
-
const signature = await proof.wallet.signTypedData(
|
|
259
|
-
typedData.domain,
|
|
260
|
-
typedData.types,
|
|
261
|
-
typedData.message,
|
|
262
|
-
typedData.domain.chainId ?? 1,
|
|
263
|
-
'eip6492'
|
|
264
|
-
)
|
|
265
|
-
|
|
266
|
-
return { jwt: proof.jwt, timestamp, signature }
|
|
267
|
-
} else {
|
|
268
|
-
return proof
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
export function getOwnershipProofTypedData(wallet: string, timestamp: Date): TypedData {
|
|
273
|
-
return {
|
|
274
|
-
domain,
|
|
275
|
-
types: {
|
|
276
|
-
AuthMethods: [
|
|
277
|
-
{ name: 'wallet', type: 'address' },
|
|
278
|
-
{ name: 'timestamp', type: 'string' }
|
|
279
|
-
]
|
|
280
|
-
},
|
|
281
|
-
message: {
|
|
282
|
-
wallet: ethers.getAddress(wallet),
|
|
283
|
-
timestamp: toUTCString(timestamp)
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
export function getAuthUpdateProofTypedData(timestamp: Date): TypedData {
|
|
289
|
-
return {
|
|
290
|
-
domain,
|
|
291
|
-
types: {
|
|
292
|
-
AuthUpdate: [{ name: 'timestamp', type: 'string' }]
|
|
293
|
-
},
|
|
294
|
-
message: {
|
|
295
|
-
timestamp: toUTCString(timestamp)
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
const domain: ethers.TypedDataDomain = {
|
|
301
|
-
name: 'Sequence Guard',
|
|
302
|
-
version: '1',
|
|
303
|
-
chainId: 1
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
function toUTCString(date: Date): string {
|
|
307
|
-
return date.toUTCString().replace('GMT', 'UTC')
|
|
308
|
-
}
|