@reown/appkit-core-react-native 2.0.0-alpha.5 → 2.0.0-alpha.6
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/lib/commonjs/controllers/ConnectionsController.js +3 -3
- package/lib/commonjs/controllers/ConnectionsController.js.map +1 -1
- package/lib/commonjs/controllers/OptionsController.js +6 -3
- package/lib/commonjs/controllers/OptionsController.js.map +1 -1
- package/lib/commonjs/controllers/SendController.js +15 -1
- package/lib/commonjs/controllers/SendController.js.map +1 -1
- package/lib/commonjs/features/reown-authentication/ReownAuthentication.js +264 -0
- package/lib/commonjs/features/reown-authentication/ReownAuthentication.js.map +1 -0
- package/lib/commonjs/features/reown-authentication/ReownAuthenticationMessenger.js +48 -0
- package/lib/commonjs/features/reown-authentication/ReownAuthenticationMessenger.js.map +1 -0
- package/lib/commonjs/features/reown-authentication/index.js +28 -0
- package/lib/commonjs/features/reown-authentication/index.js.map +1 -0
- package/lib/commonjs/index.js +14 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/utils/CoreHelperUtil.js +13 -2
- package/lib/commonjs/utils/CoreHelperUtil.js.map +1 -1
- package/lib/commonjs/utils/FetchUtil.js.map +1 -1
- package/lib/commonjs/utils/StorageUtil.js +27 -27
- package/lib/commonjs/utils/StorageUtil.js.map +1 -1
- package/lib/module/controllers/ConnectionsController.js +4 -4
- package/lib/module/controllers/ConnectionsController.js.map +1 -1
- package/lib/module/controllers/OptionsController.js +6 -3
- package/lib/module/controllers/OptionsController.js.map +1 -1
- package/lib/module/controllers/SendController.js +15 -1
- package/lib/module/controllers/SendController.js.map +1 -1
- package/lib/module/features/reown-authentication/ReownAuthentication.js +260 -0
- package/lib/module/features/reown-authentication/ReownAuthentication.js.map +1 -0
- package/lib/module/features/reown-authentication/ReownAuthenticationMessenger.js +43 -0
- package/lib/module/features/reown-authentication/ReownAuthenticationMessenger.js.map +1 -0
- package/lib/module/features/reown-authentication/index.js +5 -0
- package/lib/module/features/reown-authentication/index.js.map +1 -0
- package/lib/module/index.js +4 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/utils/CoreHelperUtil.js +13 -2
- package/lib/module/utils/CoreHelperUtil.js.map +1 -1
- package/lib/module/utils/FetchUtil.js.map +1 -1
- package/lib/module/utils/StorageUtil.js +28 -28
- package/lib/module/utils/StorageUtil.js.map +1 -1
- package/lib/typescript/controllers/ConnectionsController.d.ts.map +1 -1
- package/lib/typescript/controllers/OptionsController.d.ts +3 -3
- package/lib/typescript/controllers/OptionsController.d.ts.map +1 -1
- package/lib/typescript/controllers/RouterController.d.ts +1 -1
- package/lib/typescript/controllers/RouterController.d.ts.map +1 -1
- package/lib/typescript/controllers/SendController.d.ts.map +1 -1
- package/lib/typescript/features/reown-authentication/ReownAuthentication.d.ts +174 -0
- package/lib/typescript/features/reown-authentication/ReownAuthentication.d.ts.map +1 -0
- package/lib/typescript/features/reown-authentication/ReownAuthenticationMessenger.d.ts +16 -0
- package/lib/typescript/features/reown-authentication/ReownAuthenticationMessenger.d.ts.map +1 -0
- package/lib/typescript/features/reown-authentication/index.d.ts +3 -0
- package/lib/typescript/features/reown-authentication/index.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +2 -0
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/utils/CoreHelperUtil.d.ts +2 -1
- package/lib/typescript/utils/CoreHelperUtil.d.ts.map +1 -1
- package/lib/typescript/utils/FetchUtil.d.ts +1 -1
- package/lib/typescript/utils/FetchUtil.d.ts.map +1 -1
- package/lib/typescript/utils/StorageUtil.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/controllers/ConnectionsController.ts +13 -3
- package/src/controllers/OptionsController.ts +11 -6
- package/src/controllers/RouterController.ts +3 -3
- package/src/controllers/SendController.ts +22 -2
- package/src/features/reown-authentication/ReownAuthentication.ts +470 -0
- package/src/features/reown-authentication/ReownAuthenticationMessenger.ts +80 -0
- package/src/features/reown-authentication/index.ts +2 -0
- package/src/index.ts +4 -0
- package/src/utils/CoreHelperUtil.ts +20 -2
- package/src/utils/FetchUtil.ts +1 -1
- package/src/utils/StorageUtil.ts +37 -53
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FetchUtil.d.ts","sourceRoot":"","sources":["../../../src/utils/FetchUtil.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AAGtE,UAAU,OAAO;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,UAAU,gBAAgB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IAC5C,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,UAAU,aAAc,SAAQ,gBAAgB;IAC9C,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAGD,qBAAa,SAAS;IACb,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IAC5B,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;gBAElB,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,OAAO;IAKpC,GAAG,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,EAAE,gBAAgB;IAOrD,IAAI,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,EAAE,aAAa;IAYzD,GAAG,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,EAAE,aAAa;IAYxD,MAAM,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,EAAE,aAAa;IAY3D,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"FetchUtil.d.ts","sourceRoot":"","sources":["../../../src/utils/FetchUtil.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AAGtE,UAAU,OAAO;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,UAAU,gBAAgB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IAC5C,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,UAAU,aAAc,SAAQ,gBAAgB;IAC9C,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAGD,qBAAa,SAAS;IACb,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IAC5B,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;gBAElB,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,OAAO;IAKpC,GAAG,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,EAAE,gBAAgB;IAOrD,IAAI,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,EAAE,aAAa;IAYzD,GAAG,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,EAAE,aAAa;IAYxD,MAAM,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,EAAE,aAAa;IAY3D,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAgB/D,SAAS,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,gBAAgB;YAsCrC,eAAe;CA2B9B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StorageUtil.d.ts","sourceRoot":"","sources":["../../../src/utils/StorageUtil.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC1B,KAAK,QAAQ,EAEb,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,cAAc,EAEpB,MAAM,mCAAmC,CAAC;AAI3C,eAAO,MAAM,WAAW;6CACmB,cAAc;;;4BAkCzB,QAAQ;
|
|
1
|
+
{"version":3,"file":"StorageUtil.d.ts","sourceRoot":"","sources":["../../../src/utils/StorageUtil.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC1B,KAAK,QAAQ,EAEb,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,cAAc,EAEpB,MAAM,mCAAmC,CAAC;AAI3C,eAAO,MAAM,WAAW;6CACmB,cAAc;;;4BAkCzB,QAAQ;8BAuBN,QAAQ,EAAE;wBAQhB,QAAQ,QAAQ,EAAE,CAAC;;cAgBrC,aAAa;oBACP,MAAM,EAAE;;8BAiBU,QAAQ;QAAE,IAAI,EAAE,aAAa,CAAC;QAAC,UAAU,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE,CAAC;oCAclD,aAAa;uCAaV,aAAa;;6CAyBP,kBAAkB;;kCAyB7B,aAAa,EAAE;;kDAsBC,qBAAqB,EAAE;;gDAsCzB,qBAAqB,EAAE;;oCAuCnC,eAAe,EAAE;;4CAsCT,kBAAkB,EAAE;;mCAsC7B,cAAc;;;CAoCpD,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reown/appkit-core-react-native",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.6",
|
|
4
4
|
"main": "lib/commonjs/index.js",
|
|
5
5
|
"types": "lib/typescript/index.d.ts",
|
|
6
6
|
"module": "lib/module/index.js",
|
|
@@ -40,10 +40,10 @@
|
|
|
40
40
|
"provenance": true
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@reown/appkit-common-react-native": "2.0.0-alpha.
|
|
43
|
+
"@reown/appkit-common-react-native": "2.0.0-alpha.6",
|
|
44
44
|
"countries-and-timezones": "3.7.2",
|
|
45
45
|
"derive-valtio": "0.2.0",
|
|
46
|
-
"valtio": "2.1.
|
|
46
|
+
"valtio": "2.1.8"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
49
|
"@walletconnect/react-native-compat": ">=2.16.1",
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
type AccountType,
|
|
14
14
|
type Connection,
|
|
15
15
|
SolanaBaseAdapter,
|
|
16
|
+
BitcoinBaseAdapter,
|
|
16
17
|
type Identity
|
|
17
18
|
} from '@reown/appkit-common-react-native';
|
|
18
19
|
import { StorageUtil } from '../utils/StorageUtil';
|
|
@@ -279,8 +280,11 @@ export const ConnectionsController = {
|
|
|
279
280
|
const existingBalances = connection.balances.get(address) || [];
|
|
280
281
|
// Check if this token already exists by contract address or symbol
|
|
281
282
|
const existingIndex = existingBalances.findIndex(existingBalance => {
|
|
282
|
-
if (balance.address) {
|
|
283
|
-
return
|
|
283
|
+
if (balance.address && existingBalance.address) {
|
|
284
|
+
return (
|
|
285
|
+
CoreHelperUtil.getPlainAddress(existingBalance.address) ===
|
|
286
|
+
CoreHelperUtil.getPlainAddress(balance.address)
|
|
287
|
+
);
|
|
284
288
|
}
|
|
285
289
|
|
|
286
290
|
return existingBalance.symbol === balance.symbol;
|
|
@@ -449,7 +453,13 @@ export const ConnectionsController = {
|
|
|
449
453
|
|
|
450
454
|
const adapter = baseState.connections.get(baseState.activeNamespace)?.adapter;
|
|
451
455
|
|
|
452
|
-
if (
|
|
456
|
+
if (
|
|
457
|
+
(adapter instanceof EVMAdapter ||
|
|
458
|
+
adapter instanceof SolanaBaseAdapter ||
|
|
459
|
+
adapter instanceof BitcoinBaseAdapter) &&
|
|
460
|
+
plainAddress &&
|
|
461
|
+
chainId
|
|
462
|
+
) {
|
|
453
463
|
return adapter.signMessage(plainAddress, message, chainId);
|
|
454
464
|
}
|
|
455
465
|
|
|
@@ -7,7 +7,8 @@ import type {
|
|
|
7
7
|
Features,
|
|
8
8
|
ProjectId,
|
|
9
9
|
SdkType,
|
|
10
|
-
SdkVersion
|
|
10
|
+
SdkVersion,
|
|
11
|
+
SIWXConfig
|
|
11
12
|
} from '@reown/appkit-common-react-native';
|
|
12
13
|
|
|
13
14
|
import { ConstantsUtil } from '../utils/ConstantsUtil';
|
|
@@ -29,7 +30,7 @@ export interface OptionsControllerState {
|
|
|
29
30
|
sdkType: SdkType;
|
|
30
31
|
sdkVersion: SdkVersion;
|
|
31
32
|
metadata?: Metadata;
|
|
32
|
-
|
|
33
|
+
siwx?: SIWXConfig;
|
|
33
34
|
isOnRampEnabled?: boolean;
|
|
34
35
|
features?: Features;
|
|
35
36
|
debug?: boolean;
|
|
@@ -87,10 +88,6 @@ export const OptionsController = {
|
|
|
87
88
|
state.metadata = metadata;
|
|
88
89
|
},
|
|
89
90
|
|
|
90
|
-
setIsSiweEnabled(isSiweEnabled: OptionsControllerState['isSiweEnabled']) {
|
|
91
|
-
state.isSiweEnabled = isSiweEnabled;
|
|
92
|
-
},
|
|
93
|
-
|
|
94
91
|
setFeatures(features: OptionsControllerState['features']) {
|
|
95
92
|
state.features = { ...ConstantsUtil.DEFAULT_FEATURES, ...features };
|
|
96
93
|
},
|
|
@@ -117,6 +114,14 @@ export const OptionsController = {
|
|
|
117
114
|
state.requestedNetworks = requestedNetworks;
|
|
118
115
|
},
|
|
119
116
|
|
|
117
|
+
setSiwx(siwx?: OptionsControllerState['siwx']) {
|
|
118
|
+
if (siwx && (siwx?.signOutOnDisconnect === undefined || siwx?.signOutOnDisconnect === null)) {
|
|
119
|
+
siwx.signOutOnDisconnect = true;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
state.siwx = siwx;
|
|
123
|
+
},
|
|
124
|
+
|
|
120
125
|
isClipboardAvailable() {
|
|
121
126
|
return !!state.clipboardClient;
|
|
122
127
|
},
|
|
@@ -15,23 +15,23 @@ export interface RouterControllerState {
|
|
|
15
15
|
| 'Connect'
|
|
16
16
|
| 'ConnectSocials'
|
|
17
17
|
| 'ConnectingExternal'
|
|
18
|
-
| 'ConnectingSiwe'
|
|
19
18
|
| 'ConnectingSocial'
|
|
20
|
-
| 'WalletConnect'
|
|
21
19
|
| 'GetWallet'
|
|
22
20
|
| 'Networks'
|
|
23
|
-
| 'SwitchNetwork'
|
|
24
21
|
| 'OnRamp'
|
|
25
22
|
| 'OnRampCheckout'
|
|
26
23
|
| 'OnRampLoading'
|
|
27
24
|
| 'OnRampSettings'
|
|
28
25
|
| 'OnRampTransaction'
|
|
26
|
+
| 'SIWXSignMessage'
|
|
29
27
|
| 'Swap'
|
|
30
28
|
| 'SwapPreview'
|
|
29
|
+
| 'SwitchNetwork'
|
|
31
30
|
| 'Transactions'
|
|
32
31
|
| 'UnsupportedChain'
|
|
33
32
|
| 'UpgradeEmailWallet'
|
|
34
33
|
| 'WalletCompatibleNetworks'
|
|
34
|
+
| 'WalletConnect'
|
|
35
35
|
| 'WalletReceive'
|
|
36
36
|
| 'WalletSend'
|
|
37
37
|
| 'WalletSendPreview'
|
|
@@ -8,6 +8,7 @@ import { EventsController } from './EventsController';
|
|
|
8
8
|
import { RouterController } from './RouterController';
|
|
9
9
|
import { ConnectionsController } from './ConnectionsController';
|
|
10
10
|
import { SwapController } from './SwapController';
|
|
11
|
+
import { ConstantsUtil as CoreConstantsUtil } from '../utils/ConstantsUtil';
|
|
11
12
|
|
|
12
13
|
// -- Types --------------------------------------------- //
|
|
13
14
|
export interface TxParams {
|
|
@@ -118,13 +119,18 @@ export const SendController = {
|
|
|
118
119
|
});
|
|
119
120
|
RouterController.reset(isAuth ? 'Account' : 'AccountDefault');
|
|
120
121
|
this.resetState();
|
|
121
|
-
} catch (error) {
|
|
122
|
+
} catch (error: any) {
|
|
122
123
|
EventsController.sendEvent({
|
|
123
124
|
type: 'track',
|
|
124
125
|
event: 'SEND_ERROR',
|
|
125
126
|
properties: eventProperties
|
|
126
127
|
});
|
|
127
|
-
|
|
128
|
+
|
|
129
|
+
if (error?.message && error?.message.includes('user rejected')) {
|
|
130
|
+
SnackController.showError('Transaction cancelled');
|
|
131
|
+
} else {
|
|
132
|
+
SnackController.showError('Something went wrong');
|
|
133
|
+
}
|
|
128
134
|
} finally {
|
|
129
135
|
this.state.loading = false;
|
|
130
136
|
}
|
|
@@ -222,7 +228,21 @@ export const SendController = {
|
|
|
222
228
|
throw new Error('Invalid address');
|
|
223
229
|
}
|
|
224
230
|
|
|
231
|
+
let tokenMint: string | undefined;
|
|
232
|
+
|
|
233
|
+
if (
|
|
234
|
+
SendController.state.token &&
|
|
235
|
+
SendController.state.token.address !== CoreConstantsUtil.NATIVE_TOKEN_ADDRESS.solana
|
|
236
|
+
) {
|
|
237
|
+
if (CoreHelperUtil.isCaipAddress(SendController.state.token.address)) {
|
|
238
|
+
tokenMint = CoreHelperUtil.getPlainAddress(SendController.state.token.address);
|
|
239
|
+
} else {
|
|
240
|
+
tokenMint = SendController.state.token.address;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
225
244
|
await ConnectionsController.sendTransaction({
|
|
245
|
+
tokenMint,
|
|
226
246
|
fromAddress: plainAddress,
|
|
227
247
|
toAddress: this.state.receiverAddress,
|
|
228
248
|
amount: this.state.sendTokenAmount,
|
|
@@ -0,0 +1,470 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type CaipNetworkId,
|
|
3
|
+
type ChainNamespace,
|
|
4
|
+
type SafeStorageItems,
|
|
5
|
+
SafeStorageKeys,
|
|
6
|
+
type SIWXConfig,
|
|
7
|
+
type SIWXMessage,
|
|
8
|
+
type SIWXSession
|
|
9
|
+
} from '@reown/appkit-common-react-native';
|
|
10
|
+
|
|
11
|
+
import { ApiController } from '../../controllers/ApiController';
|
|
12
|
+
import { BlockchainApiController } from '../../controllers/BlockchainApiController';
|
|
13
|
+
|
|
14
|
+
import { ReownAuthenticationMessenger } from './ReownAuthenticationMessenger';
|
|
15
|
+
import { ConnectionsController } from '../../controllers/ConnectionsController';
|
|
16
|
+
import { CoreHelperUtil } from '../../utils/CoreHelperUtil';
|
|
17
|
+
import { OptionsController } from '../../controllers/OptionsController';
|
|
18
|
+
import { FetchUtil } from '../../utils/FetchUtil';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* This is the configuration for using SIWX with Reown Authentication service.
|
|
22
|
+
* It allows you to authenticate and capture user sessions through the Reown Dashboard.
|
|
23
|
+
*/
|
|
24
|
+
export class ReownAuthentication implements SIWXConfig {
|
|
25
|
+
private readonly localAuthStorageKey: keyof SafeStorageItems;
|
|
26
|
+
private readonly localNonceStorageKey: keyof SafeStorageItems;
|
|
27
|
+
private readonly messenger: ReownAuthenticationMessenger;
|
|
28
|
+
private readonly fetchUtil = new FetchUtil({ baseUrl: CoreHelperUtil.getApiUrl() });
|
|
29
|
+
public readonly signOutOnDisconnect: boolean;
|
|
30
|
+
|
|
31
|
+
private required: boolean;
|
|
32
|
+
|
|
33
|
+
private listeners: ReownAuthentication.EventListeners = {
|
|
34
|
+
sessionChanged: []
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
constructor(params: ReownAuthentication.ConstructorParams = {}) {
|
|
38
|
+
this.localAuthStorageKey =
|
|
39
|
+
(params.localAuthStorageKey as keyof SafeStorageItems) || SafeStorageKeys.SIWX_AUTH_TOKEN;
|
|
40
|
+
this.localNonceStorageKey =
|
|
41
|
+
(params.localNonceStorageKey as keyof SafeStorageItems) || SafeStorageKeys.SIWX_NONCE_TOKEN;
|
|
42
|
+
this.required = params.required ?? true;
|
|
43
|
+
|
|
44
|
+
this.messenger = new ReownAuthenticationMessenger({
|
|
45
|
+
getNonce: this.getNonce.bind(this)
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
this.signOutOnDisconnect = params.signOutOnDisconnect ?? true;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async createMessage(input: SIWXMessage.Input): Promise<SIWXMessage> {
|
|
52
|
+
return this.messenger.createMessage(input);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async addSession(session: SIWXSession): Promise<void> {
|
|
56
|
+
const response = await this.request({
|
|
57
|
+
method: 'POST',
|
|
58
|
+
key: 'authenticate',
|
|
59
|
+
body: {
|
|
60
|
+
data: session.cacao ? undefined : session.data,
|
|
61
|
+
message: session.message,
|
|
62
|
+
signature: session.signature,
|
|
63
|
+
clientId: this.getClientId(),
|
|
64
|
+
walletInfo: this.getWalletInfo()
|
|
65
|
+
},
|
|
66
|
+
headers: ['nonce']
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
this.setStorageToken(response.token, this.localAuthStorageKey);
|
|
70
|
+
|
|
71
|
+
this.emit('sessionChanged', session);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async getSessions(chainId: CaipNetworkId, address: string): Promise<SIWXSession[]> {
|
|
75
|
+
try {
|
|
76
|
+
const sessions = await this.getStorageToken(this.localAuthStorageKey);
|
|
77
|
+
if (!sessions) {
|
|
78
|
+
return [];
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const account = await this.request({
|
|
82
|
+
method: 'GET',
|
|
83
|
+
key: 'me',
|
|
84
|
+
query: {},
|
|
85
|
+
headers: ['auth']
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
if (!account) {
|
|
89
|
+
return [];
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const isSameAddress = account.address.toLowerCase() === address.toLowerCase();
|
|
93
|
+
const isSameNetwork = account.caip2Network === chainId;
|
|
94
|
+
|
|
95
|
+
if (!isSameAddress || !isSameNetwork) {
|
|
96
|
+
return [];
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const session: SIWXSession = {
|
|
100
|
+
data: {
|
|
101
|
+
accountAddress: account.address,
|
|
102
|
+
chainId: account.caip2Network
|
|
103
|
+
} as SIWXMessage.Data,
|
|
104
|
+
message: '',
|
|
105
|
+
signature: ''
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
this.emit('sessionChanged', session);
|
|
109
|
+
|
|
110
|
+
return [session];
|
|
111
|
+
} catch {
|
|
112
|
+
return [];
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
async revokeSession(_chainId: CaipNetworkId, _address: string): Promise<void> {
|
|
117
|
+
return Promise.resolve(this.clearStorageTokens());
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async setSessions(sessions: SIWXSession[]): Promise<void> {
|
|
121
|
+
if (sessions.length === 0) {
|
|
122
|
+
this.clearStorageTokens();
|
|
123
|
+
} else {
|
|
124
|
+
const session = (sessions.find(
|
|
125
|
+
s => s.data.chainId === ConnectionsController.state.activeCaipNetworkId
|
|
126
|
+
) || sessions[0]) as SIWXSession;
|
|
127
|
+
|
|
128
|
+
await this.addSession(session);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
getRequired() {
|
|
133
|
+
return this.required;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
async getSessionAccount() {
|
|
137
|
+
const sessions = await this.getStorageToken(this.localAuthStorageKey);
|
|
138
|
+
if (!sessions) {
|
|
139
|
+
throw new Error('Not authenticated');
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return this.request({
|
|
143
|
+
method: 'GET',
|
|
144
|
+
key: 'me',
|
|
145
|
+
body: undefined,
|
|
146
|
+
query: {
|
|
147
|
+
includeAppKitAccount: true
|
|
148
|
+
},
|
|
149
|
+
headers: ['auth']
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
async setSessionAccountMetadata(metadata: object | null = null) {
|
|
154
|
+
const sessions = await this.getStorageToken(this.localAuthStorageKey);
|
|
155
|
+
if (!sessions) {
|
|
156
|
+
throw new Error('Not authenticated');
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return this.request({
|
|
160
|
+
method: 'PUT',
|
|
161
|
+
key: 'account-metadata',
|
|
162
|
+
body: { metadata },
|
|
163
|
+
headers: ['auth']
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
on<Event extends keyof ReownAuthentication.Events>(
|
|
168
|
+
event: Event,
|
|
169
|
+
callback: ReownAuthentication.Listener<Event>
|
|
170
|
+
) {
|
|
171
|
+
this.listeners[event].push(callback);
|
|
172
|
+
|
|
173
|
+
return () => {
|
|
174
|
+
this.listeners[event] = this.listeners[event].filter(
|
|
175
|
+
cb => cb !== callback
|
|
176
|
+
) as ReownAuthentication.EventListeners[Event];
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
removeAllListeners() {
|
|
181
|
+
const keys = Object.keys(this.listeners) as (keyof ReownAuthentication.Events)[];
|
|
182
|
+
keys.forEach(key => {
|
|
183
|
+
this.listeners[key] = [];
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
private async request<
|
|
188
|
+
Method extends ReownAuthentication.Methods,
|
|
189
|
+
Key extends ReownAuthentication.RequestKeys<Method>
|
|
190
|
+
>({
|
|
191
|
+
method,
|
|
192
|
+
key,
|
|
193
|
+
query,
|
|
194
|
+
body,
|
|
195
|
+
headers
|
|
196
|
+
}: ReownAuthentication.RequestParams<Key, Method>): Promise<
|
|
197
|
+
ReownAuthentication.RequestResponse<Method, Key>
|
|
198
|
+
> {
|
|
199
|
+
const { projectId, st, sv, domain } = this.getSDKProperties();
|
|
200
|
+
|
|
201
|
+
const url = this.fetchUtil.createUrl({
|
|
202
|
+
path: `/auth/v1/${String(key)}`,
|
|
203
|
+
params: { projectId, st, sv, domain, ...query }
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
const nonceJwt = await this.getStorageToken(this.localNonceStorageKey);
|
|
207
|
+
const auth = await this.getStorageToken(this.localAuthStorageKey);
|
|
208
|
+
|
|
209
|
+
const response = await fetch(url, {
|
|
210
|
+
method,
|
|
211
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
212
|
+
headers: {
|
|
213
|
+
'Content-Type': 'application/json',
|
|
214
|
+
...(Array.isArray(headers)
|
|
215
|
+
? headers.reduce((acc, header) => {
|
|
216
|
+
switch (header) {
|
|
217
|
+
case 'nonce':
|
|
218
|
+
acc['x-nonce-jwt'] = `Bearer ${nonceJwt}`;
|
|
219
|
+
break;
|
|
220
|
+
case 'auth':
|
|
221
|
+
acc['Authorization'] = `Bearer ${auth}`;
|
|
222
|
+
break;
|
|
223
|
+
default:
|
|
224
|
+
break;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return acc;
|
|
228
|
+
}, {})
|
|
229
|
+
: {})
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
if (!response.ok) {
|
|
234
|
+
throw new Error(await response.text());
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (response.headers.get('content-type')?.includes('application/json')) {
|
|
238
|
+
return response.json();
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return null as ReownAuthentication.RequestResponse<Method, Key>;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
private async getStorageToken(key: keyof SafeStorageItems): Promise<string | undefined> {
|
|
245
|
+
return OptionsController.getStorage().getItem(key);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
private setStorageToken(token: string, key: keyof SafeStorageItems): void {
|
|
249
|
+
OptionsController.getStorage().setItem(key, token);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
private clearStorageTokens(): void {
|
|
253
|
+
OptionsController.getStorage().removeItem(this.localAuthStorageKey);
|
|
254
|
+
OptionsController.getStorage().removeItem(this.localNonceStorageKey);
|
|
255
|
+
this.emit('sessionChanged', undefined);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
private async getNonce(): Promise<string> {
|
|
259
|
+
const { nonce, token } = await this.request({
|
|
260
|
+
method: 'GET',
|
|
261
|
+
key: 'nonce'
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
this.setStorageToken(token, this.localNonceStorageKey);
|
|
265
|
+
|
|
266
|
+
return nonce;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
private getClientId(): string | null {
|
|
270
|
+
return BlockchainApiController.state.clientId;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
private getWalletInfo(): ReownAuthentication.WalletInfo | undefined {
|
|
274
|
+
const connectedWalletInfo = ConnectionsController.state.walletInfo;
|
|
275
|
+
const connectionProperties = ConnectionsController.state.connection?.properties;
|
|
276
|
+
|
|
277
|
+
if (!connectedWalletInfo || !connectionProperties) {
|
|
278
|
+
return undefined;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
if (connectionProperties?.provider) {
|
|
282
|
+
const social = connectionProperties.provider;
|
|
283
|
+
const identifier = connectionProperties.email || 'unknown';
|
|
284
|
+
|
|
285
|
+
return { type: 'social', social, identifier };
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
let { name, icon, type } = connectedWalletInfo;
|
|
289
|
+
|
|
290
|
+
if (!type || type !== 'walletconnect') {
|
|
291
|
+
type = 'unknown';
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
return {
|
|
295
|
+
type,
|
|
296
|
+
name,
|
|
297
|
+
icon
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
private getSDKProperties(): { projectId: string; st: string; sv: string; domain: string } {
|
|
302
|
+
const headers = ApiController._getApiHeaders();
|
|
303
|
+
|
|
304
|
+
return {
|
|
305
|
+
projectId: headers['x-project-id'],
|
|
306
|
+
st: headers['x-sdk-type'],
|
|
307
|
+
sv: headers['x-sdk-version'],
|
|
308
|
+
domain: headers['origin']
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
private emit<Event extends keyof ReownAuthentication.Events>(
|
|
313
|
+
event: Event,
|
|
314
|
+
data: ReownAuthentication.Events[Event]
|
|
315
|
+
) {
|
|
316
|
+
this.listeners[event].forEach(listener => listener(data));
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
export namespace ReownAuthentication {
|
|
321
|
+
export type ConstructorParams = {
|
|
322
|
+
/**
|
|
323
|
+
* The key to use for storing the session token in local storage.
|
|
324
|
+
* @default '@appkit/siwx-auth-token'
|
|
325
|
+
*/
|
|
326
|
+
localAuthStorageKey?: string;
|
|
327
|
+
/**
|
|
328
|
+
* The key to use for storing the nonce token in local storage.
|
|
329
|
+
* @default '@appkit/siwx-nonce-token'
|
|
330
|
+
*/
|
|
331
|
+
localNonceStorageKey?: string;
|
|
332
|
+
/**
|
|
333
|
+
* If false the wallet stays connected when user denies the signature request.
|
|
334
|
+
* @default true
|
|
335
|
+
*/
|
|
336
|
+
required?: boolean;
|
|
337
|
+
/**
|
|
338
|
+
* This flag determines whether the session should be cleared when the user disconnects.
|
|
339
|
+
*
|
|
340
|
+
* @default true
|
|
341
|
+
*/
|
|
342
|
+
signOutOnDisconnect?: boolean;
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
export type AvailableRequestHeaders = {
|
|
346
|
+
nonce: {
|
|
347
|
+
'x-nonce-jwt': string;
|
|
348
|
+
};
|
|
349
|
+
auth: {
|
|
350
|
+
Authorization: string;
|
|
351
|
+
};
|
|
352
|
+
origin: {
|
|
353
|
+
origin: string;
|
|
354
|
+
};
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
export type RequestParams<Key extends keyof Requests[Method], Method extends Methods> = {
|
|
358
|
+
method: Method;
|
|
359
|
+
key: Key;
|
|
360
|
+
// @ts-expect-error - This is matching correctly already
|
|
361
|
+
} & Pick<Requests[Method][Key], 'query' | 'body' | 'headers'>;
|
|
362
|
+
|
|
363
|
+
export type RequestResponse<
|
|
364
|
+
Method extends Methods,
|
|
365
|
+
Key extends RequestKeys<Method>
|
|
366
|
+
// @ts-expect-error - This is matching correctly already
|
|
367
|
+
> = Requests[Method][Key]['response'];
|
|
368
|
+
|
|
369
|
+
export type Request<
|
|
370
|
+
Body,
|
|
371
|
+
Response,
|
|
372
|
+
Query extends Record<string, unknown> | undefined = undefined,
|
|
373
|
+
Headers extends (keyof AvailableRequestHeaders)[] | undefined = undefined
|
|
374
|
+
> = (Response extends undefined
|
|
375
|
+
? {
|
|
376
|
+
response?: never;
|
|
377
|
+
}
|
|
378
|
+
: {
|
|
379
|
+
response: Response;
|
|
380
|
+
}) &
|
|
381
|
+
(Body extends undefined ? { body?: never } : { body: Body }) &
|
|
382
|
+
(Query extends undefined ? { query?: never } : { query: Query }) &
|
|
383
|
+
(Headers extends undefined ? { headers?: never } : { headers: Headers });
|
|
384
|
+
|
|
385
|
+
export type Requests = {
|
|
386
|
+
GET: {
|
|
387
|
+
nonce: Request<undefined, { nonce: string; token: string }>;
|
|
388
|
+
me: Request<
|
|
389
|
+
undefined,
|
|
390
|
+
Omit<SessionAccount, 'appKitAccount'>,
|
|
391
|
+
{ includeAppKitAccount?: boolean },
|
|
392
|
+
['auth']
|
|
393
|
+
>;
|
|
394
|
+
};
|
|
395
|
+
POST: {
|
|
396
|
+
'authenticate': Request<
|
|
397
|
+
{
|
|
398
|
+
data?: SIWXMessage.Data;
|
|
399
|
+
message: string;
|
|
400
|
+
signature: string;
|
|
401
|
+
clientId?: string | null;
|
|
402
|
+
walletInfo?: WalletInfo;
|
|
403
|
+
},
|
|
404
|
+
{
|
|
405
|
+
token: string;
|
|
406
|
+
},
|
|
407
|
+
undefined,
|
|
408
|
+
['nonce']
|
|
409
|
+
>;
|
|
410
|
+
'sign-out': Request<undefined, never, never, ['auth']>;
|
|
411
|
+
};
|
|
412
|
+
PUT: {
|
|
413
|
+
'account-metadata': Request<{ metadata: object | null }, unknown, undefined, ['auth']>;
|
|
414
|
+
};
|
|
415
|
+
};
|
|
416
|
+
|
|
417
|
+
export type Methods = 'GET' | 'POST' | 'PUT';
|
|
418
|
+
|
|
419
|
+
export type RequestKeys<Method extends Methods> = keyof Requests[Method];
|
|
420
|
+
|
|
421
|
+
export type WalletInfo =
|
|
422
|
+
| {
|
|
423
|
+
type: 'walletconnect' | 'external' | 'unknown';
|
|
424
|
+
name: string | undefined;
|
|
425
|
+
icon: string | undefined;
|
|
426
|
+
}
|
|
427
|
+
| { type: 'social'; social: string; identifier: string };
|
|
428
|
+
|
|
429
|
+
export type Events = {
|
|
430
|
+
sessionChanged: SIWXSession | undefined;
|
|
431
|
+
};
|
|
432
|
+
|
|
433
|
+
export type Listener<Event extends keyof Events> = (event: Events[Event]) => void;
|
|
434
|
+
|
|
435
|
+
export type EventListeners = {
|
|
436
|
+
[Key in keyof Events]: Listener<Key>[];
|
|
437
|
+
};
|
|
438
|
+
|
|
439
|
+
export type SessionAccount = {
|
|
440
|
+
aud: string;
|
|
441
|
+
iss: string;
|
|
442
|
+
exp: number;
|
|
443
|
+
projectIdKey: string;
|
|
444
|
+
sub: string;
|
|
445
|
+
address: string;
|
|
446
|
+
chainId: number | string;
|
|
447
|
+
chainNamespace: ChainNamespace;
|
|
448
|
+
caip2Network: string;
|
|
449
|
+
uri: string;
|
|
450
|
+
domain: string;
|
|
451
|
+
projectUuid: string;
|
|
452
|
+
profileUuid: string;
|
|
453
|
+
nonce: string;
|
|
454
|
+
email?: string;
|
|
455
|
+
appKitAccount?: {
|
|
456
|
+
uuid: string;
|
|
457
|
+
caip2_chain: string;
|
|
458
|
+
address: string;
|
|
459
|
+
profile_uuid: string;
|
|
460
|
+
created_at: string;
|
|
461
|
+
is_main_account: boolean;
|
|
462
|
+
verification_status: null;
|
|
463
|
+
connection_method: object | null;
|
|
464
|
+
metadata: object;
|
|
465
|
+
last_signed_in_at: string;
|
|
466
|
+
signed_up_at: string;
|
|
467
|
+
updated_at: string;
|
|
468
|
+
};
|
|
469
|
+
};
|
|
470
|
+
}
|