@dynamic-labs/solana 1.1.0-alpha.21 → 1.1.0-alpha.23
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 +15 -0
- package/package.json +7 -7
- package/src/CoinbaseSolana.cjs +4 -2
- package/src/CoinbaseSolana.js +4 -2
- package/src/Phantom.cjs +41 -0
- package/src/Phantom.d.ts +12 -0
- package/src/Phantom.js +37 -0
- package/src/index.cjs +2 -0
- package/src/index.d.ts +2 -1
- package/src/index.js +2 -0
- package/src/injected/{Phantom.cjs → PhantomInjected.cjs} +2 -2
- package/src/injected/{Phantom.d.ts → PhantomInjected.d.ts} +1 -1
- package/src/injected/{Phantom.js → PhantomInjected.js} +2 -2
- package/src/injected/fetchInjectedWalletConnectors.cjs +0 -2
- package/src/injected/fetchInjectedWalletConnectors.js +0 -2
- package/src/phantomRedirect/PhantomRedirect.cjs +160 -0
- package/src/phantomRedirect/PhantomRedirect.js +151 -0
- package/src/phantomRedirect/storage.cjs +80 -0
- package/src/phantomRedirect/storage.js +76 -0
- package/src/phantomRedirect/utils.cjs +29 -0
- package/src/phantomRedirect/utils.js +18 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,19 @@
|
|
|
1
1
|
|
|
2
|
+
## [1.1.0-alpha.23](https://github.com/dynamic-labs/DynamicAuth/compare/v1.1.0-alpha.22...v1.1.0-alpha.23) (2024-02-01)
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
* bitcoin signPsbt ([3c964de](https://github.com/dynamic-labs/DynamicAuth/commit/3c964dea8a55debaf184c5a94f0f5fabdda3c877))
|
|
8
|
+
* embedded wallet email auth flow ([#4353](https://github.com/dynamic-labs/DynamicAuth/issues/4353)) ([4875da3](https://github.com/dynamic-labs/DynamicAuth/commit/4875da32c47c27facef1b1cdbdc214566bbfd171))
|
|
9
|
+
|
|
10
|
+
## [1.1.0-alpha.22](https://github.com/dynamic-labs/DynamicAuth/compare/v1.1.0-alpha.21...v1.1.0-alpha.22) (2024-02-01)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* onAuthFlowClose not being called ([#4563](https://github.com/dynamic-labs/DynamicAuth/issues/4563)) ([c4b2648](https://github.com/dynamic-labs/DynamicAuth/commit/c4b264885b7dba6e204ef49bf642d25c7d287b04))
|
|
16
|
+
|
|
2
17
|
## [1.1.0-alpha.21](https://github.com/dynamic-labs/DynamicAuth/compare/v1.1.0-alpha.20...v1.1.0-alpha.21) (2024-02-01)
|
|
3
18
|
|
|
4
19
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dynamic-labs/solana",
|
|
3
|
-
"version": "1.1.0-alpha.
|
|
3
|
+
"version": "1.1.0-alpha.23",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/dynamic-labs/DynamicAuth.git",
|
|
@@ -30,12 +30,12 @@
|
|
|
30
30
|
"@dynamic-labs/sdk-api": "0.0.356",
|
|
31
31
|
"bs58": "^5.0.0",
|
|
32
32
|
"tweetnacl": "^1.0.3",
|
|
33
|
-
"@dynamic-labs/rpc-providers": "1.1.0-alpha.
|
|
34
|
-
"@dynamic-labs/turnkey": "1.1.0-alpha.
|
|
35
|
-
"@dynamic-labs/types": "1.1.0-alpha.
|
|
36
|
-
"@dynamic-labs/utils": "1.1.0-alpha.
|
|
37
|
-
"@dynamic-labs/wallet-book": "1.1.0-alpha.
|
|
38
|
-
"@dynamic-labs/wallet-connector-core": "1.1.0-alpha.
|
|
33
|
+
"@dynamic-labs/rpc-providers": "1.1.0-alpha.23",
|
|
34
|
+
"@dynamic-labs/turnkey": "1.1.0-alpha.23",
|
|
35
|
+
"@dynamic-labs/types": "1.1.0-alpha.23",
|
|
36
|
+
"@dynamic-labs/utils": "1.1.0-alpha.23",
|
|
37
|
+
"@dynamic-labs/wallet-book": "1.1.0-alpha.23",
|
|
38
|
+
"@dynamic-labs/wallet-connector-core": "1.1.0-alpha.23",
|
|
39
39
|
"eventemitter3": "5.0.1"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {}
|
package/src/CoinbaseSolana.cjs
CHANGED
|
@@ -7,10 +7,12 @@ var utils = require('@dynamic-labs/utils');
|
|
|
7
7
|
var walletBook = require('@dynamic-labs/wallet-book');
|
|
8
8
|
require('@dynamic-labs/turnkey');
|
|
9
9
|
require('@dynamic-labs/sdk-api');
|
|
10
|
-
|
|
10
|
+
require('./solWalletConnector.cjs');
|
|
11
|
+
require('tweetnacl');
|
|
12
|
+
require('bs58');
|
|
11
13
|
require('@solana/web3.js');
|
|
14
|
+
var InjectedWalletBase = require('./injected/InjectedWalletBase.cjs');
|
|
12
15
|
require('@dynamic-labs/wallet-connector-core');
|
|
13
|
-
require('./solWalletConnector.cjs');
|
|
14
16
|
var isSignedMessage = require('./utils/isSignedMessage.cjs');
|
|
15
17
|
|
|
16
18
|
class CoinbaseSolana extends InjectedWalletBase.InjectedWalletBase {
|
package/src/CoinbaseSolana.js
CHANGED
|
@@ -3,10 +3,12 @@ import { bufferToBase64 } from '@dynamic-labs/utils';
|
|
|
3
3
|
import { findWalletBookWallet } from '@dynamic-labs/wallet-book';
|
|
4
4
|
import '@dynamic-labs/turnkey';
|
|
5
5
|
import '@dynamic-labs/sdk-api';
|
|
6
|
-
import
|
|
6
|
+
import './solWalletConnector.js';
|
|
7
|
+
import 'tweetnacl';
|
|
8
|
+
import 'bs58';
|
|
7
9
|
import '@solana/web3.js';
|
|
10
|
+
import { InjectedWalletBase } from './injected/InjectedWalletBase.js';
|
|
8
11
|
import '@dynamic-labs/wallet-connector-core';
|
|
9
|
-
import './solWalletConnector.js';
|
|
10
12
|
import { isSignedMessage } from './utils/isSignedMessage.js';
|
|
11
13
|
|
|
12
14
|
class CoinbaseSolana extends InjectedWalletBase {
|
package/src/Phantom.cjs
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var _tslib = require('../_virtual/_tslib.cjs');
|
|
6
|
+
var walletBook = require('@dynamic-labs/wallet-book');
|
|
7
|
+
var utils = require('@dynamic-labs/utils');
|
|
8
|
+
var solWalletConnector = require('./solWalletConnector.cjs');
|
|
9
|
+
var PhantomRedirect = require('./phantomRedirect/PhantomRedirect.cjs');
|
|
10
|
+
var PhantomInjected = require('./injected/PhantomInjected.cjs');
|
|
11
|
+
|
|
12
|
+
class Phantom extends solWalletConnector.SolWalletConnector {
|
|
13
|
+
constructor(opts) {
|
|
14
|
+
super(opts);
|
|
15
|
+
this.name = 'Phantom';
|
|
16
|
+
this.wallet = walletBook.findWalletBookWallet(this.walletBook, this.key);
|
|
17
|
+
}
|
|
18
|
+
connect() {
|
|
19
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
20
|
+
yield this.getMobileOrInstalledWallet().connect();
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
getSigner() {
|
|
24
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
25
|
+
return this.getMobileOrInstalledWallet().getSigner();
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
getMobileOrInstalledWallet() {
|
|
29
|
+
if (!utils.isMobile()) {
|
|
30
|
+
return new PhantomInjected.PhantomInjected(this.constructorProps);
|
|
31
|
+
}
|
|
32
|
+
if (this.constructorProps.mobileExperience === 'redirect') {
|
|
33
|
+
return new PhantomRedirect.PhantomRedirect(this.constructorProps);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
return new PhantomInjected.PhantomInjected(this.constructorProps);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
exports.Phantom = Phantom;
|
package/src/Phantom.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { WalletSchema } from '@dynamic-labs/wallet-book';
|
|
2
|
+
import { WalletConnectorCore } from '@dynamic-labs/wallet-connector-core';
|
|
3
|
+
import { ISolana } from '..';
|
|
4
|
+
import { SolWalletConnector, SolWalletConnectorOpts } from './solWalletConnector';
|
|
5
|
+
export declare class Phantom extends SolWalletConnector {
|
|
6
|
+
name: string;
|
|
7
|
+
wallet: WalletSchema | undefined;
|
|
8
|
+
constructor(opts: SolWalletConnectorOpts);
|
|
9
|
+
connect(): Promise<void>;
|
|
10
|
+
getSigner(): Promise<ISolana | undefined>;
|
|
11
|
+
getMobileOrInstalledWallet(): WalletConnectorCore.WalletConnector;
|
|
12
|
+
}
|
package/src/Phantom.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { __awaiter } from '../_virtual/_tslib.js';
|
|
2
|
+
import { findWalletBookWallet } from '@dynamic-labs/wallet-book';
|
|
3
|
+
import { isMobile } from '@dynamic-labs/utils';
|
|
4
|
+
import { SolWalletConnector } from './solWalletConnector.js';
|
|
5
|
+
import { PhantomRedirect } from './phantomRedirect/PhantomRedirect.js';
|
|
6
|
+
import { PhantomInjected } from './injected/PhantomInjected.js';
|
|
7
|
+
|
|
8
|
+
class Phantom extends SolWalletConnector {
|
|
9
|
+
constructor(opts) {
|
|
10
|
+
super(opts);
|
|
11
|
+
this.name = 'Phantom';
|
|
12
|
+
this.wallet = findWalletBookWallet(this.walletBook, this.key);
|
|
13
|
+
}
|
|
14
|
+
connect() {
|
|
15
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
16
|
+
yield this.getMobileOrInstalledWallet().connect();
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
getSigner() {
|
|
20
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
21
|
+
return this.getMobileOrInstalledWallet().getSigner();
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
getMobileOrInstalledWallet() {
|
|
25
|
+
if (!isMobile()) {
|
|
26
|
+
return new PhantomInjected(this.constructorProps);
|
|
27
|
+
}
|
|
28
|
+
if (this.constructorProps.mobileExperience === 'redirect') {
|
|
29
|
+
return new PhantomRedirect(this.constructorProps);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
return new PhantomInjected(this.constructorProps);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export { Phantom };
|
package/src/index.cjs
CHANGED
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
var turnkey = require('@dynamic-labs/turnkey');
|
|
6
6
|
var sdkApi = require('@dynamic-labs/sdk-api');
|
|
7
|
+
var Phantom = require('./Phantom.cjs');
|
|
7
8
|
var fetchInjectedWalletConnectors = require('./injected/fetchInjectedWalletConnectors.cjs');
|
|
8
9
|
var isSignedMessage = require('./utils/isSignedMessage.cjs');
|
|
9
10
|
var isBackpackSolanaSigner = require('./utils/isBackpackSolanaSigner.cjs');
|
|
@@ -13,6 +14,7 @@ const SolanaWalletConnectors = (props) => [
|
|
|
13
14
|
...fetchInjectedWalletConnectors.injectedWalletOverrides,
|
|
14
15
|
...fetchInjectedWalletConnectors.fetchInjectedWalletConnectors(props),
|
|
15
16
|
...turnkey.TurnkeyWalletConnectors(props, sdkApi.ChainEnum.Sol),
|
|
17
|
+
Phantom.Phantom,
|
|
16
18
|
];
|
|
17
19
|
|
|
18
20
|
exports.isSignedMessage = isSignedMessage.isSignedMessage;
|
package/src/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
import { Phantom } from './Phantom';
|
|
2
|
+
export declare const SolanaWalletConnectors: (props: any) => (import("dist/packages/wallet-connector-core/src").WalletConnectorConstructor | typeof Phantom)[];
|
|
2
3
|
export { isSignedMessage } from './utils/isSignedMessage';
|
|
3
4
|
export { isBackpackSolanaSigner } from './utils/isBackpackSolanaSigner';
|
|
4
5
|
export type { ISolana, IBackpackSolanaSigner, ICoinbaseSolanaSigner, SignedMessage, ISolanaSigner, } from './types';
|
package/src/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { TurnkeyWalletConnectors } from '@dynamic-labs/turnkey';
|
|
2
2
|
import { ChainEnum } from '@dynamic-labs/sdk-api';
|
|
3
|
+
import { Phantom } from './Phantom.js';
|
|
3
4
|
import { injectedWalletOverrides, fetchInjectedWalletConnectors } from './injected/fetchInjectedWalletConnectors.js';
|
|
4
5
|
export { isSignedMessage } from './utils/isSignedMessage.js';
|
|
5
6
|
export { isBackpackSolanaSigner } from './utils/isBackpackSolanaSigner.js';
|
|
@@ -9,6 +10,7 @@ const SolanaWalletConnectors = (props) => [
|
|
|
9
10
|
...injectedWalletOverrides,
|
|
10
11
|
...fetchInjectedWalletConnectors(props),
|
|
11
12
|
...TurnkeyWalletConnectors(props, ChainEnum.Sol),
|
|
13
|
+
Phantom,
|
|
12
14
|
];
|
|
13
15
|
|
|
14
16
|
export { SolanaWalletConnectors };
|
|
@@ -7,7 +7,7 @@ var utils = require('@dynamic-labs/utils');
|
|
|
7
7
|
var walletBook = require('@dynamic-labs/wallet-book');
|
|
8
8
|
var InjectedWalletBase = require('./InjectedWalletBase.cjs');
|
|
9
9
|
|
|
10
|
-
class
|
|
10
|
+
class PhantomInjected extends InjectedWalletBase.InjectedWalletBase {
|
|
11
11
|
constructor(opts) {
|
|
12
12
|
super(opts);
|
|
13
13
|
this.name = 'Phantom';
|
|
@@ -32,4 +32,4 @@ class Phantom extends InjectedWalletBase.InjectedWalletBase {
|
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
exports.
|
|
35
|
+
exports.PhantomInjected = PhantomInjected;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SolWalletConnectorOpts } from '../solWalletConnector';
|
|
2
2
|
import { InjectedWalletBase } from './InjectedWalletBase';
|
|
3
|
-
export declare class
|
|
3
|
+
export declare class PhantomInjected extends InjectedWalletBase {
|
|
4
4
|
name: string;
|
|
5
5
|
constructor(opts: SolWalletConnectorOpts);
|
|
6
6
|
fetchPublicAddress(): Promise<string | undefined>;
|
|
@@ -3,7 +3,7 @@ import { isMobile, handleMobileWalletRedirect } from '@dynamic-labs/utils';
|
|
|
3
3
|
import { findWalletBookWallet } from '@dynamic-labs/wallet-book';
|
|
4
4
|
import { InjectedWalletBase } from './InjectedWalletBase.js';
|
|
5
5
|
|
|
6
|
-
class
|
|
6
|
+
class PhantomInjected extends InjectedWalletBase {
|
|
7
7
|
constructor(opts) {
|
|
8
8
|
super(opts);
|
|
9
9
|
this.name = 'Phantom';
|
|
@@ -28,4 +28,4 @@ class Phantom extends InjectedWalletBase {
|
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
export {
|
|
31
|
+
export { PhantomInjected };
|
|
@@ -5,13 +5,11 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
5
5
|
var CoinbaseSolana = require('../CoinbaseSolana.cjs');
|
|
6
6
|
var Slope = require('../Slope.cjs');
|
|
7
7
|
var InjectedWalletBase = require('./InjectedWalletBase.cjs');
|
|
8
|
-
var Phantom = require('./Phantom.cjs');
|
|
9
8
|
var BackpackSol = require('./BackpackSol.cjs');
|
|
10
9
|
|
|
11
10
|
const injectedWalletOverrides = [
|
|
12
11
|
CoinbaseSolana.CoinbaseSolana,
|
|
13
12
|
Slope.Slope,
|
|
14
|
-
Phantom.Phantom,
|
|
15
13
|
BackpackSol.BackpackSol,
|
|
16
14
|
];
|
|
17
15
|
const filteredInjectedWalletKeysOverrides = [
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import { CoinbaseSolana } from '../CoinbaseSolana.js';
|
|
2
2
|
import { Slope } from '../Slope.js';
|
|
3
3
|
import { InjectedWalletBase } from './InjectedWalletBase.js';
|
|
4
|
-
import { Phantom } from './Phantom.js';
|
|
5
4
|
import { BackpackSol } from './BackpackSol.js';
|
|
6
5
|
|
|
7
6
|
const injectedWalletOverrides = [
|
|
8
7
|
CoinbaseSolana,
|
|
9
8
|
Slope,
|
|
10
|
-
Phantom,
|
|
11
9
|
BackpackSol,
|
|
12
10
|
];
|
|
13
11
|
const filteredInjectedWalletKeysOverrides = [
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var _tslib = require('../../_virtual/_tslib.cjs');
|
|
6
|
+
var nacl = require('tweetnacl');
|
|
7
|
+
var bs58 = require('bs58');
|
|
8
|
+
var web3_js = require('@solana/web3.js');
|
|
9
|
+
var solWalletConnector = require('../solWalletConnector.cjs');
|
|
10
|
+
var utils = require('./utils.cjs');
|
|
11
|
+
var storage = require('./storage.cjs');
|
|
12
|
+
|
|
13
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
14
|
+
|
|
15
|
+
var nacl__default = /*#__PURE__*/_interopDefaultLegacy(nacl);
|
|
16
|
+
var bs58__default = /*#__PURE__*/_interopDefaultLegacy(bs58);
|
|
17
|
+
|
|
18
|
+
class PhantomRedirect extends solWalletConnector.SolWalletConnector {
|
|
19
|
+
constructor(props) {
|
|
20
|
+
super(Object.assign({}, props));
|
|
21
|
+
this.name = 'Phantom';
|
|
22
|
+
}
|
|
23
|
+
fetchPublicAddress() {
|
|
24
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
25
|
+
const address = storage.storage.address.get();
|
|
26
|
+
if (address) {
|
|
27
|
+
return address;
|
|
28
|
+
}
|
|
29
|
+
yield this.connect();
|
|
30
|
+
return undefined;
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
connect() {
|
|
34
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
35
|
+
// Generate a new key pair
|
|
36
|
+
const keyPair = nacl__default["default"].box.keyPair();
|
|
37
|
+
storage.storage.encryptionPublicKey.set(keyPair.publicKey);
|
|
38
|
+
storage.storage.encryptionSecretKey.set(keyPair.secretKey);
|
|
39
|
+
const isLocalHost = window.location.href.includes('localhost') ||
|
|
40
|
+
window.location.href.includes('0.0.0.0') ||
|
|
41
|
+
window.location.href.includes('127.0.0.1');
|
|
42
|
+
const params = new URLSearchParams({
|
|
43
|
+
app_url: isLocalHost ? 'https://demo.dynamic.xyz' : window.location.href,
|
|
44
|
+
cluster: 'mainnet-beta',
|
|
45
|
+
dapp_encryption_public_key: bs58__default["default"].encode(keyPair.publicKey),
|
|
46
|
+
redirect_link: window.location.href,
|
|
47
|
+
});
|
|
48
|
+
const url = utils.buildUrl('connect', params);
|
|
49
|
+
window.location.href = url;
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
getSession() {
|
|
53
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
54
|
+
const params = new URLSearchParams(window.location.search);
|
|
55
|
+
const { data, nonce, phantom_encryption_public_key: phantomEncryptionPublicKey, encryptionSecretKey, } = this.getInputsOrThrow('getSession', ['data', 'nonce', 'phantom_encryption_public_key'], ['encryptionSecretKey']);
|
|
56
|
+
const sharedSecret = nacl__default["default"].box.before(bs58__default["default"].decode(phantomEncryptionPublicKey), encryptionSecretKey);
|
|
57
|
+
storage.storage.sharedSecret.set(sharedSecret);
|
|
58
|
+
const connectData = utils.decryptPayload(data, nonce, sharedSecret);
|
|
59
|
+
storage.storage.session.set(connectData.session);
|
|
60
|
+
storage.storage.address.set(new web3_js.PublicKey(connectData.public_key));
|
|
61
|
+
params.delete('phantom_encryption_public_key');
|
|
62
|
+
params.delete('data');
|
|
63
|
+
params.delete('nonce');
|
|
64
|
+
history.replaceState(null, '', `${window.location.origin}${window.location.pathname}?${params.toString()}`);
|
|
65
|
+
return connectData.public_key;
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
signMessage(messageToSign) {
|
|
69
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
70
|
+
const { session, sharedSecret, encryptionPublicKey } = this.getInputsOrThrow('signMessage', [], ['session', 'sharedSecret', 'encryptionPublicKey']);
|
|
71
|
+
storage.storage.message.set(messageToSign);
|
|
72
|
+
const payload = {
|
|
73
|
+
message: bs58__default["default"].encode(Buffer.from(messageToSign)),
|
|
74
|
+
session,
|
|
75
|
+
};
|
|
76
|
+
const [nonce, encryptedPayload] = utils.encryptPayload(payload, sharedSecret);
|
|
77
|
+
const params = new URLSearchParams({
|
|
78
|
+
dapp_encryption_public_key: bs58__default["default"].encode(encryptionPublicKey),
|
|
79
|
+
nonce: bs58__default["default"].encode(nonce),
|
|
80
|
+
payload: bs58__default["default"].encode(encryptedPayload),
|
|
81
|
+
redirect_link: window.location.href,
|
|
82
|
+
});
|
|
83
|
+
const url = utils.buildUrl('signMessage', params);
|
|
84
|
+
window.location.href = url;
|
|
85
|
+
// throwing this to prevent local storage from being cleared.
|
|
86
|
+
// when verifying signature, the SDK calls endSession when no
|
|
87
|
+
// signature is returned. in the case of phantom mobile, a signature
|
|
88
|
+
// is not returned from signMessage, so an error will always be thrown.
|
|
89
|
+
// this is a workaround to prevent the SDK from clearing local storage
|
|
90
|
+
// ideally we would figure out how to:
|
|
91
|
+
// 1. kick off the sign message on one tab
|
|
92
|
+
// 2. resume the process on that tab after the user signs in phantom
|
|
93
|
+
throw new Error('ignore');
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
extractSignature() {
|
|
97
|
+
const params = new URLSearchParams(window.location.search);
|
|
98
|
+
const { data, nonce, sharedSecret, message } = this.getInputsOrThrow('extractSignature', ['data', 'nonce'], ['sharedSecret', 'message']);
|
|
99
|
+
const signMessageData = utils.decryptPayload(data, nonce, sharedSecret);
|
|
100
|
+
params.delete('data');
|
|
101
|
+
params.delete('nonce');
|
|
102
|
+
history.replaceState(null, '', `${window.location.origin}${window.location.pathname}?${params.toString()}`);
|
|
103
|
+
return {
|
|
104
|
+
message,
|
|
105
|
+
signature: signMessageData.signature,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
getSigner() {
|
|
109
|
+
return Promise.resolve(undefined);
|
|
110
|
+
}
|
|
111
|
+
getConnectedAccounts() {
|
|
112
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
113
|
+
const address = storage.storage.address.get();
|
|
114
|
+
return address ? [address] : [];
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
endSession() {
|
|
118
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
119
|
+
// for establishing the shared secret. NOT the wallet address
|
|
120
|
+
storage.storage.address.remove();
|
|
121
|
+
storage.storage.encryptionPublicKey.remove();
|
|
122
|
+
storage.storage.encryptionSecretKey.remove();
|
|
123
|
+
storage.storage.message.remove();
|
|
124
|
+
storage.storage.session.remove();
|
|
125
|
+
storage.storage.sharedSecret.remove();
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Helper method to get inputs from query params and localstorage
|
|
130
|
+
*
|
|
131
|
+
* The second argument is used to read values from the query string
|
|
132
|
+
* e.g. ['data', 'nonce'] -> params.get('data') and params.get('nonce')
|
|
133
|
+
*
|
|
134
|
+
* The third argument is used to read values from local storage
|
|
135
|
+
* e.g. ['address', 'message'] -> storage.address.get() and storage.message.get()
|
|
136
|
+
*
|
|
137
|
+
* Throws an error if any of the inputs are unable to be found in their respective locations
|
|
138
|
+
*/
|
|
139
|
+
getInputsOrThrow(methodName, queryParams, storageParams) {
|
|
140
|
+
const inputs = {};
|
|
141
|
+
const queryString = new URLSearchParams(window.location.search);
|
|
142
|
+
queryParams.forEach((param) => {
|
|
143
|
+
const value = queryString.get(param);
|
|
144
|
+
if (!value) {
|
|
145
|
+
throw new Error(`[PhantomRedirect] ${methodName} called, but required input '${param}' not found in query params`);
|
|
146
|
+
}
|
|
147
|
+
inputs[param] = value;
|
|
148
|
+
});
|
|
149
|
+
storageParams.forEach((storageParam) => {
|
|
150
|
+
const value = storage.storage[storageParam].get();
|
|
151
|
+
if (!value) {
|
|
152
|
+
throw new Error(`[PhantomRedirect] ${methodName} called, but required input '${storageParam}' not found in local storage`);
|
|
153
|
+
}
|
|
154
|
+
inputs[storageParam] = value;
|
|
155
|
+
});
|
|
156
|
+
return inputs;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
exports.PhantomRedirect = PhantomRedirect;
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { __awaiter } from '../../_virtual/_tslib.js';
|
|
2
|
+
import nacl from 'tweetnacl';
|
|
3
|
+
import bs58 from 'bs58';
|
|
4
|
+
import { PublicKey } from '@solana/web3.js';
|
|
5
|
+
import { SolWalletConnector } from '../solWalletConnector.js';
|
|
6
|
+
import { buildUrl, decryptPayload, encryptPayload } from './utils.js';
|
|
7
|
+
import { storage } from './storage.js';
|
|
8
|
+
|
|
9
|
+
class PhantomRedirect extends SolWalletConnector {
|
|
10
|
+
constructor(props) {
|
|
11
|
+
super(Object.assign({}, props));
|
|
12
|
+
this.name = 'Phantom';
|
|
13
|
+
}
|
|
14
|
+
fetchPublicAddress() {
|
|
15
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
16
|
+
const address = storage.address.get();
|
|
17
|
+
if (address) {
|
|
18
|
+
return address;
|
|
19
|
+
}
|
|
20
|
+
yield this.connect();
|
|
21
|
+
return undefined;
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
connect() {
|
|
25
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26
|
+
// Generate a new key pair
|
|
27
|
+
const keyPair = nacl.box.keyPair();
|
|
28
|
+
storage.encryptionPublicKey.set(keyPair.publicKey);
|
|
29
|
+
storage.encryptionSecretKey.set(keyPair.secretKey);
|
|
30
|
+
const isLocalHost = window.location.href.includes('localhost') ||
|
|
31
|
+
window.location.href.includes('0.0.0.0') ||
|
|
32
|
+
window.location.href.includes('127.0.0.1');
|
|
33
|
+
const params = new URLSearchParams({
|
|
34
|
+
app_url: isLocalHost ? 'https://demo.dynamic.xyz' : window.location.href,
|
|
35
|
+
cluster: 'mainnet-beta',
|
|
36
|
+
dapp_encryption_public_key: bs58.encode(keyPair.publicKey),
|
|
37
|
+
redirect_link: window.location.href,
|
|
38
|
+
});
|
|
39
|
+
const url = buildUrl('connect', params);
|
|
40
|
+
window.location.href = url;
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
getSession() {
|
|
44
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
45
|
+
const params = new URLSearchParams(window.location.search);
|
|
46
|
+
const { data, nonce, phantom_encryption_public_key: phantomEncryptionPublicKey, encryptionSecretKey, } = this.getInputsOrThrow('getSession', ['data', 'nonce', 'phantom_encryption_public_key'], ['encryptionSecretKey']);
|
|
47
|
+
const sharedSecret = nacl.box.before(bs58.decode(phantomEncryptionPublicKey), encryptionSecretKey);
|
|
48
|
+
storage.sharedSecret.set(sharedSecret);
|
|
49
|
+
const connectData = decryptPayload(data, nonce, sharedSecret);
|
|
50
|
+
storage.session.set(connectData.session);
|
|
51
|
+
storage.address.set(new PublicKey(connectData.public_key));
|
|
52
|
+
params.delete('phantom_encryption_public_key');
|
|
53
|
+
params.delete('data');
|
|
54
|
+
params.delete('nonce');
|
|
55
|
+
history.replaceState(null, '', `${window.location.origin}${window.location.pathname}?${params.toString()}`);
|
|
56
|
+
return connectData.public_key;
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
signMessage(messageToSign) {
|
|
60
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
61
|
+
const { session, sharedSecret, encryptionPublicKey } = this.getInputsOrThrow('signMessage', [], ['session', 'sharedSecret', 'encryptionPublicKey']);
|
|
62
|
+
storage.message.set(messageToSign);
|
|
63
|
+
const payload = {
|
|
64
|
+
message: bs58.encode(Buffer.from(messageToSign)),
|
|
65
|
+
session,
|
|
66
|
+
};
|
|
67
|
+
const [nonce, encryptedPayload] = encryptPayload(payload, sharedSecret);
|
|
68
|
+
const params = new URLSearchParams({
|
|
69
|
+
dapp_encryption_public_key: bs58.encode(encryptionPublicKey),
|
|
70
|
+
nonce: bs58.encode(nonce),
|
|
71
|
+
payload: bs58.encode(encryptedPayload),
|
|
72
|
+
redirect_link: window.location.href,
|
|
73
|
+
});
|
|
74
|
+
const url = buildUrl('signMessage', params);
|
|
75
|
+
window.location.href = url;
|
|
76
|
+
// throwing this to prevent local storage from being cleared.
|
|
77
|
+
// when verifying signature, the SDK calls endSession when no
|
|
78
|
+
// signature is returned. in the case of phantom mobile, a signature
|
|
79
|
+
// is not returned from signMessage, so an error will always be thrown.
|
|
80
|
+
// this is a workaround to prevent the SDK from clearing local storage
|
|
81
|
+
// ideally we would figure out how to:
|
|
82
|
+
// 1. kick off the sign message on one tab
|
|
83
|
+
// 2. resume the process on that tab after the user signs in phantom
|
|
84
|
+
throw new Error('ignore');
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
extractSignature() {
|
|
88
|
+
const params = new URLSearchParams(window.location.search);
|
|
89
|
+
const { data, nonce, sharedSecret, message } = this.getInputsOrThrow('extractSignature', ['data', 'nonce'], ['sharedSecret', 'message']);
|
|
90
|
+
const signMessageData = decryptPayload(data, nonce, sharedSecret);
|
|
91
|
+
params.delete('data');
|
|
92
|
+
params.delete('nonce');
|
|
93
|
+
history.replaceState(null, '', `${window.location.origin}${window.location.pathname}?${params.toString()}`);
|
|
94
|
+
return {
|
|
95
|
+
message,
|
|
96
|
+
signature: signMessageData.signature,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
getSigner() {
|
|
100
|
+
return Promise.resolve(undefined);
|
|
101
|
+
}
|
|
102
|
+
getConnectedAccounts() {
|
|
103
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
104
|
+
const address = storage.address.get();
|
|
105
|
+
return address ? [address] : [];
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
endSession() {
|
|
109
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
110
|
+
// for establishing the shared secret. NOT the wallet address
|
|
111
|
+
storage.address.remove();
|
|
112
|
+
storage.encryptionPublicKey.remove();
|
|
113
|
+
storage.encryptionSecretKey.remove();
|
|
114
|
+
storage.message.remove();
|
|
115
|
+
storage.session.remove();
|
|
116
|
+
storage.sharedSecret.remove();
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Helper method to get inputs from query params and localstorage
|
|
121
|
+
*
|
|
122
|
+
* The second argument is used to read values from the query string
|
|
123
|
+
* e.g. ['data', 'nonce'] -> params.get('data') and params.get('nonce')
|
|
124
|
+
*
|
|
125
|
+
* The third argument is used to read values from local storage
|
|
126
|
+
* e.g. ['address', 'message'] -> storage.address.get() and storage.message.get()
|
|
127
|
+
*
|
|
128
|
+
* Throws an error if any of the inputs are unable to be found in their respective locations
|
|
129
|
+
*/
|
|
130
|
+
getInputsOrThrow(methodName, queryParams, storageParams) {
|
|
131
|
+
const inputs = {};
|
|
132
|
+
const queryString = new URLSearchParams(window.location.search);
|
|
133
|
+
queryParams.forEach((param) => {
|
|
134
|
+
const value = queryString.get(param);
|
|
135
|
+
if (!value) {
|
|
136
|
+
throw new Error(`[PhantomRedirect] ${methodName} called, but required input '${param}' not found in query params`);
|
|
137
|
+
}
|
|
138
|
+
inputs[param] = value;
|
|
139
|
+
});
|
|
140
|
+
storageParams.forEach((storageParam) => {
|
|
141
|
+
const value = storage[storageParam].get();
|
|
142
|
+
if (!value) {
|
|
143
|
+
throw new Error(`[PhantomRedirect] ${methodName} called, but required input '${storageParam}' not found in local storage`);
|
|
144
|
+
}
|
|
145
|
+
inputs[storageParam] = value;
|
|
146
|
+
});
|
|
147
|
+
return inputs;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export { PhantomRedirect };
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
const storage = {
|
|
6
|
+
address: {
|
|
7
|
+
get: () => { var _a; return (_a = localStorage.getItem('dynamic_phantom_wallet_address')) !== null && _a !== void 0 ? _a : undefined; },
|
|
8
|
+
remove: () => {
|
|
9
|
+
localStorage.removeItem('dynamic_phantom_wallet_address');
|
|
10
|
+
},
|
|
11
|
+
set: (address) => {
|
|
12
|
+
localStorage.setItem('dynamic_phantom_wallet_address', address.toString());
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
encryptionPublicKey: {
|
|
16
|
+
get: () => {
|
|
17
|
+
const rawPublicKey = localStorage.getItem('dynamic_phantom_public_key');
|
|
18
|
+
if (!rawPublicKey) {
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
return new Uint8Array(JSON.parse(rawPublicKey));
|
|
22
|
+
},
|
|
23
|
+
remove: () => {
|
|
24
|
+
localStorage.removeItem('dynamic_phantom_public_key');
|
|
25
|
+
},
|
|
26
|
+
set: (publicKey) => {
|
|
27
|
+
localStorage.setItem('dynamic_phantom_public_key', JSON.stringify([...publicKey]));
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
encryptionSecretKey: {
|
|
31
|
+
get: () => {
|
|
32
|
+
const rawSecretKey = localStorage.getItem('dynamic_phantom_secret_key');
|
|
33
|
+
if (!rawSecretKey) {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
return new Uint8Array(JSON.parse(rawSecretKey));
|
|
37
|
+
},
|
|
38
|
+
remove: () => {
|
|
39
|
+
localStorage.removeItem('dynamic_phantom_secret_key');
|
|
40
|
+
},
|
|
41
|
+
set: (secretKey) => {
|
|
42
|
+
localStorage.setItem('dynamic_phantom_secret_key', JSON.stringify([...secretKey]));
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
message: {
|
|
46
|
+
get: () => { var _a; return (_a = localStorage.getItem('dynamic_phantom_message_to_sign')) !== null && _a !== void 0 ? _a : undefined; },
|
|
47
|
+
remove: () => {
|
|
48
|
+
localStorage.removeItem('dynamic_phantom_message_to_sign');
|
|
49
|
+
},
|
|
50
|
+
set: (message) => {
|
|
51
|
+
localStorage.setItem('dynamic_phantom_message_to_sign', message);
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
session: {
|
|
55
|
+
get: () => { var _a; return (_a = localStorage.getItem('dynamic_phantom_session')) !== null && _a !== void 0 ? _a : undefined; },
|
|
56
|
+
remove: () => {
|
|
57
|
+
localStorage.removeItem('dynamic_phantom_session');
|
|
58
|
+
},
|
|
59
|
+
set: (session) => {
|
|
60
|
+
localStorage.setItem('dynamic_phantom_session', session);
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
sharedSecret: {
|
|
64
|
+
get: () => {
|
|
65
|
+
const rawSharedSecret = localStorage.getItem('dynamic_phantom_shared_secret');
|
|
66
|
+
if (!rawSharedSecret) {
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
return new Uint8Array(JSON.parse(rawSharedSecret));
|
|
70
|
+
},
|
|
71
|
+
remove: () => {
|
|
72
|
+
localStorage.removeItem('dynamic_phantom_shared_secret');
|
|
73
|
+
},
|
|
74
|
+
set: (sharedSecret) => {
|
|
75
|
+
localStorage.setItem('dynamic_phantom_shared_secret', JSON.stringify([...sharedSecret]));
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
exports.storage = storage;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
const storage = {
|
|
2
|
+
address: {
|
|
3
|
+
get: () => { var _a; return (_a = localStorage.getItem('dynamic_phantom_wallet_address')) !== null && _a !== void 0 ? _a : undefined; },
|
|
4
|
+
remove: () => {
|
|
5
|
+
localStorage.removeItem('dynamic_phantom_wallet_address');
|
|
6
|
+
},
|
|
7
|
+
set: (address) => {
|
|
8
|
+
localStorage.setItem('dynamic_phantom_wallet_address', address.toString());
|
|
9
|
+
},
|
|
10
|
+
},
|
|
11
|
+
encryptionPublicKey: {
|
|
12
|
+
get: () => {
|
|
13
|
+
const rawPublicKey = localStorage.getItem('dynamic_phantom_public_key');
|
|
14
|
+
if (!rawPublicKey) {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
return new Uint8Array(JSON.parse(rawPublicKey));
|
|
18
|
+
},
|
|
19
|
+
remove: () => {
|
|
20
|
+
localStorage.removeItem('dynamic_phantom_public_key');
|
|
21
|
+
},
|
|
22
|
+
set: (publicKey) => {
|
|
23
|
+
localStorage.setItem('dynamic_phantom_public_key', JSON.stringify([...publicKey]));
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
encryptionSecretKey: {
|
|
27
|
+
get: () => {
|
|
28
|
+
const rawSecretKey = localStorage.getItem('dynamic_phantom_secret_key');
|
|
29
|
+
if (!rawSecretKey) {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
return new Uint8Array(JSON.parse(rawSecretKey));
|
|
33
|
+
},
|
|
34
|
+
remove: () => {
|
|
35
|
+
localStorage.removeItem('dynamic_phantom_secret_key');
|
|
36
|
+
},
|
|
37
|
+
set: (secretKey) => {
|
|
38
|
+
localStorage.setItem('dynamic_phantom_secret_key', JSON.stringify([...secretKey]));
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
message: {
|
|
42
|
+
get: () => { var _a; return (_a = localStorage.getItem('dynamic_phantom_message_to_sign')) !== null && _a !== void 0 ? _a : undefined; },
|
|
43
|
+
remove: () => {
|
|
44
|
+
localStorage.removeItem('dynamic_phantom_message_to_sign');
|
|
45
|
+
},
|
|
46
|
+
set: (message) => {
|
|
47
|
+
localStorage.setItem('dynamic_phantom_message_to_sign', message);
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
session: {
|
|
51
|
+
get: () => { var _a; return (_a = localStorage.getItem('dynamic_phantom_session')) !== null && _a !== void 0 ? _a : undefined; },
|
|
52
|
+
remove: () => {
|
|
53
|
+
localStorage.removeItem('dynamic_phantom_session');
|
|
54
|
+
},
|
|
55
|
+
set: (session) => {
|
|
56
|
+
localStorage.setItem('dynamic_phantom_session', session);
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
sharedSecret: {
|
|
60
|
+
get: () => {
|
|
61
|
+
const rawSharedSecret = localStorage.getItem('dynamic_phantom_shared_secret');
|
|
62
|
+
if (!rawSharedSecret) {
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
return new Uint8Array(JSON.parse(rawSharedSecret));
|
|
66
|
+
},
|
|
67
|
+
remove: () => {
|
|
68
|
+
localStorage.removeItem('dynamic_phantom_shared_secret');
|
|
69
|
+
},
|
|
70
|
+
set: (sharedSecret) => {
|
|
71
|
+
localStorage.setItem('dynamic_phantom_shared_secret', JSON.stringify([...sharedSecret]));
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export { storage };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var nacl = require('tweetnacl');
|
|
6
|
+
var bs58 = require('bs58');
|
|
7
|
+
|
|
8
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
9
|
+
|
|
10
|
+
var nacl__default = /*#__PURE__*/_interopDefaultLegacy(nacl);
|
|
11
|
+
var bs58__default = /*#__PURE__*/_interopDefaultLegacy(bs58);
|
|
12
|
+
|
|
13
|
+
const buildUrl = (path, params) => `https://phantom.app/ul/v1/${path}?${params.toString()}`;
|
|
14
|
+
const decryptPayload = (data, nonce, sharedSecret) => {
|
|
15
|
+
const decryptedData = nacl__default["default"].box.open.after(bs58__default["default"].decode(data), bs58__default["default"].decode(nonce), sharedSecret);
|
|
16
|
+
if (!decryptedData) {
|
|
17
|
+
throw new Error('Unable to decrypt data');
|
|
18
|
+
}
|
|
19
|
+
return JSON.parse(Buffer.from(decryptedData).toString('utf8'));
|
|
20
|
+
};
|
|
21
|
+
const encryptPayload = (payload, sharedSecret) => {
|
|
22
|
+
const nonce = nacl__default["default"].randomBytes(24);
|
|
23
|
+
const encryptedPayload = nacl__default["default"].box.after(Buffer.from(JSON.stringify(payload)), nonce, sharedSecret);
|
|
24
|
+
return [nonce, encryptedPayload];
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
exports.buildUrl = buildUrl;
|
|
28
|
+
exports.decryptPayload = decryptPayload;
|
|
29
|
+
exports.encryptPayload = encryptPayload;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import nacl from 'tweetnacl';
|
|
2
|
+
import bs58 from 'bs58';
|
|
3
|
+
|
|
4
|
+
const buildUrl = (path, params) => `https://phantom.app/ul/v1/${path}?${params.toString()}`;
|
|
5
|
+
const decryptPayload = (data, nonce, sharedSecret) => {
|
|
6
|
+
const decryptedData = nacl.box.open.after(bs58.decode(data), bs58.decode(nonce), sharedSecret);
|
|
7
|
+
if (!decryptedData) {
|
|
8
|
+
throw new Error('Unable to decrypt data');
|
|
9
|
+
}
|
|
10
|
+
return JSON.parse(Buffer.from(decryptedData).toString('utf8'));
|
|
11
|
+
};
|
|
12
|
+
const encryptPayload = (payload, sharedSecret) => {
|
|
13
|
+
const nonce = nacl.randomBytes(24);
|
|
14
|
+
const encryptedPayload = nacl.box.after(Buffer.from(JSON.stringify(payload)), nonce, sharedSecret);
|
|
15
|
+
return [nonce, encryptedPayload];
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export { buildUrl, decryptPayload, encryptPayload };
|