-
Notifications
You must be signed in to change notification settings - Fork 84
Expand file tree
/
Copy pathFederatedKeylessAccount.ts
More file actions
182 lines (171 loc) · 6.99 KB
/
FederatedKeylessAccount.ts
File metadata and controls
182 lines (171 loc) · 6.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
// Copyright © Aptos Foundation
// SPDX-License-Identifier: Apache-2.0
import { HexInput } from "../types";
import { AccountAddress, AccountAddressInput } from "../core/accountAddress";
import { getIssAudAndUidVal, Groth16VerificationKey, ZeroKnowledgeSig } from "../core/crypto";
import { EphemeralKeyPair } from "./EphemeralKeyPair";
import { Deserializer, Serializer } from "../bcs";
import { FederatedKeylessPublicKey } from "../core/crypto/federatedKeyless";
import { AbstractKeylessAccount, ProofFetchCallback } from "./AbstractKeylessAccount";
/**
* Account implementation for the FederatedKeyless authentication scheme.
*
* Used to represent a FederatedKeyless based account and sign transactions with it.
*
* Use `FederatedKeylessAccount.create()` to instantiate a KeylessAccount with a JSON Web Token (JWT), proof, EphemeralKeyPair and the
* address the JSON Web Key Set (JWKS) are installed that will be used to verify the JWT.
*
* When the proof expires or the JWT becomes invalid, the KeylessAccount must be instantiated again with a new JWT,
* EphemeralKeyPair, and corresponding proof.
* @group Implementation
* @category Account (On-Chain Model)
*/
export class FederatedKeylessAccount extends AbstractKeylessAccount {
/**
* The FederatedKeylessPublicKey associated with the account
* @group Implementation
* @category Account (On-Chain Model)
*/
readonly publicKey: FederatedKeylessPublicKey;
readonly audless: boolean;
/**
* Use the static generator `FederatedKeylessAccount.create(...)` instead.
* Creates a KeylessAccount instance using the provided parameters.
* This function allows you to set up a KeylessAccount with specific attributes such as address, proof, and JWT.
*
* **Important**: This constructor uses `FederatedKeylessPublicKey.createSync()` which requires
* poseidon-lite to already be loaded. Use `FederatedKeylessAccount.create()` (async) for the
* standard flow, or call `await ensurePoseidonLoaded()` before constructing/deserializing directly.
*
* @param args - The parameters for creating a KeylessAccount.
* @param args.address - Optional account address associated with the KeylessAccount.
* @param args.proof - A Zero Knowledge Signature or a promise that resolves to one.
* @param args.jwt - A JSON Web Token used for authentication.
* @param args.ephemeralKeyPair - The ephemeral key pair used in the account creation.
* @param args.jwkAddress - The address which stores the JSON Web Key Set (JWKS) used to verify the JWT.
* @param args.uidKey - Optional key for user identification, defaults to "sub".
* @param args.proofFetchCallback - Optional callback function for fetching proof.
*/
constructor(args: {
address?: AccountAddress;
ephemeralKeyPair: EphemeralKeyPair;
iss: string;
uidKey: string;
uidVal: string;
aud: string;
pepper: HexInput;
jwkAddress: AccountAddress;
proof: ZeroKnowledgeSig | Promise<ZeroKnowledgeSig>;
proofFetchCallback?: ProofFetchCallback;
jwt: string;
verificationKeyHash?: HexInput;
audless?: boolean;
}) {
const publicKey = FederatedKeylessPublicKey.createSync(args);
super({ publicKey, ...args });
this.publicKey = publicKey;
this.audless = args.audless ?? false;
}
/**
* Serializes the transaction data into a format suitable for transmission or storage.
* This function ensures that both the transaction bytes and the proof are properly serialized.
*
* @param serializer - The serializer instance used to convert the transaction data into bytes.
*/
serialize(serializer: Serializer): void {
super.serialize(serializer);
this.publicKey.jwkAddress.serialize(serializer);
}
/**
* Deserializes the provided deserializer to create a KeylessAccount instance.
* This function extracts necessary components such as the JWT, UID key, pepper, ephemeral key pair, and proof from the deserializer.
*
* @param deserializer - The deserializer instance used to retrieve the serialized data.
* @returns A KeylessAccount instance created from the deserialized data.
*/
static deserialize(deserializer: Deserializer): FederatedKeylessAccount {
const { address, proof, ephemeralKeyPair, jwt, uidKey, pepper, verificationKeyHash } =
AbstractKeylessAccount.partialDeserialize(deserializer);
const jwkAddress = AccountAddress.deserialize(deserializer);
const { iss, aud, uidVal } = getIssAudAndUidVal({ jwt, uidKey });
return new FederatedKeylessAccount({
address,
proof,
ephemeralKeyPair,
iss,
uidKey,
uidVal,
aud,
pepper,
jwt,
verificationKeyHash,
jwkAddress,
});
}
/**
* Deserialize bytes using this account's information.
*
* @param bytes The bytes being interpreted.
* @returns
*/
static fromBytes(bytes: HexInput): FederatedKeylessAccount {
return FederatedKeylessAccount.deserialize(Deserializer.fromHex(bytes));
}
/**
* Creates a KeylessAccount instance using the provided parameters.
* This function allows you to set up a KeylessAccount with specific attributes such as address, proof, and JWT.
* This is used instead of the KeylessAccount constructor.
*
* @param args - The parameters for creating a KeylessAccount.
* @param args.address - Optional account address associated with the KeylessAccount.
* @param args.proof - A Zero Knowledge Signature or a promise that resolves to one.
* @param args.jwt - A JSON Web Token used for authentication.
* @param args.ephemeralKeyPair - The ephemeral key pair used in the account creation.
* @param args.jwkAddress - The address which stores the JSON Web Key Set (JWKS) used to verify the JWT.
* @param args.uidKey - Optional key for user identification, defaults to "sub".
* @param args.proofFetchCallback - Optional callback function for fetching proof.
*/
static create(args: {
address?: AccountAddress;
proof: ZeroKnowledgeSig | Promise<ZeroKnowledgeSig>;
jwt: string;
ephemeralKeyPair: EphemeralKeyPair;
pepper: HexInput;
jwkAddress: AccountAddressInput;
uidKey?: string;
proofFetchCallback?: ProofFetchCallback;
verificationKey?: Groth16VerificationKey;
verificationKeyHash?: Uint8Array;
}): FederatedKeylessAccount {
const {
address,
proof,
jwt,
ephemeralKeyPair,
pepper,
jwkAddress,
uidKey = "sub",
proofFetchCallback,
verificationKey,
verificationKeyHash,
} = args;
if (verificationKeyHash && verificationKey) {
throw new Error("Cannot provide both verificationKey and verificationKeyHash");
}
const { iss, aud, uidVal } = getIssAudAndUidVal({ jwt, uidKey });
return new FederatedKeylessAccount({
address,
proof,
ephemeralKeyPair,
iss,
uidKey,
uidVal,
aud,
pepper,
jwkAddress: AccountAddress.from(jwkAddress),
jwt,
proofFetchCallback,
verificationKeyHash: verificationKeyHash ?? (verificationKey ? verificationKey.hash() : undefined),
});
}
}