@phantom/react-native-sdk 1.0.4 → 1.0.5
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/dist/index.js +43 -35
- package/dist/index.mjs +43 -36
- package/package.json +11 -11
package/dist/index.js
CHANGED
|
@@ -557,7 +557,7 @@ var ExpoAuthProvider = class {
|
|
|
557
557
|
// OAuth session management - defaults to allow refresh unless explicitly clearing after logout
|
|
558
558
|
clear_previous_session: (phantomOptions.clearPreviousSession ?? false).toString(),
|
|
559
559
|
allow_refresh: (phantomOptions.allowRefresh ?? true).toString(),
|
|
560
|
-
sdk_version: "1.0.
|
|
560
|
+
sdk_version: "1.0.5",
|
|
561
561
|
sdk_type: "react-native",
|
|
562
562
|
platform: import_react_native5.Platform.OS
|
|
563
563
|
});
|
|
@@ -657,7 +657,6 @@ var ExpoAuth2AuthProvider = class {
|
|
|
657
657
|
throw new Error("Stamper key pair not found.");
|
|
658
658
|
}
|
|
659
659
|
const codeVerifier = (0, import_auth2.createCodeVerifier)();
|
|
660
|
-
const salt = (0, import_auth2.createSalt)();
|
|
661
660
|
const url = await (0, import_auth2.createConnectStartUrl)({
|
|
662
661
|
keyPair,
|
|
663
662
|
connectLoginUrl: this.auth2ProviderOptions.connectLoginUrl,
|
|
@@ -666,7 +665,8 @@ var ExpoAuth2AuthProvider = class {
|
|
|
666
665
|
sessionId: options.sessionId,
|
|
667
666
|
provider: options.provider,
|
|
668
667
|
codeVerifier,
|
|
669
|
-
salt
|
|
668
|
+
// The P-256 ephemeral key is unique per wallet, so no additional salt is needed.
|
|
669
|
+
salt: ""
|
|
670
670
|
});
|
|
671
671
|
await WebBrowser2.warmUpAsync();
|
|
672
672
|
let result;
|
|
@@ -699,8 +699,7 @@ var ExpoAuth2AuthProvider = class {
|
|
|
699
699
|
code,
|
|
700
700
|
codeVerifier
|
|
701
701
|
});
|
|
702
|
-
this.stamper.idToken
|
|
703
|
-
this.stamper.salt = salt;
|
|
702
|
+
await this.stamper.setIdToken(idToken);
|
|
704
703
|
const { organizationId, walletId } = await this.kms.discoverOrganizationAndWalletId(bearerToken, authUserId);
|
|
705
704
|
return {
|
|
706
705
|
walletId,
|
|
@@ -728,18 +727,23 @@ var ExpoAuth2Stamper = class {
|
|
|
728
727
|
*/
|
|
729
728
|
constructor(storageKey) {
|
|
730
729
|
this.storageKey = storageKey;
|
|
731
|
-
this.
|
|
732
|
-
this.publicKey = null;
|
|
730
|
+
this._keyPair = null;
|
|
733
731
|
this._keyInfo = null;
|
|
732
|
+
this._idToken = null;
|
|
734
733
|
this.algorithm = import_sdk_types.Algorithm.secp256r1;
|
|
735
734
|
this.type = "OIDC";
|
|
736
735
|
}
|
|
737
736
|
async init() {
|
|
738
737
|
const stored = await this.loadRecord();
|
|
739
738
|
if (stored) {
|
|
740
|
-
this.
|
|
741
|
-
|
|
739
|
+
this._keyPair = {
|
|
740
|
+
privateKey: await this.importPrivateKey(stored.privateKeyPkcs8),
|
|
741
|
+
publicKey: await this.importPublicKeyFromBase58(stored.keyInfo.publicKey)
|
|
742
|
+
};
|
|
742
743
|
this._keyInfo = stored.keyInfo;
|
|
744
|
+
if (stored.idToken) {
|
|
745
|
+
this._idToken = stored.idToken;
|
|
746
|
+
}
|
|
743
747
|
return this._keyInfo;
|
|
744
748
|
}
|
|
745
749
|
return this.generateAndStore();
|
|
@@ -748,45 +752,51 @@ var ExpoAuth2Stamper = class {
|
|
|
748
752
|
return this._keyInfo;
|
|
749
753
|
}
|
|
750
754
|
getCryptoKeyPair() {
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
755
|
+
return this._keyPair;
|
|
756
|
+
}
|
|
757
|
+
/**
|
|
758
|
+
* Arms the stamper with the OIDC id token for subsequent KMS stamp() calls.
|
|
759
|
+
*
|
|
760
|
+
* Persists the token to SecureStore alongside the key pair so that
|
|
761
|
+
* auto-connect can restore it on the next app launch without a new login.
|
|
762
|
+
*/
|
|
763
|
+
async setIdToken(idToken) {
|
|
764
|
+
this._idToken = idToken;
|
|
765
|
+
const existing = await this.loadRecord();
|
|
766
|
+
if (existing) {
|
|
767
|
+
await this.storeRecord({ ...existing, idToken });
|
|
768
|
+
}
|
|
754
769
|
}
|
|
755
770
|
async stamp(params) {
|
|
756
|
-
if (!this.
|
|
771
|
+
if (!this._keyPair || !this._keyInfo || this._idToken === null) {
|
|
757
772
|
throw new Error("ExpoAuth2Stamper not initialized. Call init() first.");
|
|
758
773
|
}
|
|
759
774
|
const signatureRaw = await crypto.subtle.sign(
|
|
760
775
|
{ name: "ECDSA", hash: "SHA-256" },
|
|
761
|
-
this.privateKey,
|
|
776
|
+
this._keyPair.privateKey,
|
|
762
777
|
new Uint8Array(params.data)
|
|
763
778
|
);
|
|
764
779
|
const rawPublicKey = import_bs58.default.decode(this._keyInfo.publicKey);
|
|
765
|
-
if (this.idToken === void 0 || this.salt === void 0) {
|
|
766
|
-
throw new Error("ExpoAuth2Stamper not initialized with idToken or salt.");
|
|
767
|
-
}
|
|
768
780
|
const stampData = {
|
|
769
|
-
kind:
|
|
770
|
-
idToken: this.
|
|
781
|
+
kind: this.type,
|
|
782
|
+
idToken: this._idToken,
|
|
771
783
|
publicKey: (0, import_base64url.base64urlEncode)(rawPublicKey),
|
|
772
|
-
algorithm:
|
|
773
|
-
salt
|
|
784
|
+
algorithm: this.algorithm,
|
|
785
|
+
// The P-256 ephemeral key is unique per wallet, so no additional salt is needed.
|
|
786
|
+
salt: "",
|
|
774
787
|
signature: (0, import_base64url.base64urlEncode)(new Uint8Array(signatureRaw))
|
|
775
788
|
};
|
|
776
789
|
return (0, import_base64url.base64urlEncode)(new TextEncoder().encode(JSON.stringify(stampData)));
|
|
777
790
|
}
|
|
778
791
|
async resetKeyPair() {
|
|
779
|
-
await this.
|
|
780
|
-
this.privateKey = null;
|
|
781
|
-
this.publicKey = null;
|
|
782
|
-
this._keyInfo = null;
|
|
792
|
+
await this.clear();
|
|
783
793
|
return this.generateAndStore();
|
|
784
794
|
}
|
|
785
795
|
async clear() {
|
|
786
796
|
await this.clearStoredRecord();
|
|
787
|
-
this.
|
|
788
|
-
this.publicKey = null;
|
|
797
|
+
this._keyPair = null;
|
|
789
798
|
this._keyInfo = null;
|
|
799
|
+
this._idToken = null;
|
|
790
800
|
}
|
|
791
801
|
// Auth2 doesn't use key rotation; minimal no-op implementations.
|
|
792
802
|
async rotateKeyPair() {
|
|
@@ -811,16 +821,11 @@ var ExpoAuth2Stamper = class {
|
|
|
811
821
|
const publicKeyBase58 = import_bs58.default.encode(rawPublicKey);
|
|
812
822
|
const keyIdBuffer = await crypto.subtle.digest("SHA-256", rawPublicKey.buffer);
|
|
813
823
|
const keyId = (0, import_base64url.base64urlEncode)(new Uint8Array(keyIdBuffer)).substring(0, 16);
|
|
824
|
+
this._keyPair = keyPair;
|
|
814
825
|
this._keyInfo = { keyId, publicKey: publicKeyBase58, createdAt: Date.now() };
|
|
815
826
|
const pkcs8Buffer = await crypto.subtle.exportKey("pkcs8", keyPair.privateKey);
|
|
816
827
|
const privateKeyPkcs8 = import_buffer.Buffer.from(pkcs8Buffer).toString("base64");
|
|
817
|
-
await
|
|
818
|
-
this.storageKey,
|
|
819
|
-
JSON.stringify({ privateKeyPkcs8, keyInfo: this._keyInfo }),
|
|
820
|
-
{ requireAuthentication: false }
|
|
821
|
-
);
|
|
822
|
-
this.privateKey = await this.importPrivateKey(privateKeyPkcs8);
|
|
823
|
-
this.publicKey = keyPair.publicKey;
|
|
828
|
+
await this.storeRecord({ privateKeyPkcs8, keyInfo: this._keyInfo });
|
|
824
829
|
return this._keyInfo;
|
|
825
830
|
}
|
|
826
831
|
async importPublicKeyFromBase58(base58PublicKey) {
|
|
@@ -853,6 +858,9 @@ var ExpoAuth2Stamper = class {
|
|
|
853
858
|
return null;
|
|
854
859
|
}
|
|
855
860
|
}
|
|
861
|
+
async storeRecord(record) {
|
|
862
|
+
await SecureStore2.setItemAsync(this.storageKey, JSON.stringify(record), { requireAuthentication: false });
|
|
863
|
+
}
|
|
856
864
|
async clearStoredRecord() {
|
|
857
865
|
try {
|
|
858
866
|
await SecureStore2.deleteItemAsync(this.storageKey);
|
|
@@ -1203,7 +1211,7 @@ function PhantomProvider({ children, config, debugConfig, theme, appIcon, appNam
|
|
|
1203
1211
|
[import_constants3.ANALYTICS_HEADERS.CLIENT]: import_react_native7.Platform.OS,
|
|
1204
1212
|
[import_constants3.ANALYTICS_HEADERS.APP_ID]: config.appId,
|
|
1205
1213
|
[import_constants3.ANALYTICS_HEADERS.WALLET_TYPE]: config.embeddedWalletType,
|
|
1206
|
-
[import_constants3.ANALYTICS_HEADERS.SDK_VERSION]: "1.0.
|
|
1214
|
+
[import_constants3.ANALYTICS_HEADERS.SDK_VERSION]: "1.0.5"
|
|
1207
1215
|
// Replaced at build time
|
|
1208
1216
|
}
|
|
1209
1217
|
};
|
package/dist/index.mjs
CHANGED
|
@@ -515,7 +515,7 @@ var ExpoAuthProvider = class {
|
|
|
515
515
|
// OAuth session management - defaults to allow refresh unless explicitly clearing after logout
|
|
516
516
|
clear_previous_session: (phantomOptions.clearPreviousSession ?? false).toString(),
|
|
517
517
|
allow_refresh: (phantomOptions.allowRefresh ?? true).toString(),
|
|
518
|
-
sdk_version: "1.0.
|
|
518
|
+
sdk_version: "1.0.5",
|
|
519
519
|
sdk_type: "react-native",
|
|
520
520
|
platform: Platform.OS
|
|
521
521
|
});
|
|
@@ -594,7 +594,6 @@ var ExpoAuthProvider = class {
|
|
|
594
594
|
import * as WebBrowser2 from "expo-web-browser";
|
|
595
595
|
import {
|
|
596
596
|
createCodeVerifier,
|
|
597
|
-
createSalt,
|
|
598
597
|
exchangeAuthCode,
|
|
599
598
|
Auth2KmsRpcClient,
|
|
600
599
|
createConnectStartUrl
|
|
@@ -621,7 +620,6 @@ var ExpoAuth2AuthProvider = class {
|
|
|
621
620
|
throw new Error("Stamper key pair not found.");
|
|
622
621
|
}
|
|
623
622
|
const codeVerifier = createCodeVerifier();
|
|
624
|
-
const salt = createSalt();
|
|
625
623
|
const url = await createConnectStartUrl({
|
|
626
624
|
keyPair,
|
|
627
625
|
connectLoginUrl: this.auth2ProviderOptions.connectLoginUrl,
|
|
@@ -630,7 +628,8 @@ var ExpoAuth2AuthProvider = class {
|
|
|
630
628
|
sessionId: options.sessionId,
|
|
631
629
|
provider: options.provider,
|
|
632
630
|
codeVerifier,
|
|
633
|
-
salt
|
|
631
|
+
// The P-256 ephemeral key is unique per wallet, so no additional salt is needed.
|
|
632
|
+
salt: ""
|
|
634
633
|
});
|
|
635
634
|
await WebBrowser2.warmUpAsync();
|
|
636
635
|
let result;
|
|
@@ -663,8 +662,7 @@ var ExpoAuth2AuthProvider = class {
|
|
|
663
662
|
code,
|
|
664
663
|
codeVerifier
|
|
665
664
|
});
|
|
666
|
-
this.stamper.idToken
|
|
667
|
-
this.stamper.salt = salt;
|
|
665
|
+
await this.stamper.setIdToken(idToken);
|
|
668
666
|
const { organizationId, walletId } = await this.kms.discoverOrganizationAndWalletId(bearerToken, authUserId);
|
|
669
667
|
return {
|
|
670
668
|
walletId,
|
|
@@ -692,18 +690,23 @@ var ExpoAuth2Stamper = class {
|
|
|
692
690
|
*/
|
|
693
691
|
constructor(storageKey) {
|
|
694
692
|
this.storageKey = storageKey;
|
|
695
|
-
this.
|
|
696
|
-
this.publicKey = null;
|
|
693
|
+
this._keyPair = null;
|
|
697
694
|
this._keyInfo = null;
|
|
695
|
+
this._idToken = null;
|
|
698
696
|
this.algorithm = Algorithm.secp256r1;
|
|
699
697
|
this.type = "OIDC";
|
|
700
698
|
}
|
|
701
699
|
async init() {
|
|
702
700
|
const stored = await this.loadRecord();
|
|
703
701
|
if (stored) {
|
|
704
|
-
this.
|
|
705
|
-
|
|
702
|
+
this._keyPair = {
|
|
703
|
+
privateKey: await this.importPrivateKey(stored.privateKeyPkcs8),
|
|
704
|
+
publicKey: await this.importPublicKeyFromBase58(stored.keyInfo.publicKey)
|
|
705
|
+
};
|
|
706
706
|
this._keyInfo = stored.keyInfo;
|
|
707
|
+
if (stored.idToken) {
|
|
708
|
+
this._idToken = stored.idToken;
|
|
709
|
+
}
|
|
707
710
|
return this._keyInfo;
|
|
708
711
|
}
|
|
709
712
|
return this.generateAndStore();
|
|
@@ -712,45 +715,51 @@ var ExpoAuth2Stamper = class {
|
|
|
712
715
|
return this._keyInfo;
|
|
713
716
|
}
|
|
714
717
|
getCryptoKeyPair() {
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
+
return this._keyPair;
|
|
719
|
+
}
|
|
720
|
+
/**
|
|
721
|
+
* Arms the stamper with the OIDC id token for subsequent KMS stamp() calls.
|
|
722
|
+
*
|
|
723
|
+
* Persists the token to SecureStore alongside the key pair so that
|
|
724
|
+
* auto-connect can restore it on the next app launch without a new login.
|
|
725
|
+
*/
|
|
726
|
+
async setIdToken(idToken) {
|
|
727
|
+
this._idToken = idToken;
|
|
728
|
+
const existing = await this.loadRecord();
|
|
729
|
+
if (existing) {
|
|
730
|
+
await this.storeRecord({ ...existing, idToken });
|
|
731
|
+
}
|
|
718
732
|
}
|
|
719
733
|
async stamp(params) {
|
|
720
|
-
if (!this.
|
|
734
|
+
if (!this._keyPair || !this._keyInfo || this._idToken === null) {
|
|
721
735
|
throw new Error("ExpoAuth2Stamper not initialized. Call init() first.");
|
|
722
736
|
}
|
|
723
737
|
const signatureRaw = await crypto.subtle.sign(
|
|
724
738
|
{ name: "ECDSA", hash: "SHA-256" },
|
|
725
|
-
this.privateKey,
|
|
739
|
+
this._keyPair.privateKey,
|
|
726
740
|
new Uint8Array(params.data)
|
|
727
741
|
);
|
|
728
742
|
const rawPublicKey = bs58.decode(this._keyInfo.publicKey);
|
|
729
|
-
if (this.idToken === void 0 || this.salt === void 0) {
|
|
730
|
-
throw new Error("ExpoAuth2Stamper not initialized with idToken or salt.");
|
|
731
|
-
}
|
|
732
743
|
const stampData = {
|
|
733
|
-
kind:
|
|
734
|
-
idToken: this.
|
|
744
|
+
kind: this.type,
|
|
745
|
+
idToken: this._idToken,
|
|
735
746
|
publicKey: base64urlEncode(rawPublicKey),
|
|
736
|
-
algorithm:
|
|
737
|
-
salt
|
|
747
|
+
algorithm: this.algorithm,
|
|
748
|
+
// The P-256 ephemeral key is unique per wallet, so no additional salt is needed.
|
|
749
|
+
salt: "",
|
|
738
750
|
signature: base64urlEncode(new Uint8Array(signatureRaw))
|
|
739
751
|
};
|
|
740
752
|
return base64urlEncode(new TextEncoder().encode(JSON.stringify(stampData)));
|
|
741
753
|
}
|
|
742
754
|
async resetKeyPair() {
|
|
743
|
-
await this.
|
|
744
|
-
this.privateKey = null;
|
|
745
|
-
this.publicKey = null;
|
|
746
|
-
this._keyInfo = null;
|
|
755
|
+
await this.clear();
|
|
747
756
|
return this.generateAndStore();
|
|
748
757
|
}
|
|
749
758
|
async clear() {
|
|
750
759
|
await this.clearStoredRecord();
|
|
751
|
-
this.
|
|
752
|
-
this.publicKey = null;
|
|
760
|
+
this._keyPair = null;
|
|
753
761
|
this._keyInfo = null;
|
|
762
|
+
this._idToken = null;
|
|
754
763
|
}
|
|
755
764
|
// Auth2 doesn't use key rotation; minimal no-op implementations.
|
|
756
765
|
async rotateKeyPair() {
|
|
@@ -775,16 +784,11 @@ var ExpoAuth2Stamper = class {
|
|
|
775
784
|
const publicKeyBase58 = bs58.encode(rawPublicKey);
|
|
776
785
|
const keyIdBuffer = await crypto.subtle.digest("SHA-256", rawPublicKey.buffer);
|
|
777
786
|
const keyId = base64urlEncode(new Uint8Array(keyIdBuffer)).substring(0, 16);
|
|
787
|
+
this._keyPair = keyPair;
|
|
778
788
|
this._keyInfo = { keyId, publicKey: publicKeyBase58, createdAt: Date.now() };
|
|
779
789
|
const pkcs8Buffer = await crypto.subtle.exportKey("pkcs8", keyPair.privateKey);
|
|
780
790
|
const privateKeyPkcs8 = Buffer.from(pkcs8Buffer).toString("base64");
|
|
781
|
-
await
|
|
782
|
-
this.storageKey,
|
|
783
|
-
JSON.stringify({ privateKeyPkcs8, keyInfo: this._keyInfo }),
|
|
784
|
-
{ requireAuthentication: false }
|
|
785
|
-
);
|
|
786
|
-
this.privateKey = await this.importPrivateKey(privateKeyPkcs8);
|
|
787
|
-
this.publicKey = keyPair.publicKey;
|
|
791
|
+
await this.storeRecord({ privateKeyPkcs8, keyInfo: this._keyInfo });
|
|
788
792
|
return this._keyInfo;
|
|
789
793
|
}
|
|
790
794
|
async importPublicKeyFromBase58(base58PublicKey) {
|
|
@@ -817,6 +821,9 @@ var ExpoAuth2Stamper = class {
|
|
|
817
821
|
return null;
|
|
818
822
|
}
|
|
819
823
|
}
|
|
824
|
+
async storeRecord(record) {
|
|
825
|
+
await SecureStore2.setItemAsync(this.storageKey, JSON.stringify(record), { requireAuthentication: false });
|
|
826
|
+
}
|
|
820
827
|
async clearStoredRecord() {
|
|
821
828
|
try {
|
|
822
829
|
await SecureStore2.deleteItemAsync(this.storageKey);
|
|
@@ -1167,7 +1174,7 @@ function PhantomProvider({ children, config, debugConfig, theme, appIcon, appNam
|
|
|
1167
1174
|
[ANALYTICS_HEADERS.CLIENT]: Platform2.OS,
|
|
1168
1175
|
[ANALYTICS_HEADERS.APP_ID]: config.appId,
|
|
1169
1176
|
[ANALYTICS_HEADERS.WALLET_TYPE]: config.embeddedWalletType,
|
|
1170
|
-
[ANALYTICS_HEADERS.SDK_VERSION]: "1.0.
|
|
1177
|
+
[ANALYTICS_HEADERS.SDK_VERSION]: "1.0.5"
|
|
1171
1178
|
// Replaced at build time
|
|
1172
1179
|
}
|
|
1173
1180
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phantom/react-native-sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "Phantom Wallet SDK for React Native and Expo applications",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -45,16 +45,16 @@
|
|
|
45
45
|
"directory": "packages/react-native-sdk"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@phantom/api-key-stamper": "^1.0.
|
|
49
|
-
"@phantom/auth2": "^1.0.
|
|
50
|
-
"@phantom/base64url": "^1.0.
|
|
51
|
-
"@phantom/chain-interfaces": "^1.0.
|
|
52
|
-
"@phantom/client": "^1.0.
|
|
53
|
-
"@phantom/constants": "^1.0.
|
|
54
|
-
"@phantom/crypto": "^1.0.
|
|
55
|
-
"@phantom/embedded-provider-core": "^1.0.
|
|
56
|
-
"@phantom/sdk-types": "^1.0.
|
|
57
|
-
"@phantom/wallet-sdk-ui": "^1.0.
|
|
48
|
+
"@phantom/api-key-stamper": "^1.0.5",
|
|
49
|
+
"@phantom/auth2": "^1.0.1",
|
|
50
|
+
"@phantom/base64url": "^1.0.5",
|
|
51
|
+
"@phantom/chain-interfaces": "^1.0.5",
|
|
52
|
+
"@phantom/client": "^1.0.5",
|
|
53
|
+
"@phantom/constants": "^1.0.5",
|
|
54
|
+
"@phantom/crypto": "^1.0.5",
|
|
55
|
+
"@phantom/embedded-provider-core": "^1.0.5",
|
|
56
|
+
"@phantom/sdk-types": "^1.0.5",
|
|
57
|
+
"@phantom/wallet-sdk-ui": "^1.0.5",
|
|
58
58
|
"@types/bs58": "^5.0.0",
|
|
59
59
|
"bs58": "^6.0.0",
|
|
60
60
|
"buffer": "^6.0.3"
|