@stellar/typescript-wallet-sdk 1.4.0 → 1.5.0
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 +88 -0
- package/README.md +51 -0
- package/examples/sep24/sep24.ts +4 -9
- package/jest.e2e.config.js +9 -0
- package/lib/bundle.js +43625 -43200
- package/lib/bundle.js.map +1 -1
- package/lib/bundle_browser.js +45203 -42345
- package/lib/bundle_browser.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/walletSdk/Anchor/index.d.ts +1 -1
- package/lib/walletSdk/Auth/AuthHeaderSigner.d.ts +61 -0
- package/lib/walletSdk/Auth/index.d.ts +2 -2
- package/lib/walletSdk/Exceptions/index.d.ts +6 -0
- package/lib/walletSdk/Horizon/AccountService.d.ts +1 -1
- package/lib/walletSdk/Horizon/Stellar.d.ts +1 -1
- package/lib/walletSdk/Horizon/Transaction/TransactionBuilder.d.ts +1 -1
- package/lib/walletSdk/Recovery/AccountRecover.d.ts +1 -1
- package/lib/walletSdk/Recovery/index.d.ts +2 -2
- package/lib/walletSdk/Types/auth.d.ts +17 -0
- package/lib/walletSdk/Types/horizon.d.ts +1 -1
- package/lib/walletSdk/Types/index.d.ts +1 -1
- package/lib/walletSdk/Types/recovery.d.ts +2 -2
- package/package.json +6 -1
- package/src/index.ts +5 -0
- package/src/walletSdk/Anchor/index.ts +1 -1
- package/src/walletSdk/Auth/AuthHeaderSigner.ts +162 -0
- package/src/walletSdk/Auth/index.ts +48 -2
- package/src/walletSdk/Exceptions/index.ts +19 -0
- package/src/walletSdk/Horizon/AccountService.ts +1 -1
- package/src/walletSdk/Horizon/Stellar.ts +1 -1
- package/src/walletSdk/Horizon/Transaction/TransactionBuilder.ts +1 -1
- package/src/walletSdk/Recovery/AccountRecover.ts +1 -1
- package/src/walletSdk/Recovery/index.ts +2 -2
- package/src/walletSdk/Types/auth.ts +19 -0
- package/src/walletSdk/Types/horizon.ts +1 -1
- package/src/walletSdk/Types/index.ts +1 -1
- package/src/walletSdk/Types/recovery.ts +2 -2
- package/test/e2e/README.md +11 -0
- package/test/e2e/browser.test.ts +52 -0
- package/test/integration/README.md +38 -0
- package/test/integration/anchorplatform.test.ts +9 -0
- package/test/server.test.ts +13 -0
- package/test/wallet.test.ts +85 -0
- package/webpack.config.js +4 -0
- package/test/README.md +0 -18
package/lib/index.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export { Anchor } from "./walletSdk/Anchor";
|
|
|
11
11
|
export { Sep24 } from "./walletSdk/Anchor/Sep24";
|
|
12
12
|
export { IssuedAssetId, NativeAssetId, FiatAssetId } from "./walletSdk/Asset";
|
|
13
13
|
export { Sep10, WalletSigner, DefaultSigner } from "./walletSdk/Auth";
|
|
14
|
+
export { AuthHeaderSigner, DefaultAuthHeaderSigner, DomainAuthHeaderSigner, } from "./walletSdk/Auth/AuthHeaderSigner";
|
|
14
15
|
export { AccountKeypair, PublicKeypair, SigningKeypair, AccountService, Stellar, CommonTransactionBuilder, TransactionBuilder, SponsoringBuilder, } from "./walletSdk/Horizon";
|
|
15
16
|
export { Recovery } from "./walletSdk/Recovery";
|
|
16
17
|
export { Watcher } from "./walletSdk/Watcher";
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { AxiosInstance } from "axios";
|
|
2
|
+
import { AuthHeaderClaims, AuthHeaderCreateTokenParams } from "../Types";
|
|
3
|
+
export interface AuthHeaderSigner {
|
|
4
|
+
createToken({ claims, clientDomain, issuer, }: AuthHeaderCreateTokenParams): Promise<string>;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Signer for signing JWT for GET /Auth with a custodial private key
|
|
8
|
+
*
|
|
9
|
+
* @class
|
|
10
|
+
*/
|
|
11
|
+
export declare class DefaultAuthHeaderSigner implements AuthHeaderSigner {
|
|
12
|
+
expiration: number;
|
|
13
|
+
constructor(expiration?: number);
|
|
14
|
+
/**
|
|
15
|
+
* Create a signed JWT for the auth header
|
|
16
|
+
* @constructor
|
|
17
|
+
* @param {AuthHeaderCreateTokenParams} params - The create token parameters
|
|
18
|
+
* @param {AuthHeaderClaims} params.claims - the data to be signed in the JWT
|
|
19
|
+
* @param {string} [params.clientDomain] - the client domain hosting SEP-1 toml
|
|
20
|
+
* @param {AccountKeypair} [params.issuer] - the account signing the JWT
|
|
21
|
+
* @returns {Promise<string>} The signed JWT
|
|
22
|
+
*/
|
|
23
|
+
createToken({ claims, clientDomain, issuer, }: AuthHeaderCreateTokenParams): Promise<string>;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Signer for signing JWT for GET /Auth using a remote server to sign.
|
|
27
|
+
*
|
|
28
|
+
* @class
|
|
29
|
+
*/
|
|
30
|
+
export declare class DomainAuthHeaderSigner implements AuthHeaderSigner {
|
|
31
|
+
signerUrl: string;
|
|
32
|
+
expiration: number;
|
|
33
|
+
httpClient: AxiosInstance;
|
|
34
|
+
constructor(signerUrl: string, expiration?: number, httpClient?: AxiosInstance);
|
|
35
|
+
/**
|
|
36
|
+
* Create a signed JWT for the auth header by using a remote server to sign the JWT
|
|
37
|
+
* @constructor
|
|
38
|
+
* @param {AuthHeaderCreateTokenParams} params - The create token parameters
|
|
39
|
+
* @param {AuthHeaderClaims} params.claims - the data to be signed in the JWT
|
|
40
|
+
* @param {string} [params.clientDomain] - the client domain hosting SEP-1 toml
|
|
41
|
+
* @param {AccountKeypair} [params.issuer] - unused, will not be used to sign
|
|
42
|
+
* @returns {Promise<string>} The signed JWT
|
|
43
|
+
*/
|
|
44
|
+
createToken({ claims, clientDomain, issuer, }: AuthHeaderCreateTokenParams): Promise<string>;
|
|
45
|
+
/**
|
|
46
|
+
* Sign JWT by calling a remote server
|
|
47
|
+
* @constructor
|
|
48
|
+
* @param {SignTokenRemoteParams} params - the sign token params
|
|
49
|
+
* @param {AuthHeaderClaims} params.claims - the data to be signed in the JWT
|
|
50
|
+
* @param {string} params.clientDomain - the client domain hosting SEP-1 toml
|
|
51
|
+
* @param {number} params.expiration - when the token should expire
|
|
52
|
+
* @param {number} params.issuedAt - when the token was created
|
|
53
|
+
* @returns {Promise<string>} The signed JWT
|
|
54
|
+
*/
|
|
55
|
+
signTokenRemote({ claims, clientDomain, expiration, issuedAt, }: {
|
|
56
|
+
claims: AuthHeaderClaims;
|
|
57
|
+
clientDomain: string;
|
|
58
|
+
expiration: number;
|
|
59
|
+
issuedAt: number;
|
|
60
|
+
}): Promise<string>;
|
|
61
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AxiosInstance } from "axios";
|
|
2
|
-
import { Config } from "
|
|
2
|
+
import { Config } from "../";
|
|
3
3
|
import { AuthenticateParams, AuthToken } from "../Types";
|
|
4
4
|
export { WalletSigner, DefaultSigner } from "./WalletSigner";
|
|
5
5
|
type Sep10Params = {
|
|
@@ -35,7 +35,7 @@ export declare class Sep10 {
|
|
|
35
35
|
* @param {string} [params.clientDomain] - Domain hosting stellar.toml file containing `SIGNING_KEY`.
|
|
36
36
|
* @returns {Promise<AuthToken>} The authentication token.
|
|
37
37
|
*/
|
|
38
|
-
authenticate({ accountKp, walletSigner, memoId, clientDomain, }: AuthenticateParams): Promise<AuthToken>;
|
|
38
|
+
authenticate({ accountKp, walletSigner, memoId, clientDomain, authHeaderSigner, }: AuthenticateParams): Promise<AuthToken>;
|
|
39
39
|
private challenge;
|
|
40
40
|
private sign;
|
|
41
41
|
private getToken;
|
|
@@ -115,3 +115,9 @@ export declare class UnknownAnchorTransactionError extends Error {
|
|
|
115
115
|
export declare class InvalidJsonError extends Error {
|
|
116
116
|
constructor();
|
|
117
117
|
}
|
|
118
|
+
export declare class AuthHeaderSigningKeypairRequiredError extends Error {
|
|
119
|
+
constructor();
|
|
120
|
+
}
|
|
121
|
+
export declare class AuthHeaderClientDomainRequiredError extends Error {
|
|
122
|
+
constructor();
|
|
123
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Horizon, Transaction, FeeBumpTransaction } from "@stellar/stellar-sdk";
|
|
2
|
-
import { Config } from "
|
|
2
|
+
import { Config } from "../";
|
|
3
3
|
import { AccountService } from "./AccountService";
|
|
4
4
|
import { TransactionBuilder } from "./Transaction/TransactionBuilder";
|
|
5
5
|
import { TransactionParams, SubmitWithFeeIncreaseParams, FeeBumpTransactionParams } from "../Types";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Account as StellarAccount, Transaction, Horizon, Memo, xdr } from "@stellar/stellar-sdk";
|
|
2
|
-
import { Config } from "
|
|
2
|
+
import { Config } from "../../";
|
|
3
3
|
import { AccountKeypair } from "../Account";
|
|
4
4
|
import { StellarAssetId } from "../../Asset";
|
|
5
5
|
import { WithdrawTransaction, PathPayParams } from "../../Types";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AxiosInstance } from "axios";
|
|
2
2
|
import { Transaction } from "@stellar/stellar-sdk";
|
|
3
|
-
import { RecoveryServer, RecoveryServerKey, RecoveryServerMap, RecoveryServerSigningMap } from "
|
|
3
|
+
import { RecoveryServer, RecoveryServerKey, RecoveryServerMap, RecoveryServerSigningMap } from "../Types";
|
|
4
4
|
import { AccountKeypair, Stellar } from "../Horizon";
|
|
5
5
|
/**
|
|
6
6
|
* Used for Account Recovery using Sep-30.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AxiosInstance } from "axios";
|
|
2
2
|
import { Transaction } from "@stellar/stellar-sdk";
|
|
3
|
-
import { Config } from "
|
|
4
|
-
import { AccountSigner, AccountThreshold, CommonBuilder, RecoverableWallet, RecoverableWalletConfig, RecoveryAccountInfoMap, RecoveryAuthMap, RecoveryServerKey, RecoveryServerMap } from "
|
|
3
|
+
import { Config } from "../";
|
|
4
|
+
import { AccountSigner, AccountThreshold, CommonBuilder, RecoverableWallet, RecoverableWalletConfig, RecoveryAccountInfoMap, RecoveryAuthMap, RecoveryServerKey, RecoveryServerMap } from "../Types";
|
|
5
5
|
import { AccountRecover } from "./AccountRecover";
|
|
6
6
|
import { Sep10 } from "../Auth";
|
|
7
7
|
import { AccountKeypair, Stellar } from "../Horizon";
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { Transaction } from "@stellar/stellar-sdk";
|
|
2
2
|
import { WalletSigner } from "../Auth/WalletSigner";
|
|
3
3
|
import { AccountKeypair, SigningKeypair } from "../Horizon/Account";
|
|
4
|
+
import { AuthHeaderSigner } from "../Auth/AuthHeaderSigner";
|
|
4
5
|
export type AuthenticateParams = {
|
|
5
6
|
accountKp: AccountKeypair;
|
|
6
7
|
walletSigner?: WalletSigner;
|
|
7
8
|
memoId?: string;
|
|
8
9
|
clientDomain?: string;
|
|
10
|
+
authHeaderSigner?: AuthHeaderSigner;
|
|
9
11
|
};
|
|
10
12
|
export declare class AuthToken {
|
|
11
13
|
token: string;
|
|
@@ -22,6 +24,7 @@ export type ChallengeParams = {
|
|
|
22
24
|
accountKp: AccountKeypair;
|
|
23
25
|
memoId?: string;
|
|
24
26
|
clientDomain?: string;
|
|
27
|
+
authHeaderSigner?: AuthHeaderSigner;
|
|
25
28
|
};
|
|
26
29
|
export type XdrEncodedTransaction = string;
|
|
27
30
|
export type NetworkPassphrase = string;
|
|
@@ -56,3 +59,17 @@ export type SignChallengeTxnResponse = {
|
|
|
56
59
|
transaction: XdrEncodedTransaction;
|
|
57
60
|
networkPassphrase: NetworkPassphrase;
|
|
58
61
|
};
|
|
62
|
+
export type AuthHeaderClaims = {
|
|
63
|
+
account: string;
|
|
64
|
+
home_domain: string;
|
|
65
|
+
web_auth_endpoint: string;
|
|
66
|
+
memo?: string;
|
|
67
|
+
client_domain?: string;
|
|
68
|
+
exp?: number;
|
|
69
|
+
iat?: number;
|
|
70
|
+
};
|
|
71
|
+
export type AuthHeaderCreateTokenParams = {
|
|
72
|
+
claims: AuthHeaderClaims;
|
|
73
|
+
clientDomain?: string;
|
|
74
|
+
issuer?: AccountKeypair;
|
|
75
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Memo, Horizon, Transaction } from "@stellar/stellar-sdk";
|
|
2
2
|
import { AccountKeypair } from "../Horizon/Account";
|
|
3
|
-
import { SponsoringBuilder, TransactionBuilder } from "
|
|
3
|
+
import { SponsoringBuilder, TransactionBuilder } from "../Horizon";
|
|
4
4
|
import { StellarAssetId } from "../Asset";
|
|
5
5
|
export declare enum NETWORK_URLS {
|
|
6
6
|
PUBLIC = "https://horizon.stellar.org",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { RawAxiosRequestHeaders } from "axios";
|
|
2
2
|
import { Networks } from "@stellar/stellar-sdk";
|
|
3
|
-
import { ApplicationConfiguration, StellarConfiguration } from "
|
|
3
|
+
import { ApplicationConfiguration, StellarConfiguration } from "../";
|
|
4
4
|
import { RecoveryServerMap } from "./recovery";
|
|
5
5
|
export type WalletParams = {
|
|
6
6
|
stellarConfiguration: StellarConfiguration;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Transaction } from "@stellar/stellar-sdk";
|
|
2
|
-
import { WalletSigner } from "
|
|
3
|
-
import { AccountKeypair, PublicKeypair } from "
|
|
2
|
+
import { WalletSigner } from "../Auth";
|
|
3
|
+
import { AccountKeypair, PublicKeypair } from "../Horizon";
|
|
4
4
|
import { AuthToken } from "./auth";
|
|
5
5
|
import { CommonBuilder } from "./horizon";
|
|
6
6
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stellar/typescript-wallet-sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"engines": {
|
|
5
5
|
"node": ">=18"
|
|
6
6
|
},
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
"jest": "^29.4.1",
|
|
30
30
|
"lint-staged": "^14.0.1",
|
|
31
31
|
"npm-run-all": "^4.1.5",
|
|
32
|
+
"playwright": "^1.43.1",
|
|
32
33
|
"prettier": "^2.0.5",
|
|
33
34
|
"pretty-quick": "^2.0.1",
|
|
34
35
|
"process": "^0.11.10",
|
|
@@ -45,11 +46,14 @@
|
|
|
45
46
|
"dependencies": {
|
|
46
47
|
"@stellar/stellar-sdk": "^11.1.0",
|
|
47
48
|
"axios": "^1.4.0",
|
|
49
|
+
"base64url": "^3.0.1",
|
|
48
50
|
"https-browserify": "^1.0.0",
|
|
49
51
|
"jws": "^4.0.0",
|
|
50
52
|
"lodash": "^4.17.21",
|
|
51
53
|
"query-string": "^7.1.3",
|
|
52
54
|
"stream-http": "^3.2.0",
|
|
55
|
+
"tweetnacl": "^1.0.3",
|
|
56
|
+
"tweetnacl-util": "^0.15.1",
|
|
53
57
|
"url": "^0.11.0",
|
|
54
58
|
"util": "^0.12.5",
|
|
55
59
|
"utility-types": "^3.10.0",
|
|
@@ -58,6 +62,7 @@
|
|
|
58
62
|
"scripts": {
|
|
59
63
|
"test": "jest --watchAll",
|
|
60
64
|
"test:ci": "jest --ci",
|
|
65
|
+
"test:e2e:ci": "jest --config jest.e2e.config.js --ci",
|
|
61
66
|
"test:recovery:ci": "jest --config jest.integration.config.js recovery.test.ts --ci",
|
|
62
67
|
"test:anchorplatform:ci": "yarn jest --config jest.integration.config.js anchorplatform.test.ts --ci",
|
|
63
68
|
"build:web": "webpack --config webpack.config.js",
|
package/src/index.ts
CHANGED
|
@@ -17,6 +17,11 @@ export { Anchor } from "./walletSdk/Anchor";
|
|
|
17
17
|
export { Sep24 } from "./walletSdk/Anchor/Sep24";
|
|
18
18
|
export { IssuedAssetId, NativeAssetId, FiatAssetId } from "./walletSdk/Asset";
|
|
19
19
|
export { Sep10, WalletSigner, DefaultSigner } from "./walletSdk/Auth";
|
|
20
|
+
export {
|
|
21
|
+
AuthHeaderSigner,
|
|
22
|
+
DefaultAuthHeaderSigner,
|
|
23
|
+
DomainAuthHeaderSigner,
|
|
24
|
+
} from "./walletSdk/Auth/AuthHeaderSigner";
|
|
20
25
|
export {
|
|
21
26
|
AccountKeypair,
|
|
22
27
|
PublicKeypair,
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { AxiosInstance } from "axios";
|
|
2
|
+
import { StrKey } from "@stellar/stellar-sdk";
|
|
3
|
+
import nacl from "tweetnacl";
|
|
4
|
+
import naclUtil from "tweetnacl-util";
|
|
5
|
+
import base64url from "base64url";
|
|
6
|
+
|
|
7
|
+
import { SigningKeypair } from "../Horizon/Account";
|
|
8
|
+
import { DefaultClient } from "../";
|
|
9
|
+
import { AuthHeaderClaims, AuthHeaderCreateTokenParams } from "../Types";
|
|
10
|
+
import {
|
|
11
|
+
AuthHeaderSigningKeypairRequiredError,
|
|
12
|
+
AuthHeaderClientDomainRequiredError,
|
|
13
|
+
} from "../Exceptions";
|
|
14
|
+
|
|
15
|
+
export interface AuthHeaderSigner {
|
|
16
|
+
createToken({
|
|
17
|
+
claims,
|
|
18
|
+
clientDomain,
|
|
19
|
+
issuer,
|
|
20
|
+
}: AuthHeaderCreateTokenParams): Promise<string>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Signer for signing JWT for GET /Auth with a custodial private key
|
|
25
|
+
*
|
|
26
|
+
* @class
|
|
27
|
+
*/
|
|
28
|
+
export class DefaultAuthHeaderSigner implements AuthHeaderSigner {
|
|
29
|
+
expiration: number;
|
|
30
|
+
|
|
31
|
+
constructor(expiration: number = 900) {
|
|
32
|
+
this.expiration = expiration;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Create a signed JWT for the auth header
|
|
37
|
+
* @constructor
|
|
38
|
+
* @param {AuthHeaderCreateTokenParams} params - The create token parameters
|
|
39
|
+
* @param {AuthHeaderClaims} params.claims - the data to be signed in the JWT
|
|
40
|
+
* @param {string} [params.clientDomain] - the client domain hosting SEP-1 toml
|
|
41
|
+
* @param {AccountKeypair} [params.issuer] - the account signing the JWT
|
|
42
|
+
* @returns {Promise<string>} The signed JWT
|
|
43
|
+
*/
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
45
|
+
async createToken({
|
|
46
|
+
claims,
|
|
47
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
48
|
+
clientDomain,
|
|
49
|
+
issuer,
|
|
50
|
+
}: AuthHeaderCreateTokenParams): Promise<string> {
|
|
51
|
+
if (!(issuer instanceof SigningKeypair)) {
|
|
52
|
+
throw new AuthHeaderSigningKeypairRequiredError();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const issuedAt = claims.iat || Math.floor(Date.now() / 1000);
|
|
56
|
+
const timeExp =
|
|
57
|
+
claims.exp || Math.floor(Date.now() / 1000) + this.expiration;
|
|
58
|
+
|
|
59
|
+
// turn stellar kp into nacl kp for creating JWT
|
|
60
|
+
const rawSeed = StrKey.decodeEd25519SecretSeed(issuer.secretKey);
|
|
61
|
+
const naclKP = nacl.sign.keyPair.fromSeed(rawSeed);
|
|
62
|
+
|
|
63
|
+
// encode JWT message
|
|
64
|
+
const header = { alg: "EdDSA" };
|
|
65
|
+
const encodedHeader = base64url(JSON.stringify(header));
|
|
66
|
+
const encodedPayload = base64url(
|
|
67
|
+
JSON.stringify({ ...claims, exp: timeExp, iat: issuedAt }),
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
// sign JWT and create signature
|
|
71
|
+
const signature = nacl.sign.detached(
|
|
72
|
+
naclUtil.decodeUTF8(`${encodedHeader}.${encodedPayload}`),
|
|
73
|
+
naclKP.secretKey,
|
|
74
|
+
);
|
|
75
|
+
const encodedSignature = base64url(Buffer.from(signature));
|
|
76
|
+
|
|
77
|
+
const jwt = `${encodedHeader}.${encodedPayload}.${encodedSignature}`;
|
|
78
|
+
return jwt;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Signer for signing JWT for GET /Auth using a remote server to sign.
|
|
84
|
+
*
|
|
85
|
+
* @class
|
|
86
|
+
*/
|
|
87
|
+
export class DomainAuthHeaderSigner implements AuthHeaderSigner {
|
|
88
|
+
signerUrl: string;
|
|
89
|
+
expiration: number;
|
|
90
|
+
httpClient: AxiosInstance;
|
|
91
|
+
|
|
92
|
+
constructor(
|
|
93
|
+
signerUrl: string,
|
|
94
|
+
expiration: number = 900,
|
|
95
|
+
httpClient?: AxiosInstance,
|
|
96
|
+
) {
|
|
97
|
+
this.signerUrl = signerUrl;
|
|
98
|
+
this.expiration = expiration;
|
|
99
|
+
this.httpClient = httpClient || DefaultClient;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Create a signed JWT for the auth header by using a remote server to sign the JWT
|
|
104
|
+
* @constructor
|
|
105
|
+
* @param {AuthHeaderCreateTokenParams} params - The create token parameters
|
|
106
|
+
* @param {AuthHeaderClaims} params.claims - the data to be signed in the JWT
|
|
107
|
+
* @param {string} [params.clientDomain] - the client domain hosting SEP-1 toml
|
|
108
|
+
* @param {AccountKeypair} [params.issuer] - unused, will not be used to sign
|
|
109
|
+
* @returns {Promise<string>} The signed JWT
|
|
110
|
+
*/
|
|
111
|
+
async createToken({
|
|
112
|
+
claims,
|
|
113
|
+
clientDomain,
|
|
114
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
115
|
+
issuer,
|
|
116
|
+
}: AuthHeaderCreateTokenParams): Promise<string> {
|
|
117
|
+
if (!clientDomain) {
|
|
118
|
+
throw new AuthHeaderClientDomainRequiredError();
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const issuedAt = Math.floor(Date.now() / 1000);
|
|
122
|
+
const expiration = Math.floor(Date.now() / 1000) + this.expiration;
|
|
123
|
+
|
|
124
|
+
return await this.signTokenRemote({
|
|
125
|
+
claims,
|
|
126
|
+
clientDomain,
|
|
127
|
+
expiration,
|
|
128
|
+
issuedAt,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Sign JWT by calling a remote server
|
|
134
|
+
* @constructor
|
|
135
|
+
* @param {SignTokenRemoteParams} params - the sign token params
|
|
136
|
+
* @param {AuthHeaderClaims} params.claims - the data to be signed in the JWT
|
|
137
|
+
* @param {string} params.clientDomain - the client domain hosting SEP-1 toml
|
|
138
|
+
* @param {number} params.expiration - when the token should expire
|
|
139
|
+
* @param {number} params.issuedAt - when the token was created
|
|
140
|
+
* @returns {Promise<string>} The signed JWT
|
|
141
|
+
*/
|
|
142
|
+
async signTokenRemote({
|
|
143
|
+
claims,
|
|
144
|
+
clientDomain,
|
|
145
|
+
expiration,
|
|
146
|
+
issuedAt,
|
|
147
|
+
}: {
|
|
148
|
+
claims: AuthHeaderClaims;
|
|
149
|
+
clientDomain: string;
|
|
150
|
+
expiration: number;
|
|
151
|
+
issuedAt: number;
|
|
152
|
+
}): Promise<string> {
|
|
153
|
+
const resp = await this.httpClient.post(this.signerUrl, {
|
|
154
|
+
clientDomain,
|
|
155
|
+
expiration,
|
|
156
|
+
issuedAt,
|
|
157
|
+
...claims,
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
return resp.data.token;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
@@ -2,7 +2,7 @@ import { AxiosInstance } from "axios";
|
|
|
2
2
|
import { TransactionBuilder, Transaction } from "@stellar/stellar-sdk";
|
|
3
3
|
import { decode } from "jws";
|
|
4
4
|
|
|
5
|
-
import { Config } from "
|
|
5
|
+
import { Config } from "../";
|
|
6
6
|
import {
|
|
7
7
|
InvalidMemoError,
|
|
8
8
|
ClientDomainWithMemoError,
|
|
@@ -17,7 +17,10 @@ import {
|
|
|
17
17
|
ChallengeParams,
|
|
18
18
|
ChallengeResponse,
|
|
19
19
|
SignParams,
|
|
20
|
+
AuthHeaderClaims,
|
|
20
21
|
} from "../Types";
|
|
22
|
+
import { AccountKeypair } from "../Horizon/Account";
|
|
23
|
+
import { AuthHeaderSigner } from "./AuthHeaderSigner";
|
|
21
24
|
|
|
22
25
|
export { WalletSigner, DefaultSigner } from "./WalletSigner";
|
|
23
26
|
|
|
@@ -71,11 +74,13 @@ export class Sep10 {
|
|
|
71
74
|
walletSigner,
|
|
72
75
|
memoId,
|
|
73
76
|
clientDomain,
|
|
77
|
+
authHeaderSigner,
|
|
74
78
|
}: AuthenticateParams): Promise<AuthToken> {
|
|
75
79
|
const challengeResponse = await this.challenge({
|
|
76
80
|
accountKp,
|
|
77
81
|
memoId,
|
|
78
82
|
clientDomain: clientDomain || this.cfg.app.defaultClientDomain,
|
|
83
|
+
authHeaderSigner,
|
|
79
84
|
});
|
|
80
85
|
const signedTransaction = await this.sign({
|
|
81
86
|
accountKp,
|
|
@@ -90,6 +95,7 @@ export class Sep10 {
|
|
|
90
95
|
accountKp,
|
|
91
96
|
memoId,
|
|
92
97
|
clientDomain,
|
|
98
|
+
authHeaderSigner,
|
|
93
99
|
}: ChallengeParams): Promise<ChallengeResponse> {
|
|
94
100
|
if (memoId && parseInt(memoId) < 0) {
|
|
95
101
|
throw new InvalidMemoError();
|
|
@@ -104,8 +110,29 @@ export class Sep10 {
|
|
|
104
110
|
}${clientDomain ? `&client_domain=${clientDomain}` : ""}${
|
|
105
111
|
this.homeDomain ? `&home_domain=${this.homeDomain}` : ""
|
|
106
112
|
}`;
|
|
113
|
+
|
|
114
|
+
const claims = {
|
|
115
|
+
account: accountKp.publicKey,
|
|
116
|
+
home_domain: this.homeDomain,
|
|
117
|
+
memo: memoId,
|
|
118
|
+
client_domain: clientDomain,
|
|
119
|
+
web_auth_endpoint: this.webAuthEndpoint,
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
const token = await createAuthSignToken(
|
|
123
|
+
accountKp,
|
|
124
|
+
claims,
|
|
125
|
+
clientDomain,
|
|
126
|
+
authHeaderSigner,
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
let headers = {};
|
|
130
|
+
if (token) {
|
|
131
|
+
headers = { Authorization: `Bearer ${token}` };
|
|
132
|
+
}
|
|
133
|
+
|
|
107
134
|
try {
|
|
108
|
-
const resp = await this.httpClient.get(url);
|
|
135
|
+
const resp = await this.httpClient.get(url, { headers });
|
|
109
136
|
const challengeResponse: ChallengeResponse = resp.data;
|
|
110
137
|
return challengeResponse;
|
|
111
138
|
} catch (e) {
|
|
@@ -165,3 +192,22 @@ const validateToken = (token: string) => {
|
|
|
165
192
|
throw new ExpiredTokenError(parsedToken.expiresAt);
|
|
166
193
|
}
|
|
167
194
|
};
|
|
195
|
+
|
|
196
|
+
const createAuthSignToken = async (
|
|
197
|
+
account: AccountKeypair,
|
|
198
|
+
claims: AuthHeaderClaims,
|
|
199
|
+
clientDomain?: string,
|
|
200
|
+
authHeaderSigner?: AuthHeaderSigner,
|
|
201
|
+
) => {
|
|
202
|
+
if (!authHeaderSigner) {
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const issuer = clientDomain ? null : account;
|
|
207
|
+
|
|
208
|
+
return authHeaderSigner.createToken({
|
|
209
|
+
claims,
|
|
210
|
+
clientDomain,
|
|
211
|
+
issuer,
|
|
212
|
+
});
|
|
213
|
+
};
|
|
@@ -305,3 +305,22 @@ export class InvalidJsonError extends Error {
|
|
|
305
305
|
Object.setPrototypeOf(this, InvalidJsonError.prototype);
|
|
306
306
|
}
|
|
307
307
|
}
|
|
308
|
+
|
|
309
|
+
export class AuthHeaderSigningKeypairRequiredError extends Error {
|
|
310
|
+
constructor() {
|
|
311
|
+
super("Must be SigningKeypair to sign auth header");
|
|
312
|
+
Object.setPrototypeOf(
|
|
313
|
+
this,
|
|
314
|
+
AuthHeaderSigningKeypairRequiredError.prototype,
|
|
315
|
+
);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
export class AuthHeaderClientDomainRequiredError extends Error {
|
|
320
|
+
constructor() {
|
|
321
|
+
super(
|
|
322
|
+
"This class should only be used for remote signing. For local signing use DefaultAuthHeaderSigner.",
|
|
323
|
+
);
|
|
324
|
+
Object.setPrototypeOf(this, AuthHeaderClientDomainRequiredError.prototype);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from "@stellar/stellar-sdk";
|
|
8
8
|
import axios from "axios";
|
|
9
9
|
|
|
10
|
-
import { Config } from "
|
|
10
|
+
import { Config } from "../";
|
|
11
11
|
import { AccountService } from "./AccountService";
|
|
12
12
|
import { TransactionBuilder } from "./Transaction/TransactionBuilder";
|
|
13
13
|
import {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AxiosInstance } from "axios";
|
|
2
2
|
import { Transaction } from "@stellar/stellar-sdk";
|
|
3
3
|
|
|
4
|
-
import { Config } from "
|
|
4
|
+
import { Config } from "../";
|
|
5
5
|
import {
|
|
6
6
|
AccountSigner,
|
|
7
7
|
AccountThreshold,
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
RecoveryIdentityMap,
|
|
17
17
|
RecoveryServerKey,
|
|
18
18
|
RecoveryServerMap,
|
|
19
|
-
} from "
|
|
19
|
+
} from "../Types";
|
|
20
20
|
import { AccountRecover } from "./AccountRecover";
|
|
21
21
|
import { Sep10 } from "../Auth";
|
|
22
22
|
import {
|
|
@@ -3,12 +3,14 @@ import { decode } from "jws";
|
|
|
3
3
|
|
|
4
4
|
import { WalletSigner } from "../Auth/WalletSigner";
|
|
5
5
|
import { AccountKeypair, SigningKeypair } from "../Horizon/Account";
|
|
6
|
+
import { AuthHeaderSigner } from "../Auth/AuthHeaderSigner";
|
|
6
7
|
|
|
7
8
|
export type AuthenticateParams = {
|
|
8
9
|
accountKp: AccountKeypair;
|
|
9
10
|
walletSigner?: WalletSigner;
|
|
10
11
|
memoId?: string;
|
|
11
12
|
clientDomain?: string;
|
|
13
|
+
authHeaderSigner?: AuthHeaderSigner;
|
|
12
14
|
};
|
|
13
15
|
|
|
14
16
|
export class AuthToken {
|
|
@@ -49,6 +51,7 @@ export type ChallengeParams = {
|
|
|
49
51
|
accountKp: AccountKeypair;
|
|
50
52
|
memoId?: string;
|
|
51
53
|
clientDomain?: string;
|
|
54
|
+
authHeaderSigner?: AuthHeaderSigner;
|
|
52
55
|
};
|
|
53
56
|
|
|
54
57
|
export type XdrEncodedTransaction = string;
|
|
@@ -91,3 +94,19 @@ export type SignChallengeTxnResponse = {
|
|
|
91
94
|
transaction: XdrEncodedTransaction;
|
|
92
95
|
networkPassphrase: NetworkPassphrase;
|
|
93
96
|
};
|
|
97
|
+
|
|
98
|
+
export type AuthHeaderClaims = {
|
|
99
|
+
account: string;
|
|
100
|
+
home_domain: string;
|
|
101
|
+
web_auth_endpoint: string;
|
|
102
|
+
memo?: string;
|
|
103
|
+
client_domain?: string;
|
|
104
|
+
exp?: number;
|
|
105
|
+
iat?: number;
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
export type AuthHeaderCreateTokenParams = {
|
|
109
|
+
claims: AuthHeaderClaims;
|
|
110
|
+
clientDomain?: string;
|
|
111
|
+
issuer?: AccountKeypair;
|
|
112
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Memo, Horizon, Transaction } from "@stellar/stellar-sdk";
|
|
2
2
|
import { AccountKeypair } from "../Horizon/Account";
|
|
3
|
-
import { SponsoringBuilder, TransactionBuilder } from "
|
|
3
|
+
import { SponsoringBuilder, TransactionBuilder } from "../Horizon";
|
|
4
4
|
import { StellarAssetId } from "../Asset";
|
|
5
5
|
|
|
6
6
|
export enum NETWORK_URLS {
|