@stellar/stellar-sdk 14.3.3 → 14.4.1
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/CHANGELOG.md +22 -1
- package/dist/stellar-sdk-minimal.js +7220 -7111
- package/dist/stellar-sdk-minimal.min.js +1 -1
- package/dist/stellar-sdk-no-axios.js +3454 -3345
- package/dist/stellar-sdk-no-axios.min.js +1 -1
- package/dist/stellar-sdk-no-eventsource.js +7471 -7362
- package/dist/stellar-sdk-no-eventsource.min.js +1 -1
- package/dist/stellar-sdk.js +7972 -7863
- package/dist/stellar-sdk.min.js +1 -1
- package/lib/config.d.ts +2 -6
- package/lib/contract/assembled_transaction.d.ts +16 -132
- package/lib/contract/assembled_transaction.js +14 -114
- package/lib/contract/errors.d.ts +26 -0
- package/lib/contract/errors.js +126 -0
- package/lib/contract/sent_transaction.d.ts +1 -1
- package/lib/contract/spec.d.ts +2 -2
- package/lib/contract/spec.js +31 -28
- package/lib/contract/types.d.ts +47 -8
- package/lib/contract/utils.d.ts +1 -1
- package/lib/contract/utils.js +18 -53
- package/lib/contract/wasm_spec_parser.d.ts +7 -0
- package/lib/contract/wasm_spec_parser.js +15 -0
- package/lib/errors/network.d.ts +1 -1
- package/lib/federation/server.d.ts +7 -7
- package/lib/horizon/horizon_axios_client.js +1 -1
- package/lib/horizon/server.d.ts +1 -1
- package/lib/horizon/server.js +2 -2
- package/lib/index.d.ts +0 -3
- package/lib/minimal/config.d.ts +2 -6
- package/lib/minimal/contract/assembled_transaction.d.ts +16 -132
- package/lib/minimal/contract/assembled_transaction.js +14 -114
- package/lib/minimal/contract/errors.d.ts +26 -0
- package/lib/minimal/contract/errors.js +126 -0
- package/lib/minimal/contract/sent_transaction.d.ts +1 -1
- package/lib/minimal/contract/spec.d.ts +2 -2
- package/lib/minimal/contract/spec.js +31 -28
- package/lib/minimal/contract/types.d.ts +47 -8
- package/lib/minimal/contract/utils.d.ts +1 -1
- package/lib/minimal/contract/utils.js +18 -53
- package/lib/minimal/contract/wasm_spec_parser.d.ts +7 -0
- package/lib/minimal/contract/wasm_spec_parser.js +15 -0
- package/lib/minimal/errors/network.d.ts +1 -1
- package/lib/minimal/federation/server.d.ts +7 -7
- package/lib/minimal/horizon/horizon_axios_client.js +1 -1
- package/lib/minimal/horizon/server.d.ts +1 -1
- package/lib/minimal/horizon/server.js +2 -2
- package/lib/minimal/index.d.ts +0 -3
- package/lib/minimal/rpc/api.d.ts +28 -4
- package/lib/minimal/rpc/axios.js +1 -1
- package/lib/minimal/rpc/jsonrpc.d.ts +2 -1
- package/lib/minimal/rpc/jsonrpc.js +1 -1
- package/lib/minimal/rpc/parsers.js +8 -5
- package/lib/minimal/rpc/server.d.ts +46 -7
- package/lib/minimal/rpc/server.js +290 -211
- package/lib/minimal/rpc/utils.js +1 -1
- package/lib/minimal/webauth/challenge_transaction.d.ts +235 -0
- package/lib/minimal/webauth/challenge_transaction.js +307 -0
- package/lib/minimal/webauth/index.d.ts +1 -0
- package/lib/minimal/webauth/index.js +13 -1
- package/lib/minimal/webauth/utils.d.ts +28 -273
- package/lib/minimal/webauth/utils.js +12 -288
- package/lib/no-axios/config.d.ts +2 -6
- package/lib/no-axios/contract/assembled_transaction.d.ts +16 -132
- package/lib/no-axios/contract/assembled_transaction.js +14 -114
- package/lib/no-axios/contract/errors.d.ts +26 -0
- package/lib/no-axios/contract/errors.js +126 -0
- package/lib/no-axios/contract/sent_transaction.d.ts +1 -1
- package/lib/no-axios/contract/spec.d.ts +2 -2
- package/lib/no-axios/contract/spec.js +31 -28
- package/lib/no-axios/contract/types.d.ts +47 -8
- package/lib/no-axios/contract/utils.d.ts +1 -1
- package/lib/no-axios/contract/utils.js +18 -53
- package/lib/no-axios/contract/wasm_spec_parser.d.ts +7 -0
- package/lib/no-axios/contract/wasm_spec_parser.js +15 -0
- package/lib/no-axios/errors/network.d.ts +1 -1
- package/lib/no-axios/federation/server.d.ts +7 -7
- package/lib/no-axios/horizon/horizon_axios_client.js +1 -1
- package/lib/no-axios/horizon/server.d.ts +1 -1
- package/lib/no-axios/horizon/server.js +2 -2
- package/lib/no-axios/index.d.ts +0 -3
- package/lib/no-axios/rpc/api.d.ts +28 -4
- package/lib/no-axios/rpc/axios.js +1 -1
- package/lib/no-axios/rpc/jsonrpc.d.ts +2 -1
- package/lib/no-axios/rpc/jsonrpc.js +1 -1
- package/lib/no-axios/rpc/parsers.js +8 -5
- package/lib/no-axios/rpc/server.d.ts +46 -7
- package/lib/no-axios/rpc/server.js +290 -211
- package/lib/no-axios/rpc/utils.js +1 -1
- package/lib/no-axios/webauth/challenge_transaction.d.ts +235 -0
- package/lib/no-axios/webauth/challenge_transaction.js +307 -0
- package/lib/no-axios/webauth/index.d.ts +1 -0
- package/lib/no-axios/webauth/index.js +13 -1
- package/lib/no-axios/webauth/utils.d.ts +28 -273
- package/lib/no-axios/webauth/utils.js +12 -288
- package/lib/no-eventsource/config.d.ts +2 -6
- package/lib/no-eventsource/contract/assembled_transaction.d.ts +16 -132
- package/lib/no-eventsource/contract/assembled_transaction.js +14 -114
- package/lib/no-eventsource/contract/errors.d.ts +26 -0
- package/lib/no-eventsource/contract/errors.js +126 -0
- package/lib/no-eventsource/contract/sent_transaction.d.ts +1 -1
- package/lib/no-eventsource/contract/spec.d.ts +2 -2
- package/lib/no-eventsource/contract/spec.js +31 -28
- package/lib/no-eventsource/contract/types.d.ts +47 -8
- package/lib/no-eventsource/contract/utils.d.ts +1 -1
- package/lib/no-eventsource/contract/utils.js +18 -53
- package/lib/no-eventsource/contract/wasm_spec_parser.d.ts +7 -0
- package/lib/no-eventsource/contract/wasm_spec_parser.js +15 -0
- package/lib/no-eventsource/errors/network.d.ts +1 -1
- package/lib/no-eventsource/federation/server.d.ts +7 -7
- package/lib/no-eventsource/horizon/horizon_axios_client.js +1 -1
- package/lib/no-eventsource/horizon/server.d.ts +1 -1
- package/lib/no-eventsource/horizon/server.js +2 -2
- package/lib/no-eventsource/index.d.ts +0 -3
- package/lib/no-eventsource/rpc/api.d.ts +28 -4
- package/lib/no-eventsource/rpc/axios.js +1 -1
- package/lib/no-eventsource/rpc/jsonrpc.d.ts +2 -1
- package/lib/no-eventsource/rpc/jsonrpc.js +1 -1
- package/lib/no-eventsource/rpc/parsers.js +8 -5
- package/lib/no-eventsource/rpc/server.d.ts +46 -7
- package/lib/no-eventsource/rpc/server.js +290 -211
- package/lib/no-eventsource/rpc/utils.js +1 -1
- package/lib/no-eventsource/webauth/challenge_transaction.d.ts +235 -0
- package/lib/no-eventsource/webauth/challenge_transaction.js +307 -0
- package/lib/no-eventsource/webauth/index.d.ts +1 -0
- package/lib/no-eventsource/webauth/index.js +13 -1
- package/lib/no-eventsource/webauth/utils.d.ts +28 -273
- package/lib/no-eventsource/webauth/utils.js +12 -288
- package/lib/rpc/api.d.ts +28 -4
- package/lib/rpc/axios.js +1 -1
- package/lib/rpc/jsonrpc.d.ts +2 -1
- package/lib/rpc/jsonrpc.js +1 -1
- package/lib/rpc/parsers.js +8 -5
- package/lib/rpc/server.d.ts +46 -7
- package/lib/rpc/server.js +290 -211
- package/lib/rpc/utils.js +1 -1
- package/lib/webauth/challenge_transaction.d.ts +235 -0
- package/lib/webauth/challenge_transaction.js +307 -0
- package/lib/webauth/index.d.ts +1 -0
- package/lib/webauth/index.js +13 -1
- package/lib/webauth/utils.d.ts +28 -273
- package/lib/webauth/utils.js +12 -288
- package/package.json +14 -14
- package/types/dom-monkeypatch.d.ts +1 -1
package/lib/rpc/utils.js
CHANGED
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import { Keypair, Transaction } from "@stellar/stellar-base";
|
|
2
|
+
import { ServerApi } from "../horizon/server_api";
|
|
3
|
+
/**
|
|
4
|
+
* Returns a valid {@link https://stellar.org/protocol/sep-10 | SEP-10}
|
|
5
|
+
* challenge transaction which you can use for Stellar Web Authentication.
|
|
6
|
+
* @param serverKeypair Keypair for server's signing account.
|
|
7
|
+
* @param clientAccountID The stellar account (G...) or muxed account
|
|
8
|
+
* (M...) that the wallet wishes to authenticate with the server.
|
|
9
|
+
* @param homeDomain The fully qualified domain name of the service
|
|
10
|
+
* requiring authentication
|
|
11
|
+
* @param timeout Challenge duration (default to 5 minutes).
|
|
12
|
+
* @param networkPassphrase The network passphrase. If you pass this
|
|
13
|
+
* argument then timeout is required.
|
|
14
|
+
* @param webAuthDomain The fully qualified domain name of the service
|
|
15
|
+
* issuing the challenge.
|
|
16
|
+
* @param memo The memo to attach to the challenge transaction. The
|
|
17
|
+
* memo must be of type `id`. If the `clientaccountID` is a muxed account,
|
|
18
|
+
* memos cannot be used.
|
|
19
|
+
* @param clientDomain The fully qualified domain of the client
|
|
20
|
+
* requesting the challenge. Only necessary when the 'client_domain'
|
|
21
|
+
* parameter is passed.
|
|
22
|
+
* @param clientSigningKey The public key assigned to the SIGNING_KEY
|
|
23
|
+
* attribute specified on the stellar.toml hosted on the client domain. Only
|
|
24
|
+
* necessary when the 'client_domain' parameter is passed.
|
|
25
|
+
* @returns A base64 encoded string of the raw TransactionEnvelope xdr
|
|
26
|
+
* struct for the transaction.
|
|
27
|
+
* @throws {Error} Will throw if `clientAccountID is a muxed account, and `memo`
|
|
28
|
+
* is present.
|
|
29
|
+
* @throws {Error} Will throw if `clientDomain` is provided, but
|
|
30
|
+
* `clientSigningKey` is missing
|
|
31
|
+
* @see {@link https://stellar.org/protocol/sep-10 | SEP-10: Stellar Web Auth}
|
|
32
|
+
* @example
|
|
33
|
+
* import { Keypair, Networks, WebAuth } from 'stellar-sdk'
|
|
34
|
+
*
|
|
35
|
+
* let serverKeyPair = Keypair.fromSecret("server-secret")
|
|
36
|
+
* let challenge = WebAuth.buildChallengeTx(
|
|
37
|
+
* serverKeyPair,
|
|
38
|
+
* "client-stellar-account-id",
|
|
39
|
+
* "stellar.org",
|
|
40
|
+
* 300,
|
|
41
|
+
* Networks.TESTNET);
|
|
42
|
+
*/
|
|
43
|
+
export declare function buildChallengeTx(serverKeypair: Keypair, clientAccountID: string, homeDomain: string, timeout: number | undefined, networkPassphrase: string, webAuthDomain: string, memo?: string | null, clientDomain?: string | null, clientSigningKey?: string | null): string;
|
|
44
|
+
/**
|
|
45
|
+
* Reads a SEP-10 challenge transaction and returns the decoded transaction and
|
|
46
|
+
* client account ID contained within.
|
|
47
|
+
*
|
|
48
|
+
* It also verifies that the transaction has been signed by the server.
|
|
49
|
+
*
|
|
50
|
+
* It does not verify that the transaction has been signed by the client or that
|
|
51
|
+
* any signatures other than the server's on the transaction are valid. Use one
|
|
52
|
+
* of the following functions to completely verify the transaction:
|
|
53
|
+
*
|
|
54
|
+
* - {@link module:WebAuth~verifyChallengeTxThreshold}
|
|
55
|
+
* - {@link module:WebAuth~verifyChallengeTxSigners}
|
|
56
|
+
* @param challengeTx SEP0010 challenge transaction in base64.
|
|
57
|
+
* @param serverAccountID The server's stellar account (public key).
|
|
58
|
+
* @param networkPassphrase The network passphrase, e.g.: 'Test SDF
|
|
59
|
+
* Network ; September 2015' (see {@link Networks})
|
|
60
|
+
* @param homeDomains The home domain that is expected
|
|
61
|
+
* to be included in the first Manage Data operation's string key. If an
|
|
62
|
+
* array is provided, one of the domain names in the array must match.
|
|
63
|
+
* @param webAuthDomain The home domain that is expected to be included
|
|
64
|
+
* as the value of the Manage Data operation with the 'web_auth_domain' key.
|
|
65
|
+
* If no such operation is included, this parameter is not used.
|
|
66
|
+
* @returns The actual transaction and the
|
|
67
|
+
* Stellar public key (master key) used to sign the Manage Data operation,
|
|
68
|
+
* the matched home domain, and the memo attached to the transaction, which
|
|
69
|
+
* will be null if not present.
|
|
70
|
+
* @see {@link https://stellar.org/protocol/sep-10 | SEP-10: Stellar Web Auth}
|
|
71
|
+
*/
|
|
72
|
+
export declare function readChallengeTx(challengeTx: string, serverAccountID: string, networkPassphrase: string, homeDomains: string | string[], webAuthDomain: string): {
|
|
73
|
+
tx: Transaction;
|
|
74
|
+
clientAccountID: string;
|
|
75
|
+
matchedHomeDomain: string;
|
|
76
|
+
memo: string | null;
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Verifies that for a SEP 10 challenge transaction all signatures on the
|
|
80
|
+
* transaction are accounted for. A transaction is verified if it is signed by
|
|
81
|
+
* the server account, and all other signatures match a signer that has been
|
|
82
|
+
* provided as an argument (as the accountIDs list). Additional signers can be
|
|
83
|
+
* provided that do not have a signature, but all signatures must be matched to
|
|
84
|
+
* a signer (accountIDs) for verification to succeed. If verification succeeds,
|
|
85
|
+
* a list of signers that were found is returned, not including the server
|
|
86
|
+
* account ID.
|
|
87
|
+
*
|
|
88
|
+
* Signers that are not prefixed as an address/account ID strkey (G...) will be
|
|
89
|
+
* ignored.
|
|
90
|
+
*
|
|
91
|
+
* Errors will be raised if:
|
|
92
|
+
* - The transaction is invalid according to
|
|
93
|
+
* {@link module:WebAuth~readChallengeTx}.
|
|
94
|
+
* - No client signatures are found on the transaction.
|
|
95
|
+
* - One or more signatures in the transaction are not identifiable as the
|
|
96
|
+
* server account or one of the signers provided in the arguments.
|
|
97
|
+
* @param challengeTx SEP0010 challenge transaction in base64.
|
|
98
|
+
* @param serverAccountID The server's stellar account (public key).
|
|
99
|
+
* @param networkPassphrase The network passphrase, e.g.: 'Test SDF
|
|
100
|
+
* Network ; September 2015' (see {@link Networks}).
|
|
101
|
+
* @param signers The signers public keys. This list should
|
|
102
|
+
* contain the public keys for all signers that have signed the transaction.
|
|
103
|
+
* @param homeDomains The home domain(s) that should
|
|
104
|
+
* be included in the first Manage Data operation's string key. Required in
|
|
105
|
+
* readChallengeTx().
|
|
106
|
+
* @param webAuthDomain The home domain that is expected to be included
|
|
107
|
+
* as the value of the Manage Data operation with the 'web_auth_domain' key,
|
|
108
|
+
* if present. Used in readChallengeTx().
|
|
109
|
+
* @returns The list of signers public keys that have signed
|
|
110
|
+
* the transaction, excluding the server account ID.
|
|
111
|
+
* @see {@link https://stellar.org/protocol/sep-10|SEP-10: Stellar Web Auth}
|
|
112
|
+
* @example
|
|
113
|
+
* import { Networks, TransactionBuilder, WebAuth } from 'stellar-sdk';
|
|
114
|
+
*
|
|
115
|
+
* const serverKP = Keypair.random();
|
|
116
|
+
* const clientKP1 = Keypair.random();
|
|
117
|
+
* const clientKP2 = Keypair.random();
|
|
118
|
+
*
|
|
119
|
+
* // Challenge, possibly built in the server side
|
|
120
|
+
* const challenge = WebAuth.buildChallengeTx(
|
|
121
|
+
* serverKP,
|
|
122
|
+
* clientKP1.publicKey(),
|
|
123
|
+
* "SDF",
|
|
124
|
+
* 300,
|
|
125
|
+
* Networks.TESTNET
|
|
126
|
+
* );
|
|
127
|
+
*
|
|
128
|
+
* // clock.tick(200); // Simulates a 200 ms delay when communicating from server to client
|
|
129
|
+
*
|
|
130
|
+
* // Transaction gathered from a challenge, possibly from the client side
|
|
131
|
+
* const transaction = TransactionBuilder.fromXDR(challenge, Networks.TESTNET);
|
|
132
|
+
* transaction.sign(clientKP1, clientKP2);
|
|
133
|
+
* const signedChallenge = transaction
|
|
134
|
+
* .toEnvelope()
|
|
135
|
+
* .toXDR("base64")
|
|
136
|
+
* .toString();
|
|
137
|
+
*
|
|
138
|
+
* // The result below should be equal to [clientKP1.publicKey(), clientKP2.publicKey()]
|
|
139
|
+
* WebAuth.verifyChallengeTxSigners(
|
|
140
|
+
* signedChallenge,
|
|
141
|
+
* serverKP.publicKey(),
|
|
142
|
+
* Networks.TESTNET,
|
|
143
|
+
* threshold,
|
|
144
|
+
* [clientKP1.publicKey(), clientKP2.publicKey()]
|
|
145
|
+
* );
|
|
146
|
+
*/
|
|
147
|
+
export declare function verifyChallengeTxSigners(challengeTx: string, serverAccountID: string, networkPassphrase: string, signers: string[], homeDomains: string | string[], webAuthDomain: string): string[];
|
|
148
|
+
/**
|
|
149
|
+
* Verifies that for a SEP-10 challenge transaction all signatures on the
|
|
150
|
+
* transaction are accounted for and that the signatures meet a threshold on an
|
|
151
|
+
* account. A transaction is verified if it is signed by the server account, and
|
|
152
|
+
* all other signatures match a signer that has been provided as an argument,
|
|
153
|
+
* and those signatures meet a threshold on the account.
|
|
154
|
+
*
|
|
155
|
+
* Signers that are not prefixed as an address/account ID strkey (G...) will be
|
|
156
|
+
* ignored.
|
|
157
|
+
*
|
|
158
|
+
* Errors will be raised if:
|
|
159
|
+
* - The transaction is invalid according to
|
|
160
|
+
* {@link module:WebAuth~readChallengeTx}.
|
|
161
|
+
* - No client signatures are found on the transaction.
|
|
162
|
+
* - One or more signatures in the transaction are not identifiable as the
|
|
163
|
+
* server account or one of the signers provided in the arguments.
|
|
164
|
+
* - The signatures are all valid but do not meet the threshold.
|
|
165
|
+
* @param challengeTx SEP0010 challenge transaction in base64.
|
|
166
|
+
* @param serverAccountID The server's stellar account (public key).
|
|
167
|
+
* @param networkPassphrase The network passphrase, e.g.: 'Test SDF
|
|
168
|
+
* Network ; September 2015' (see {@link Networks}).
|
|
169
|
+
* @param threshold The required signatures threshold for verifying
|
|
170
|
+
* this transaction.
|
|
171
|
+
* @param signerSummary a map of all
|
|
172
|
+
* authorized signers to their weights. It's used to validate if the
|
|
173
|
+
* transaction signatures have met the given threshold.
|
|
174
|
+
* @param homeDomains The home domain(s) that should
|
|
175
|
+
* be included in the first Manage Data operation's string key. Required in
|
|
176
|
+
* verifyChallengeTxSigners() => readChallengeTx().
|
|
177
|
+
* @param webAuthDomain The home domain that is expected to be included
|
|
178
|
+
* as the value of the Manage Data operation with the 'web_auth_domain' key,
|
|
179
|
+
* if present. Used in verifyChallengeTxSigners() => readChallengeTx().
|
|
180
|
+
* @returns The list of signers public keys that have signed
|
|
181
|
+
* the transaction, excluding the server account ID, given that the threshold
|
|
182
|
+
* was met.
|
|
183
|
+
* @throws {module:WebAuth.InvalidChallengeError} Will throw if the collective
|
|
184
|
+
* weight of the transaction's signers does not meet the necessary threshold
|
|
185
|
+
* to verify this transaction.
|
|
186
|
+
* @see {@link https://stellar.org/protocol/sep-10 | SEP-10: Stellar Web Auth}
|
|
187
|
+
* @example
|
|
188
|
+
* import { Networks, TransactionBuilder, WebAuth } from 'stellar-sdk';
|
|
189
|
+
*
|
|
190
|
+
* const serverKP = Keypair.random();
|
|
191
|
+
* const clientKP1 = Keypair.random();
|
|
192
|
+
* const clientKP2 = Keypair.random();
|
|
193
|
+
*
|
|
194
|
+
* // Challenge, possibly built in the server side
|
|
195
|
+
* const challenge = WebAuth.buildChallengeTx(
|
|
196
|
+
* serverKP,
|
|
197
|
+
* clientKP1.publicKey(),
|
|
198
|
+
* "SDF",
|
|
199
|
+
* 300,
|
|
200
|
+
* Networks.TESTNET
|
|
201
|
+
* );
|
|
202
|
+
*
|
|
203
|
+
* // clock.tick(200); // Simulates a 200 ms delay when communicating from server to client
|
|
204
|
+
*
|
|
205
|
+
* // Transaction gathered from a challenge, possibly from the client side
|
|
206
|
+
* const transaction = TransactionBuilder.fromXDR(challenge, Networks.TESTNET);
|
|
207
|
+
* transaction.sign(clientKP1, clientKP2);
|
|
208
|
+
* const signedChallenge = transaction
|
|
209
|
+
* .toEnvelope()
|
|
210
|
+
* .toXDR("base64")
|
|
211
|
+
* .toString();
|
|
212
|
+
*
|
|
213
|
+
* // Defining the threshold and signerSummary
|
|
214
|
+
* const threshold = 3;
|
|
215
|
+
* const signerSummary = [
|
|
216
|
+
* {
|
|
217
|
+
* key: this.clientKP1.publicKey(),
|
|
218
|
+
* weight: 1,
|
|
219
|
+
* },
|
|
220
|
+
* {
|
|
221
|
+
* key: this.clientKP2.publicKey(),
|
|
222
|
+
* weight: 2,
|
|
223
|
+
* },
|
|
224
|
+
* ];
|
|
225
|
+
*
|
|
226
|
+
* // The result below should be equal to [clientKP1.publicKey(), clientKP2.publicKey()]
|
|
227
|
+
* WebAuth.verifyChallengeTxThreshold(
|
|
228
|
+
* signedChallenge,
|
|
229
|
+
* serverKP.publicKey(),
|
|
230
|
+
* Networks.TESTNET,
|
|
231
|
+
* threshold,
|
|
232
|
+
* signerSummary
|
|
233
|
+
* );
|
|
234
|
+
*/
|
|
235
|
+
export declare function verifyChallengeTxThreshold(challengeTx: string, serverAccountID: string, networkPassphrase: string, threshold: number, signerSummary: ServerApi.AccountRecordSigners[], homeDomains: string | string[], webAuthDomain: string): string[];
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.buildChallengeTx = buildChallengeTx;
|
|
7
|
+
exports.readChallengeTx = readChallengeTx;
|
|
8
|
+
exports.verifyChallengeTxSigners = verifyChallengeTxSigners;
|
|
9
|
+
exports.verifyChallengeTxThreshold = verifyChallengeTxThreshold;
|
|
10
|
+
var _stellarBase = require("@stellar/stellar-base");
|
|
11
|
+
var _randombytes = _interopRequireDefault(require("randombytes"));
|
|
12
|
+
var _errors = require("./errors");
|
|
13
|
+
var _utils = require("./utils");
|
|
14
|
+
var _utils2 = require("../utils");
|
|
15
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
16
|
+
function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
|
|
17
|
+
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
18
|
+
function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
|
|
19
|
+
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
|
|
20
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
21
|
+
function _toArray(r) { return _arrayWithHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableRest(); }
|
|
22
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
23
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
24
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
25
|
+
function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
|
|
26
|
+
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
27
|
+
function buildChallengeTx(serverKeypair, clientAccountID, homeDomain) {
|
|
28
|
+
var timeout = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 300;
|
|
29
|
+
var networkPassphrase = arguments.length > 4 ? arguments[4] : undefined;
|
|
30
|
+
var webAuthDomain = arguments.length > 5 ? arguments[5] : undefined;
|
|
31
|
+
var memo = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : null;
|
|
32
|
+
var clientDomain = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : null;
|
|
33
|
+
var clientSigningKey = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : null;
|
|
34
|
+
if (clientAccountID.startsWith("M") && memo) {
|
|
35
|
+
throw Error("memo cannot be used if clientAccountID is a muxed account");
|
|
36
|
+
}
|
|
37
|
+
var account = new _stellarBase.Account(serverKeypair.publicKey(), "-1");
|
|
38
|
+
var now = Math.floor(Date.now() / 1000);
|
|
39
|
+
var value = (0, _randombytes.default)(48).toString("base64");
|
|
40
|
+
var builder = new _stellarBase.TransactionBuilder(account, {
|
|
41
|
+
fee: _stellarBase.BASE_FEE,
|
|
42
|
+
networkPassphrase: networkPassphrase,
|
|
43
|
+
timebounds: {
|
|
44
|
+
minTime: now,
|
|
45
|
+
maxTime: now + timeout
|
|
46
|
+
}
|
|
47
|
+
}).addOperation(_stellarBase.Operation.manageData({
|
|
48
|
+
name: "".concat(homeDomain, " auth"),
|
|
49
|
+
value: value,
|
|
50
|
+
source: clientAccountID
|
|
51
|
+
})).addOperation(_stellarBase.Operation.manageData({
|
|
52
|
+
name: "web_auth_domain",
|
|
53
|
+
value: webAuthDomain,
|
|
54
|
+
source: account.accountId()
|
|
55
|
+
}));
|
|
56
|
+
if (clientDomain) {
|
|
57
|
+
if (!clientSigningKey) {
|
|
58
|
+
throw Error("clientSigningKey is required if clientDomain is provided");
|
|
59
|
+
}
|
|
60
|
+
builder.addOperation(_stellarBase.Operation.manageData({
|
|
61
|
+
name: "client_domain",
|
|
62
|
+
value: clientDomain,
|
|
63
|
+
source: clientSigningKey
|
|
64
|
+
}));
|
|
65
|
+
}
|
|
66
|
+
if (memo) {
|
|
67
|
+
builder.addMemo(_stellarBase.Memo.id(memo));
|
|
68
|
+
}
|
|
69
|
+
var transaction = builder.build();
|
|
70
|
+
transaction.sign(serverKeypair);
|
|
71
|
+
return transaction.toEnvelope().toXDR("base64").toString();
|
|
72
|
+
}
|
|
73
|
+
function readChallengeTx(challengeTx, serverAccountID, networkPassphrase, homeDomains, webAuthDomain) {
|
|
74
|
+
var _transaction$timeBoun;
|
|
75
|
+
if (serverAccountID.startsWith("M")) {
|
|
76
|
+
throw Error("Invalid serverAccountID: multiplexed accounts are not supported.");
|
|
77
|
+
}
|
|
78
|
+
var transaction;
|
|
79
|
+
try {
|
|
80
|
+
transaction = new _stellarBase.Transaction(challengeTx, networkPassphrase);
|
|
81
|
+
} catch (_unused) {
|
|
82
|
+
try {
|
|
83
|
+
transaction = new _stellarBase.FeeBumpTransaction(challengeTx, networkPassphrase);
|
|
84
|
+
} catch (_unused2) {
|
|
85
|
+
throw new _errors.InvalidChallengeError("Invalid challenge: unable to deserialize challengeTx transaction string");
|
|
86
|
+
}
|
|
87
|
+
throw new _errors.InvalidChallengeError("Invalid challenge: expected a Transaction but received a FeeBumpTransaction");
|
|
88
|
+
}
|
|
89
|
+
var sequence = Number.parseInt(transaction.sequence, 10);
|
|
90
|
+
if (sequence !== 0) {
|
|
91
|
+
throw new _errors.InvalidChallengeError("The transaction sequence number should be zero");
|
|
92
|
+
}
|
|
93
|
+
if (transaction.source !== serverAccountID) {
|
|
94
|
+
throw new _errors.InvalidChallengeError("The transaction source account is not equal to the server's account");
|
|
95
|
+
}
|
|
96
|
+
if (transaction.operations.length < 1) {
|
|
97
|
+
throw new _errors.InvalidChallengeError("The transaction should contain at least one operation");
|
|
98
|
+
}
|
|
99
|
+
var _transaction$operatio = _toArray(transaction.operations),
|
|
100
|
+
operation = _transaction$operatio[0],
|
|
101
|
+
subsequentOperations = _transaction$operatio.slice(1);
|
|
102
|
+
if (!operation.source) {
|
|
103
|
+
throw new _errors.InvalidChallengeError("The transaction's operation should contain a source account");
|
|
104
|
+
}
|
|
105
|
+
var clientAccountID = operation.source;
|
|
106
|
+
var memo = null;
|
|
107
|
+
if (transaction.memo.type !== _stellarBase.MemoNone) {
|
|
108
|
+
if (clientAccountID.startsWith("M")) {
|
|
109
|
+
throw new _errors.InvalidChallengeError("The transaction has a memo but the client account ID is a muxed account");
|
|
110
|
+
}
|
|
111
|
+
if (transaction.memo.type !== _stellarBase.MemoID) {
|
|
112
|
+
throw new _errors.InvalidChallengeError("The transaction's memo must be of type `id`");
|
|
113
|
+
}
|
|
114
|
+
memo = transaction.memo.value;
|
|
115
|
+
}
|
|
116
|
+
if (operation.type !== "manageData") {
|
|
117
|
+
throw new _errors.InvalidChallengeError("The transaction's operation type should be 'manageData'");
|
|
118
|
+
}
|
|
119
|
+
if (transaction.timeBounds && Number.parseInt((_transaction$timeBoun = transaction.timeBounds) === null || _transaction$timeBoun === void 0 ? void 0 : _transaction$timeBoun.maxTime, 10) === _stellarBase.TimeoutInfinite) {
|
|
120
|
+
throw new _errors.InvalidChallengeError("The transaction requires non-infinite timebounds");
|
|
121
|
+
}
|
|
122
|
+
if (!_utils2.Utils.validateTimebounds(transaction, 60 * 5)) {
|
|
123
|
+
throw new _errors.InvalidChallengeError("The transaction has expired");
|
|
124
|
+
}
|
|
125
|
+
if (operation.value === undefined) {
|
|
126
|
+
throw new _errors.InvalidChallengeError("The transaction's operation values should not be null");
|
|
127
|
+
}
|
|
128
|
+
if (!operation.value) {
|
|
129
|
+
throw new _errors.InvalidChallengeError("The transaction's operation value should not be null");
|
|
130
|
+
}
|
|
131
|
+
if (Buffer.from(operation.value.toString(), "base64").length !== 48) {
|
|
132
|
+
throw new _errors.InvalidChallengeError("The transaction's operation value should be a 64 bytes base64 random string");
|
|
133
|
+
}
|
|
134
|
+
if (!homeDomains) {
|
|
135
|
+
throw new _errors.InvalidChallengeError("Invalid homeDomains: a home domain must be provided for verification");
|
|
136
|
+
}
|
|
137
|
+
var matchedHomeDomain;
|
|
138
|
+
if (typeof homeDomains === "string") {
|
|
139
|
+
if ("".concat(homeDomains, " auth") === operation.name) {
|
|
140
|
+
matchedHomeDomain = homeDomains;
|
|
141
|
+
}
|
|
142
|
+
} else if (Array.isArray(homeDomains)) {
|
|
143
|
+
matchedHomeDomain = homeDomains.find(function (domain) {
|
|
144
|
+
return "".concat(domain, " auth") === operation.name;
|
|
145
|
+
});
|
|
146
|
+
} else {
|
|
147
|
+
throw new _errors.InvalidChallengeError("Invalid homeDomains: homeDomains type is ".concat(_typeof(homeDomains), " but should be a string or an array"));
|
|
148
|
+
}
|
|
149
|
+
if (!matchedHomeDomain) {
|
|
150
|
+
throw new _errors.InvalidChallengeError("Invalid homeDomains: the transaction's operation key name does not match the expected home domain");
|
|
151
|
+
}
|
|
152
|
+
var _iterator = _createForOfIteratorHelper(subsequentOperations),
|
|
153
|
+
_step;
|
|
154
|
+
try {
|
|
155
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
156
|
+
var op = _step.value;
|
|
157
|
+
if (op.type !== "manageData") {
|
|
158
|
+
throw new _errors.InvalidChallengeError("The transaction has operations that are not of type 'manageData'");
|
|
159
|
+
}
|
|
160
|
+
if (op.source !== serverAccountID && op.name !== "client_domain") {
|
|
161
|
+
throw new _errors.InvalidChallengeError("The transaction has operations that are unrecognized");
|
|
162
|
+
}
|
|
163
|
+
if (op.name === "web_auth_domain") {
|
|
164
|
+
if (op.value === undefined) {
|
|
165
|
+
throw new _errors.InvalidChallengeError("'web_auth_domain' operation value should not be null");
|
|
166
|
+
}
|
|
167
|
+
if (op.value.compare(Buffer.from(webAuthDomain))) {
|
|
168
|
+
throw new _errors.InvalidChallengeError("'web_auth_domain' operation value does not match ".concat(webAuthDomain));
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
} catch (err) {
|
|
173
|
+
_iterator.e(err);
|
|
174
|
+
} finally {
|
|
175
|
+
_iterator.f();
|
|
176
|
+
}
|
|
177
|
+
if (!(0, _utils.verifyTxSignedBy)(transaction, serverAccountID)) {
|
|
178
|
+
throw new _errors.InvalidChallengeError("Transaction not signed by server: '".concat(serverAccountID, "'"));
|
|
179
|
+
}
|
|
180
|
+
return {
|
|
181
|
+
tx: transaction,
|
|
182
|
+
clientAccountID: clientAccountID,
|
|
183
|
+
matchedHomeDomain: matchedHomeDomain,
|
|
184
|
+
memo: memo
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
function verifyChallengeTxSigners(challengeTx, serverAccountID, networkPassphrase, signers, homeDomains, webAuthDomain) {
|
|
188
|
+
var _readChallengeTx = readChallengeTx(challengeTx, serverAccountID, networkPassphrase, homeDomains, webAuthDomain),
|
|
189
|
+
tx = _readChallengeTx.tx;
|
|
190
|
+
var serverKP;
|
|
191
|
+
try {
|
|
192
|
+
serverKP = _stellarBase.Keypair.fromPublicKey(serverAccountID);
|
|
193
|
+
} catch (err) {
|
|
194
|
+
throw new Error("Couldn't infer keypair from the provided 'serverAccountID': ".concat(err.message));
|
|
195
|
+
}
|
|
196
|
+
var clientSigners = new Set();
|
|
197
|
+
var _iterator2 = _createForOfIteratorHelper(signers),
|
|
198
|
+
_step2;
|
|
199
|
+
try {
|
|
200
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
201
|
+
var signer = _step2.value;
|
|
202
|
+
if (signer === serverKP.publicKey()) {
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
if (signer.charAt(0) !== "G") {
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
clientSigners.add(signer);
|
|
209
|
+
}
|
|
210
|
+
} catch (err) {
|
|
211
|
+
_iterator2.e(err);
|
|
212
|
+
} finally {
|
|
213
|
+
_iterator2.f();
|
|
214
|
+
}
|
|
215
|
+
if (clientSigners.size === 0) {
|
|
216
|
+
throw new _errors.InvalidChallengeError("No verifiable client signers provided, at least one G... address must be provided");
|
|
217
|
+
}
|
|
218
|
+
var clientSigningKey;
|
|
219
|
+
var _iterator3 = _createForOfIteratorHelper(tx.operations),
|
|
220
|
+
_step3;
|
|
221
|
+
try {
|
|
222
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
223
|
+
var op = _step3.value;
|
|
224
|
+
if (op.type === "manageData" && op.name === "client_domain") {
|
|
225
|
+
if (clientSigningKey) {
|
|
226
|
+
throw new _errors.InvalidChallengeError("Found more than one client_domain operation");
|
|
227
|
+
}
|
|
228
|
+
clientSigningKey = op.source;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
} catch (err) {
|
|
232
|
+
_iterator3.e(err);
|
|
233
|
+
} finally {
|
|
234
|
+
_iterator3.f();
|
|
235
|
+
}
|
|
236
|
+
var allSigners = [serverKP.publicKey()].concat(_toConsumableArray(Array.from(clientSigners)));
|
|
237
|
+
if (clientSigningKey) {
|
|
238
|
+
allSigners.push(clientSigningKey);
|
|
239
|
+
}
|
|
240
|
+
var signersFound = (0, _utils.gatherTxSigners)(tx, allSigners);
|
|
241
|
+
var serverSignatureFound = false;
|
|
242
|
+
var clientSigningKeySignatureFound = false;
|
|
243
|
+
var _iterator4 = _createForOfIteratorHelper(signersFound),
|
|
244
|
+
_step4;
|
|
245
|
+
try {
|
|
246
|
+
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
247
|
+
var _signer = _step4.value;
|
|
248
|
+
if (_signer === serverKP.publicKey()) {
|
|
249
|
+
serverSignatureFound = true;
|
|
250
|
+
}
|
|
251
|
+
if (_signer === clientSigningKey) {
|
|
252
|
+
clientSigningKeySignatureFound = true;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
} catch (err) {
|
|
256
|
+
_iterator4.e(err);
|
|
257
|
+
} finally {
|
|
258
|
+
_iterator4.f();
|
|
259
|
+
}
|
|
260
|
+
if (!serverSignatureFound) {
|
|
261
|
+
throw new _errors.InvalidChallengeError("Transaction not signed by server: '".concat(serverKP.publicKey(), "'"));
|
|
262
|
+
}
|
|
263
|
+
if (clientSigningKey && !clientSigningKeySignatureFound) {
|
|
264
|
+
throw new _errors.InvalidChallengeError("Transaction not signed by the source account of the 'client_domain' " + "ManageData operation");
|
|
265
|
+
}
|
|
266
|
+
if (signersFound.length === 1) {
|
|
267
|
+
throw new _errors.InvalidChallengeError("None of the given signers match the transaction signatures");
|
|
268
|
+
}
|
|
269
|
+
if (signersFound.length !== tx.signatures.length) {
|
|
270
|
+
throw new _errors.InvalidChallengeError("Transaction has unrecognized signatures");
|
|
271
|
+
}
|
|
272
|
+
signersFound.splice(signersFound.indexOf(serverKP.publicKey()), 1);
|
|
273
|
+
if (clientSigningKey) {
|
|
274
|
+
signersFound.splice(signersFound.indexOf(clientSigningKey), 1);
|
|
275
|
+
}
|
|
276
|
+
return signersFound;
|
|
277
|
+
}
|
|
278
|
+
function verifyChallengeTxThreshold(challengeTx, serverAccountID, networkPassphrase, threshold, signerSummary, homeDomains, webAuthDomain) {
|
|
279
|
+
var signers = signerSummary.map(function (signer) {
|
|
280
|
+
return signer.key;
|
|
281
|
+
});
|
|
282
|
+
var signersFound = verifyChallengeTxSigners(challengeTx, serverAccountID, networkPassphrase, signers, homeDomains, webAuthDomain);
|
|
283
|
+
var weight = 0;
|
|
284
|
+
var _iterator5 = _createForOfIteratorHelper(signersFound),
|
|
285
|
+
_step5;
|
|
286
|
+
try {
|
|
287
|
+
var _loop = function _loop() {
|
|
288
|
+
var _signerSummary$find;
|
|
289
|
+
var signer = _step5.value;
|
|
290
|
+
var sigWeight = ((_signerSummary$find = signerSummary.find(function (s) {
|
|
291
|
+
return s.key === signer;
|
|
292
|
+
})) === null || _signerSummary$find === void 0 ? void 0 : _signerSummary$find.weight) || 0;
|
|
293
|
+
weight += sigWeight;
|
|
294
|
+
};
|
|
295
|
+
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
|
|
296
|
+
_loop();
|
|
297
|
+
}
|
|
298
|
+
} catch (err) {
|
|
299
|
+
_iterator5.e(err);
|
|
300
|
+
} finally {
|
|
301
|
+
_iterator5.f();
|
|
302
|
+
}
|
|
303
|
+
if (weight < threshold) {
|
|
304
|
+
throw new _errors.InvalidChallengeError("signers with weight ".concat(weight, " do not meet threshold ").concat(threshold, "\""));
|
|
305
|
+
}
|
|
306
|
+
return signersFound;
|
|
307
|
+
}
|
package/lib/webauth/index.d.ts
CHANGED
package/lib/webauth/index.js
CHANGED
|
@@ -24,4 +24,16 @@ Object.keys(_utils).forEach(function (key) {
|
|
|
24
24
|
}
|
|
25
25
|
});
|
|
26
26
|
});
|
|
27
|
-
var _errors = require("./errors");
|
|
27
|
+
var _errors = require("./errors");
|
|
28
|
+
var _challenge_transaction = require("./challenge_transaction");
|
|
29
|
+
Object.keys(_challenge_transaction).forEach(function (key) {
|
|
30
|
+
if (key === "default" || key === "__esModule") return;
|
|
31
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
32
|
+
if (key in exports && exports[key] === _challenge_transaction[key]) return;
|
|
33
|
+
Object.defineProperty(exports, key, {
|
|
34
|
+
enumerable: true,
|
|
35
|
+
get: function get() {
|
|
36
|
+
return _challenge_transaction[key];
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
});
|