@solana-mobile/mobile-wallet-adapter-protocol 2.2.7 → 2.2.8
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/cjs/index.browser.js +28 -20
- package/lib/cjs/index.browser.js.map +1 -1
- package/lib/cjs/index.js +28 -20
- package/lib/cjs/index.js.map +1 -1
- package/lib/cjs/index.native.js +17 -14
- package/lib/cjs/index.native.js.map +1 -1
- package/lib/esm/index.browser.js +28 -20
- package/lib/esm/index.browser.js.map +1 -1
- package/lib/esm/index.js +28 -20
- package/lib/esm/index.js.map +1 -1
- package/lib/types/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/codegenSpec/NativeSolanaMobileWalletAdapter.ts +2 -0
package/lib/cjs/index.browser.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
let _solana_wallet_standard_util = require("@solana/wallet-standard-util");
|
|
3
2
|
let _solana_codecs_strings = require("@solana/codecs-strings");
|
|
3
|
+
let _solana_wallet_standard_util = require("@solana/wallet-standard-util");
|
|
4
4
|
//#region src/errors.ts
|
|
5
5
|
const SolanaMobileWalletAdapterErrorCode = {
|
|
6
6
|
ERROR_ASSOCIATION_PORT_OUT_OF_RANGE: "ERROR_ASSOCIATION_PORT_OUT_OF_RANGE",
|
|
@@ -74,6 +74,14 @@ async function createHelloReq(ecdhPublicKey, associationKeypairPrivateKey) {
|
|
|
74
74
|
return response;
|
|
75
75
|
}
|
|
76
76
|
//#endregion
|
|
77
|
+
//#region src/base58Utils.ts
|
|
78
|
+
function fromUint8Array(byteArray) {
|
|
79
|
+
return (0, _solana_codecs_strings.getBase58Decoder)().decode(byteArray);
|
|
80
|
+
}
|
|
81
|
+
function base64ToBase58(base64EncodedString) {
|
|
82
|
+
return fromUint8Array(toUint8Array(base64EncodedString));
|
|
83
|
+
}
|
|
84
|
+
//#endregion
|
|
77
85
|
//#region src/createSIWSMessage.ts
|
|
78
86
|
function createSIWSMessage(payload) {
|
|
79
87
|
return (0, _solana_wallet_standard_util.createSignInMessageText)(payload);
|
|
@@ -87,14 +95,6 @@ const SolanaSignTransactions = "solana:signTransactions";
|
|
|
87
95
|
const SolanaCloneAuthorization = "solana:cloneAuthorization";
|
|
88
96
|
const SolanaSignInWithSolana = "solana:signInWithSolana";
|
|
89
97
|
//#endregion
|
|
90
|
-
//#region src/base58Utils.ts
|
|
91
|
-
function fromUint8Array(byteArray) {
|
|
92
|
-
return (0, _solana_codecs_strings.getBase58Decoder)().decode(byteArray);
|
|
93
|
-
}
|
|
94
|
-
function base64ToBase58(base64EncodedString) {
|
|
95
|
-
return fromUint8Array(toUint8Array(base64EncodedString));
|
|
96
|
-
}
|
|
97
|
-
//#endregion
|
|
98
98
|
//#region src/createMobileWalletProxy.ts
|
|
99
99
|
/**
|
|
100
100
|
* Creates a {@link MobileWallet} proxy that handles backwards compatibility and API to RPC conversion.
|
|
@@ -110,7 +110,7 @@ function createMobileWalletProxy(protocolVersion, protocolRequestHandler) {
|
|
|
110
110
|
if (target[p] == null) target[p] = async function(inputParams) {
|
|
111
111
|
const { method, params } = handleMobileWalletRequest(p, inputParams, protocolVersion);
|
|
112
112
|
const result = await protocolRequestHandler(method, params);
|
|
113
|
-
if (method === "authorize" && params.sign_in_payload && !result.sign_in_result) result
|
|
113
|
+
if (method === "authorize" && params.sign_in_payload && !result.sign_in_result) result.sign_in_result = await signInFallback(params.sign_in_payload, result, protocolRequestHandler);
|
|
114
114
|
return handleMobileWalletResponse(p, result, protocolVersion);
|
|
115
115
|
};
|
|
116
116
|
return target[p];
|
|
@@ -137,7 +137,8 @@ function handleMobileWalletRequest(methodName, methodParams, protocolVersion) {
|
|
|
137
137
|
let method = methodName.toString().replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`).toLowerCase();
|
|
138
138
|
switch (methodName) {
|
|
139
139
|
case "authorize": {
|
|
140
|
-
|
|
140
|
+
const authorizeParams = params;
|
|
141
|
+
let { chain } = authorizeParams;
|
|
141
142
|
if (protocolVersion === "legacy") {
|
|
142
143
|
switch (chain) {
|
|
143
144
|
case "solana:testnet":
|
|
@@ -149,9 +150,10 @@ function handleMobileWalletRequest(methodName, methodParams, protocolVersion) {
|
|
|
149
150
|
case "solana:mainnet":
|
|
150
151
|
chain = "mainnet-beta";
|
|
151
152
|
break;
|
|
152
|
-
default: chain =
|
|
153
|
+
default: chain = authorizeParams.cluster;
|
|
153
154
|
}
|
|
154
|
-
|
|
155
|
+
authorizeParams.cluster = chain;
|
|
156
|
+
params = authorizeParams;
|
|
155
157
|
} else {
|
|
156
158
|
switch (chain) {
|
|
157
159
|
case "testnet":
|
|
@@ -162,7 +164,8 @@ function handleMobileWalletRequest(methodName, methodParams, protocolVersion) {
|
|
|
162
164
|
chain = "solana:mainnet";
|
|
163
165
|
break;
|
|
164
166
|
}
|
|
165
|
-
|
|
167
|
+
authorizeParams.chain = chain;
|
|
168
|
+
params = authorizeParams;
|
|
166
169
|
}
|
|
167
170
|
}
|
|
168
171
|
case "reauthorize": {
|
|
@@ -469,7 +472,7 @@ async function launchAssociation(associationUrl) {
|
|
|
469
472
|
}
|
|
470
473
|
default: assertUnreachable(browser);
|
|
471
474
|
}
|
|
472
|
-
} catch
|
|
475
|
+
} catch {
|
|
473
476
|
throw new SolanaMobileWalletAdapterError(SolanaMobileWalletAdapterErrorCode.ERROR_WALLET_NOT_FOUND, "Found no installed wallet that supports the mobile wallet protocol.");
|
|
474
477
|
}
|
|
475
478
|
}
|
|
@@ -511,7 +514,10 @@ function getSequenceNumberFromByteArray(byteArray) {
|
|
|
511
514
|
return new DataView(byteArray).getUint32(0, false);
|
|
512
515
|
}
|
|
513
516
|
function decodeVarLong(byteArray) {
|
|
514
|
-
|
|
517
|
+
const bytes = new Uint8Array(byteArray);
|
|
518
|
+
const l = byteArray.byteLength;
|
|
519
|
+
const limit = 10;
|
|
520
|
+
let value = 0, offset = 0, b;
|
|
515
521
|
do {
|
|
516
522
|
if (offset >= l || offset > limit) throw new RangeError("Failed to decode varint");
|
|
517
523
|
b = bytes[offset++];
|
|
@@ -523,7 +529,7 @@ function decodeVarLong(byteArray) {
|
|
|
523
529
|
};
|
|
524
530
|
}
|
|
525
531
|
function getReflectorIdFromByteArray(byteArray) {
|
|
526
|
-
|
|
532
|
+
const { value: length, offset } = decodeVarLong(byteArray);
|
|
527
533
|
return new Uint8Array(byteArray.slice(offset, offset + length));
|
|
528
534
|
}
|
|
529
535
|
async function transact(callback, config) {
|
|
@@ -590,7 +596,7 @@ async function startScenario(config) {
|
|
|
590
596
|
const handleMessage = async (evt) => {
|
|
591
597
|
const responseBuffer = await evt.data.arrayBuffer();
|
|
592
598
|
switch (state.__type) {
|
|
593
|
-
case "connecting":
|
|
599
|
+
case "connecting": {
|
|
594
600
|
if (responseBuffer.byteLength !== 0) throw new Error("Encountered unexpected message while connecting");
|
|
595
601
|
const ecdhKeypair = await generateECDHKeypair();
|
|
596
602
|
socket.send(await createHelloReq(ecdhKeypair.publicKey, associationKeypair.privateKey));
|
|
@@ -600,6 +606,7 @@ async function startScenario(config) {
|
|
|
600
606
|
ecdhPrivateKey: ecdhKeypair.privateKey
|
|
601
607
|
};
|
|
602
608
|
break;
|
|
609
|
+
}
|
|
603
610
|
case "connected":
|
|
604
611
|
try {
|
|
605
612
|
const sequenceNumber = getSequenceNumberFromByteArray(responseBuffer.slice(0, 4));
|
|
@@ -727,7 +734,7 @@ async function startRemoteScenario(config) {
|
|
|
727
734
|
let state = { __type: "disconnected" };
|
|
728
735
|
let socket;
|
|
729
736
|
let disposeSocket;
|
|
730
|
-
|
|
737
|
+
const decodeBytes = async (evt) => {
|
|
731
738
|
if (encoding == "base64") return toUint8Array(await evt.data).buffer;
|
|
732
739
|
else return await evt.data.arrayBuffer();
|
|
733
740
|
};
|
|
@@ -807,7 +814,7 @@ async function startRemoteScenario(config) {
|
|
|
807
814
|
const handleMessage = async (evt) => {
|
|
808
815
|
const responseBuffer = await decodeBytes(evt);
|
|
809
816
|
switch (state.__type) {
|
|
810
|
-
case "reflector_id_received":
|
|
817
|
+
case "reflector_id_received": {
|
|
811
818
|
if (responseBuffer.byteLength !== 0) throw new Error("Encountered unexpected message while awaiting reflection");
|
|
812
819
|
const ecdhKeypair = await generateECDHKeypair();
|
|
813
820
|
const binaryMsg = await createHelloReq(ecdhKeypair.publicKey, associationKeypair.privateKey);
|
|
@@ -819,6 +826,7 @@ async function startRemoteScenario(config) {
|
|
|
819
826
|
ecdhPrivateKey: ecdhKeypair.privateKey
|
|
820
827
|
};
|
|
821
828
|
break;
|
|
829
|
+
}
|
|
822
830
|
case "connected":
|
|
823
831
|
try {
|
|
824
832
|
const sequenceNumber = getSequenceNumberFromByteArray(responseBuffer.slice(0, 4));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.browser.js","names":["fromUint8Array","fromUint8Array","getStringWithURLUnsafeBase64CharactersReplaced","fromUint8Array","fromUint8Array"],"sources":["../../src/errors.ts","../../src/base64Utils.ts","../../src/createHelloReq.ts","../../src/createSIWSMessage.ts","../../src/types.ts","../../src/base58Utils.ts","../../src/createMobileWalletProxy.ts","../../src/createSequenceNumberVector.ts","../../src/encryptedMessage.ts","../../src/generateAssociationKeypair.ts","../../src/generateECDHKeypair.ts","../../src/arrayBufferToBase64String.ts","../../src/associationPort.ts","../../src/getStringWithURLUnsafeBase64CharactersReplaced.ts","../../src/getAssociateAndroidIntentURL.ts","../../src/jsonRpcMessage.ts","../../src/parseHelloRsp.ts","../../src/parseSessionProps.ts","../../src/startSession.ts","../../src/transact.ts"],"sourcesContent":["// Typescript `enums` thwart tree-shaking. See https://bargsten.org/jsts/enums/\nexport const SolanaMobileWalletAdapterErrorCode = {\n ERROR_ASSOCIATION_PORT_OUT_OF_RANGE: 'ERROR_ASSOCIATION_PORT_OUT_OF_RANGE',\n ERROR_REFLECTOR_ID_OUT_OF_RANGE: 'ERROR_REFLECTOR_ID_OUT_OF_RANGE',\n ERROR_FORBIDDEN_WALLET_BASE_URL: 'ERROR_FORBIDDEN_WALLET_BASE_URL',\n ERROR_SECURE_CONTEXT_REQUIRED: 'ERROR_SECURE_CONTEXT_REQUIRED',\n ERROR_SESSION_CLOSED: 'ERROR_SESSION_CLOSED',\n ERROR_SESSION_TIMEOUT: 'ERROR_SESSION_TIMEOUT',\n ERROR_WALLET_NOT_FOUND: 'ERROR_WALLET_NOT_FOUND',\n ERROR_INVALID_PROTOCOL_VERSION: 'ERROR_INVALID_PROTOCOL_VERSION',\n ERROR_BROWSER_NOT_SUPPORTED: 'ERROR_BROWSER_NOT_SUPPORTED',\n ERROR_LOOPBACK_ACCESS_BLOCKED: 'ERROR_LOOPBACK_ACCESS_BLOCKED',\n ERROR_ASSOCIATION_CANCELLED: 'ERROR_ASSOCIATION_CANCELLED',\n} as const;\ntype SolanaMobileWalletAdapterErrorCodeEnum =\n (typeof SolanaMobileWalletAdapterErrorCode)[keyof typeof SolanaMobileWalletAdapterErrorCode];\n\ntype ErrorDataTypeMap = {\n [SolanaMobileWalletAdapterErrorCode.ERROR_ASSOCIATION_PORT_OUT_OF_RANGE]: {\n port: number;\n };\n [SolanaMobileWalletAdapterErrorCode.ERROR_REFLECTOR_ID_OUT_OF_RANGE]: {\n id: number;\n };\n [SolanaMobileWalletAdapterErrorCode.ERROR_FORBIDDEN_WALLET_BASE_URL]: undefined;\n [SolanaMobileWalletAdapterErrorCode.ERROR_SECURE_CONTEXT_REQUIRED]: undefined;\n [SolanaMobileWalletAdapterErrorCode.ERROR_SESSION_CLOSED]: {\n closeEvent: CloseEvent;\n };\n [SolanaMobileWalletAdapterErrorCode.ERROR_SESSION_TIMEOUT]: undefined;\n [SolanaMobileWalletAdapterErrorCode.ERROR_WALLET_NOT_FOUND]: undefined;\n [SolanaMobileWalletAdapterErrorCode.ERROR_INVALID_PROTOCOL_VERSION]: undefined;\n [SolanaMobileWalletAdapterErrorCode.ERROR_BROWSER_NOT_SUPPORTED]: undefined;\n [SolanaMobileWalletAdapterErrorCode.ERROR_LOOPBACK_ACCESS_BLOCKED]: undefined;\n [SolanaMobileWalletAdapterErrorCode.ERROR_ASSOCIATION_CANCELLED]: {\n event: Event | undefined;\n };\n};\n\nexport class SolanaMobileWalletAdapterError<TErrorCode extends SolanaMobileWalletAdapterErrorCodeEnum> extends Error {\n data: ErrorDataTypeMap[TErrorCode] | undefined;\n code: TErrorCode;\n constructor(\n ...args: ErrorDataTypeMap[TErrorCode] extends Record<string, unknown>\n ? [code: TErrorCode, message: string, data: ErrorDataTypeMap[TErrorCode]]\n : [code: TErrorCode, message: string]\n ) {\n const [code, message, data] = args;\n super(message);\n this.code = code;\n this.data = data;\n this.name = 'SolanaMobileWalletAdapterError';\n }\n}\n\ntype JSONRPCErrorCode = number;\n\n// Typescript `enums` thwart tree-shaking. See https://bargsten.org/jsts/enums/\nexport const SolanaMobileWalletAdapterProtocolErrorCode = {\n // Keep these in sync with `mobilewalletadapter/common/ProtocolContract.java`.\n ERROR_AUTHORIZATION_FAILED: -1,\n ERROR_INVALID_PAYLOADS: -2,\n ERROR_NOT_SIGNED: -3,\n ERROR_NOT_SUBMITTED: -4,\n ERROR_TOO_MANY_PAYLOADS: -5,\n ERROR_ATTEST_ORIGIN_ANDROID: -100,\n} as const;\ntype SolanaMobileWalletAdapterProtocolErrorCodeEnum =\n (typeof SolanaMobileWalletAdapterProtocolErrorCode)[keyof typeof SolanaMobileWalletAdapterProtocolErrorCode];\n\ntype ProtocolErrorDataTypeMap = {\n [SolanaMobileWalletAdapterProtocolErrorCode.ERROR_AUTHORIZATION_FAILED]: undefined;\n [SolanaMobileWalletAdapterProtocolErrorCode.ERROR_INVALID_PAYLOADS]: undefined;\n [SolanaMobileWalletAdapterProtocolErrorCode.ERROR_NOT_SIGNED]: undefined;\n [SolanaMobileWalletAdapterProtocolErrorCode.ERROR_NOT_SUBMITTED]: undefined;\n [SolanaMobileWalletAdapterProtocolErrorCode.ERROR_TOO_MANY_PAYLOADS]: undefined;\n [SolanaMobileWalletAdapterProtocolErrorCode.ERROR_ATTEST_ORIGIN_ANDROID]: {\n attest_origin_uri: string;\n challenge: string;\n context: string;\n };\n};\n\nexport class SolanaMobileWalletAdapterProtocolError<\n TErrorCode extends SolanaMobileWalletAdapterProtocolErrorCodeEnum,\n> extends Error {\n data: ProtocolErrorDataTypeMap[TErrorCode] | undefined;\n code: TErrorCode | JSONRPCErrorCode;\n jsonRpcMessageId: number;\n constructor(\n ...args: ProtocolErrorDataTypeMap[TErrorCode] extends Record<string, unknown>\n ? [\n jsonRpcMessageId: number,\n code: TErrorCode | JSONRPCErrorCode,\n message: string,\n data: ProtocolErrorDataTypeMap[TErrorCode],\n ]\n : [jsonRpcMessageId: number, code: TErrorCode | JSONRPCErrorCode, message: string]\n ) {\n const [jsonRpcMessageId, code, message, data] = args;\n super(message);\n this.code = code;\n this.data = data;\n this.jsonRpcMessageId = jsonRpcMessageId;\n this.name = 'SolanaMobileWalletAdapterProtocolError';\n }\n}\n","export function encode(input: string): string {\n return window.btoa(input);\n}\n\nexport function fromUint8Array(byteArray: Uint8Array, urlsafe?: boolean): string {\n const base64 = window.btoa(String.fromCharCode.call(null, ...byteArray));\n if (urlsafe) {\n return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n } else return base64;\n}\n\nexport function toUint8Array(base64EncodedByteArray: string): Uint8Array {\n return new Uint8Array(\n window\n .atob(base64EncodedByteArray)\n .split('')\n .map((c) => c.charCodeAt(0)),\n );\n}\n","export default async function createHelloReq(ecdhPublicKey: CryptoKey, associationKeypairPrivateKey: CryptoKey) {\n const publicKeyBuffer = await crypto.subtle.exportKey('raw', ecdhPublicKey);\n const signatureBuffer = await crypto.subtle.sign(\n { hash: 'SHA-256', name: 'ECDSA' },\n associationKeypairPrivateKey,\n publicKeyBuffer,\n );\n const response = new Uint8Array(publicKeyBuffer.byteLength + signatureBuffer.byteLength);\n response.set(new Uint8Array(publicKeyBuffer), 0);\n response.set(new Uint8Array(signatureBuffer), publicKeyBuffer.byteLength);\n return response;\n}\n","import { SolanaSignInInputWithRequiredFields, createSignInMessageText } from '@solana/wallet-standard-util';\nimport { SignInPayload } from './types';\nimport { encode } from './base64Utils';\n\nexport function createSIWSMessage(payload: SolanaSignInInputWithRequiredFields & SignInPayload): string {\n return createSignInMessageText(payload);\n}\n\nexport function createSIWSMessageBase64Url(payload: SolanaSignInInputWithRequiredFields & SignInPayload): string {\n return encode(createSIWSMessage(payload)).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, ''); // convert to base64url encoding;\n}\n","import type { TransactionVersion } from '@solana/web3.js';\nimport type { SolanaSignInInput } from '@solana/wallet-standard-features';\nimport type { IdentifierArray, IdentifierString, WalletAccount, WalletIcon } from '@wallet-standard/core';\n\nexport type Account =\n | Readonly<{\n address: Base64EncodedAddress;\n label?: string;\n icon?: WalletIcon;\n chains?: IdentifierArray;\n features?: IdentifierArray;\n }>\n | WalletAccount;\n\n/**\n * Properties that wallets may present to users when an app\n * asks for authorization to execute privileged methods (see\n * {@link PrivilegedMethods}).\n */\nexport type AppIdentity = Readonly<{\n uri?: string;\n icon?: string;\n name?: string;\n}>;\n\n/**\n * An ephemeral elliptic-curve keypair on the P-256 curve.\n * This public key is used to create the association token.\n * The private key is used during session establishment.\n */\nexport type AssociationKeypair = CryptoKeyPair;\n\nexport type ProtocolVersion = 'v1' | 'legacy';\n\nexport type SessionProperties = Readonly<{\n protocol_version: ProtocolVersion;\n}>;\n\n/**\n * The context returned from a wallet after having authorized a given\n * account for use with a given application. You can cache this and\n * use it later to invoke privileged methods.\n */\nexport type AuthorizationResult = Readonly<{\n accounts: Account[];\n auth_token: AuthToken;\n wallet_uri_base: string;\n sign_in_result?: SignInResult;\n}>;\n\nexport type AuthToken = string;\n\nexport type Base64EncodedAddress = string;\n\ntype Base64EncodedSignature = string;\n\ntype Base64EncodedMessage = string;\n\ntype Base64EncodedSignedMessage = string;\n\ntype Base64EncodedSignedTransaction = string;\n\nexport type Base64EncodedTransaction = string;\n\n/**\n * @deprecated Replaced by the 'chain' parameter, which adds multi-chain capability as per MWA 2.0 spec.\n */\nexport type Cluster = 'devnet' | 'testnet' | 'mainnet-beta';\n\nexport type Chain = IdentifierString | Cluster;\n\nexport type Finality = 'confirmed' | 'finalized' | 'processed';\n\nexport type WalletAssociationConfig = Readonly<{\n baseUri?: string;\n}>;\n\nexport type RemoteWalletAssociationConfig = WalletAssociationConfig &\n Readonly<{\n remoteHostAuthority: string;\n }>;\n\nexport interface AuthorizeAPI {\n /**\n * @deprecated Replaced by updated authorize() method, which adds MWA 2.0 spec support.\n */\n authorize(params: { cluster: Cluster; identity: AppIdentity }): Promise<AuthorizationResult>;\n\n authorize(params: {\n identity: AppIdentity;\n chain?: Chain;\n features?: IdentifierArray;\n addresses?: string[];\n auth_token?: AuthToken;\n sign_in_payload?: SignInPayload;\n }): Promise<AuthorizationResult>;\n}\nexport interface CloneAuthorizationAPI {\n cloneAuthorization(params: { auth_token: AuthToken }): Promise<Readonly<{ auth_token: AuthToken }>>;\n}\nexport interface DeauthorizeAPI {\n deauthorize(params: { auth_token: AuthToken }): Promise<Readonly<Record<string, never>>>;\n}\n\nexport interface GetCapabilitiesAPI {\n getCapabilities(): Promise<\n Readonly<{\n max_transactions_per_request: number;\n max_messages_per_request: number;\n supported_transaction_versions: ReadonlyArray<TransactionVersion>;\n features: IdentifierArray;\n /**\n * @deprecated Replaced by features array.\n */\n supports_clone_authorization: boolean;\n /**\n * @deprecated Replaced by features array.\n */\n supports_sign_and_send_transactions: boolean;\n }>\n >;\n}\nexport interface ReauthorizeAPI {\n reauthorize(params: { auth_token: AuthToken; identity: AppIdentity }): Promise<AuthorizationResult>;\n}\nexport interface SignMessagesAPI {\n signMessages(params: {\n addresses: Base64EncodedAddress[];\n payloads: Base64EncodedMessage[];\n }): Promise<Readonly<{ signed_payloads: Base64EncodedSignedMessage[] }>>;\n}\nexport interface SignTransactionsAPI {\n signTransactions(params: {\n payloads: Base64EncodedTransaction[];\n }): Promise<Readonly<{ signed_payloads: Base64EncodedSignedTransaction[] }>>;\n}\nexport interface SignAndSendTransactionsAPI {\n signAndSendTransactions(params: {\n options?: Readonly<{\n min_context_slot?: number;\n commitment?: string;\n skip_preflight?: boolean;\n max_retries?: number;\n wait_for_commitment_to_send_next_transaction?: boolean;\n }>;\n payloads: Base64EncodedTransaction[];\n }): Promise<Readonly<{ signatures: Base64EncodedSignature[] }>>;\n}\n\nexport interface MobileWallet\n extends\n AuthorizeAPI,\n CloneAuthorizationAPI,\n DeauthorizeAPI,\n GetCapabilitiesAPI,\n ReauthorizeAPI,\n SignMessagesAPI,\n SignTransactionsAPI,\n SignAndSendTransactionsAPI {}\n\nexport interface TerminateSessionAPI {\n terminateSession(): void;\n}\n\nexport interface RemoteMobileWallet extends MobileWallet, TerminateSessionAPI {}\n\n// optional features\nexport const SolanaSignTransactions = 'solana:signTransactions';\nexport const SolanaCloneAuthorization = 'solana:cloneAuthorization';\nexport const SolanaSignInWithSolana = 'solana:signInWithSolana';\n\nexport type SignInPayload =\n | Readonly<{\n domain?: string;\n address?: string;\n statement?: string;\n uri?: string;\n version?: string;\n chainId?: string;\n nonce?: string;\n issuedAt?: string;\n expirationTime?: string;\n notBefore?: string;\n requestId?: string;\n resources?: readonly string[];\n }>\n | SolanaSignInInput;\n\nexport type SignInPayloadWithRequiredFields = Partial<SignInPayload> &\n Required<Pick<SignInPayload, 'domain' | 'address'>>;\n\nexport type SignInResult = Readonly<{\n address: Base64EncodedAddress;\n signed_message: Base64EncodedSignedMessage;\n signature: Base64EncodedSignature;\n signature_type?: string;\n}>;\n\nexport type Scenario = Readonly<{\n wallet: Promise<MobileWallet>;\n close: () => void;\n}>;\n\nexport type RemoteScenario = Scenario &\n Readonly<{\n associationUrl: URL;\n }>;\n","import { getBase58Decoder } from '@solana/codecs-strings';\nimport { toUint8Array } from './base64Utils';\n\nexport function fromUint8Array(byteArray: Uint8Array): string {\n return getBase58Decoder().decode(byteArray);\n}\n\nexport function base64ToBase58(base64EncodedString: string): string {\n return fromUint8Array(toUint8Array(base64EncodedString));\n}\n","import { fromUint8Array, toUint8Array } from './base64Utils';\nimport { createSIWSMessageBase64Url } from './createSIWSMessage';\nimport {\n AuthorizationResult,\n MobileWallet,\n ProtocolVersion,\n SignInPayload,\n SignInResult,\n SolanaCloneAuthorization,\n SolanaSignTransactions,\n} from './types';\nimport type { IdentifierArray } from '@wallet-standard/core';\nimport { base64ToBase58 } from './base58Utils';\n\n/**\n * Creates a {@link MobileWallet} proxy that handles backwards compatibility and API to RPC conversion.\n *\n * @param protocolVersion the protocol version in use for this session/request\n * @param protocolRequestHandler callback function that handles sending the RPC request to the wallet endpoint.\n * @returns a {@link MobileWallet} proxy\n */\nexport default function createMobileWalletProxy<\n TMethodName extends keyof MobileWallet,\n TReturn extends Awaited<ReturnType<MobileWallet[TMethodName]>>,\n>(\n protocolVersion: ProtocolVersion,\n protocolRequestHandler: (method: string, params: Parameters<MobileWallet[TMethodName]>[0]) => Promise<any>,\n): MobileWallet {\n return new Proxy<MobileWallet>({} as MobileWallet, {\n get<TMethodName extends keyof MobileWallet>(target: MobileWallet, p: TMethodName) {\n // Wrapping a Proxy in a promise results in the Proxy being asked for a 'then' property so must\n // return null if 'then' is called on this proxy to let the 'resolve()' call know this is not a promise.\n // see: https://stackoverflow.com/a/53890904\n //@ts-ignore\n if (p === 'then') {\n return null;\n }\n if (target[p] == null) {\n target[p] = async function (inputParams: Parameters<MobileWallet[TMethodName]>[0]) {\n const { method, params } = handleMobileWalletRequest(p, inputParams, protocolVersion);\n const result = (await protocolRequestHandler(method, params)) as Awaited<\n ReturnType<MobileWallet[TMethodName]>\n >;\n // if the request tried to sign in but the wallet did not return a sign in result, fallback on message signing\n if (method === 'authorize' && (params as any).sign_in_payload && !(result as any).sign_in_result) {\n (result as any)['sign_in_result'] = await signInFallback(\n (params as Parameters<MobileWallet['authorize']>[0]).sign_in_payload as SignInPayload,\n result as Awaited<ReturnType<MobileWallet['authorize']>>,\n protocolRequestHandler,\n );\n }\n return handleMobileWalletResponse(p, result, protocolVersion) as TReturn;\n } as MobileWallet[TMethodName];\n }\n return target[p];\n },\n defineProperty() {\n return false;\n },\n deleteProperty() {\n return false;\n },\n });\n}\n\n/**\n * Handles all {@link MobileWallet} API requests and determines the correct MWA RPC method and params to call.\n * This handles backwards compatibility, based on the provided @protocolVersion.\n *\n * @param methodName the name of {@link MobileWallet} method that was called\n * @param methodParams the parameters that were passed to the method\n * @param protocolVersion the protocol version in use for this session/request\n * @returns the RPC request method and params that should be sent to the wallet endpoint\n */\nfunction handleMobileWalletRequest<TMethodName extends keyof MobileWallet>(\n methodName: TMethodName,\n methodParams: Parameters<MobileWallet[TMethodName]>[0],\n protocolVersion: ProtocolVersion,\n) {\n let params = methodParams;\n let method: string = methodName\n .toString()\n .replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`)\n .toLowerCase();\n switch (methodName) {\n case 'authorize': {\n let { chain } = params as Parameters<MobileWallet['authorize']>[0];\n if (protocolVersion === 'legacy') {\n switch (chain) {\n case 'solana:testnet': {\n chain = 'testnet';\n break;\n }\n case 'solana:devnet': {\n chain = 'devnet';\n break;\n }\n case 'solana:mainnet': {\n chain = 'mainnet-beta';\n break;\n }\n default: {\n chain = (params as any).cluster;\n }\n }\n (params as any).cluster = chain;\n } else {\n switch (chain) {\n case 'testnet':\n case 'devnet': {\n chain = `solana:${chain}`;\n break;\n }\n case 'mainnet-beta': {\n chain = 'solana:mainnet';\n break;\n }\n }\n (params as Parameters<MobileWallet['authorize']>[0]).chain = chain;\n }\n }\n case 'reauthorize': {\n const { auth_token, identity } = params as Parameters<MobileWallet['authorize' | 'reauthorize']>[0];\n if (auth_token) {\n switch (protocolVersion) {\n case 'legacy': {\n method = 'reauthorize';\n params = { auth_token: auth_token, identity: identity };\n break;\n }\n default: {\n method = 'authorize';\n break;\n }\n }\n }\n break;\n }\n }\n return { method, params };\n}\n\n/**\n * Handles all {@link MobileWallet} API responses and modifies the response for backwards compatibility, if needed\n *\n * @param method the {@link MobileWallet} method that was called\n * @param response the original response that was returned by the method call\n * @param protocolVersion the protocol version in use for this session/request\n * @returns the possibly modified response\n */\nfunction handleMobileWalletResponse<TMethodName extends keyof MobileWallet>(\n method: TMethodName,\n response: Awaited<ReturnType<MobileWallet[TMethodName]>>,\n protocolVersion: ProtocolVersion,\n): Awaited<ReturnType<MobileWallet[TMethodName]>> {\n switch (method) {\n case 'getCapabilities': {\n const capabilities = response as Awaited<ReturnType<MobileWallet['getCapabilities']>>;\n switch (protocolVersion) {\n case 'legacy': {\n const features: `${string}:${string}`[] = [SolanaSignTransactions];\n if (capabilities.supports_clone_authorization === true) {\n features.push(SolanaCloneAuthorization);\n }\n return {\n ...capabilities,\n features: features as IdentifierArray,\n } as Awaited<ReturnType<MobileWallet[TMethodName]>>;\n }\n case 'v1': {\n return {\n ...capabilities,\n supports_sign_and_send_transactions: true,\n supports_clone_authorization: capabilities.features.includes(SolanaCloneAuthorization),\n } as Awaited<ReturnType<MobileWallet[TMethodName]>>;\n }\n }\n }\n }\n return response;\n}\n\nasync function signInFallback(\n signInPayload: SignInPayload,\n authorizationResult: Awaited<ReturnType<MobileWallet['authorize']>>,\n protocolRequestHandler: (method: string, params: Parameters<MobileWallet['signMessages']>[0]) => Promise<unknown>,\n) {\n const domain = signInPayload.domain ?? window.location.host;\n const address = (authorizationResult as AuthorizationResult).accounts[0].address;\n const siwsMessage = createSIWSMessageBase64Url({ ...signInPayload, domain, address: base64ToBase58(address) });\n const signMessageResult = await (protocolRequestHandler('sign_messages', {\n addresses: [address],\n payloads: [siwsMessage],\n }) as ReturnType<MobileWallet['signMessages']>);\n\n const signedPayload = toUint8Array(signMessageResult.signed_payloads[0]);\n const signedMessage = fromUint8Array(signedPayload.slice(0, signedPayload.length - 64));\n const signature = fromUint8Array(signedPayload.slice(signedPayload.length - 64));\n const signInResult: SignInResult = {\n address: address,\n // Workaround: some wallets have been observed to only reply with the message signature.\n // This is non-compliant with the spec, but in the interest of maximizing compatibility,\n // detect this case and reuse the original message.\n signed_message: signedMessage.length == 0 ? siwsMessage : signedMessage,\n signature,\n };\n return signInResult;\n}\n","export const SEQUENCE_NUMBER_BYTES = 4;\n\nexport default function createSequenceNumberVector(sequenceNumber: number): Uint8Array {\n if (sequenceNumber >= 4294967296) {\n throw new Error('Outbound sequence number overflow. The maximum sequence number is 32-bytes.');\n }\n const byteArray = new ArrayBuffer(SEQUENCE_NUMBER_BYTES);\n const view = new DataView(byteArray);\n view.setUint32(0, sequenceNumber, /* littleEndian */ false);\n return new Uint8Array(byteArray);\n}\n","import createSequenceNumberVector, { SEQUENCE_NUMBER_BYTES } from './createSequenceNumberVector.js';\nimport { SharedSecret } from './parseHelloRsp.js';\n\nconst INITIALIZATION_VECTOR_BYTES = 12;\nexport const ENCODED_PUBLIC_KEY_LENGTH_BYTES = 65;\n\nexport async function encryptMessage(plaintext: string, sequenceNumber: number, sharedSecret: SharedSecret) {\n const sequenceNumberVector = createSequenceNumberVector(sequenceNumber);\n const initializationVector = new Uint8Array(INITIALIZATION_VECTOR_BYTES);\n crypto.getRandomValues(initializationVector);\n const ciphertext = await crypto.subtle.encrypt(\n getAlgorithmParams(sequenceNumberVector, initializationVector),\n sharedSecret,\n new TextEncoder().encode(plaintext),\n );\n const response = new Uint8Array(\n sequenceNumberVector.byteLength + initializationVector.byteLength + ciphertext.byteLength,\n );\n response.set(new Uint8Array(sequenceNumberVector), 0);\n response.set(new Uint8Array(initializationVector), sequenceNumberVector.byteLength);\n response.set(new Uint8Array(ciphertext), sequenceNumberVector.byteLength + initializationVector.byteLength);\n return response;\n}\n\nexport async function decryptMessage(message: ArrayBuffer, sharedSecret: SharedSecret) {\n const sequenceNumberVector = message.slice(0, SEQUENCE_NUMBER_BYTES);\n const initializationVector = message.slice(\n SEQUENCE_NUMBER_BYTES,\n SEQUENCE_NUMBER_BYTES + INITIALIZATION_VECTOR_BYTES,\n );\n const ciphertext = message.slice(SEQUENCE_NUMBER_BYTES + INITIALIZATION_VECTOR_BYTES);\n const plaintextBuffer = await crypto.subtle.decrypt(\n getAlgorithmParams(sequenceNumberVector, initializationVector),\n sharedSecret,\n ciphertext,\n );\n const plaintext = getUtf8Decoder().decode(plaintextBuffer);\n return plaintext;\n}\n\nfunction getAlgorithmParams(sequenceNumber: ArrayBuffer, initializationVector: ArrayBuffer) {\n return {\n additionalData: sequenceNumber,\n iv: initializationVector,\n name: 'AES-GCM',\n tagLength: 128, // 16 byte tag => 128 bits\n };\n}\n\nlet _utf8Decoder: TextDecoder | undefined;\nfunction getUtf8Decoder() {\n if (_utf8Decoder === undefined) {\n _utf8Decoder = new TextDecoder('utf-8');\n }\n return _utf8Decoder;\n}\n","export default async function generateAssociationKeypair(): Promise<CryptoKeyPair> {\n return await crypto.subtle.generateKey(\n {\n name: 'ECDSA',\n namedCurve: 'P-256',\n },\n false /* extractable */,\n ['sign'] /* keyUsages */,\n );\n}\n","export default async function generateECDHKeypair(): Promise<CryptoKeyPair> {\n return await crypto.subtle.generateKey(\n {\n name: 'ECDH',\n namedCurve: 'P-256',\n },\n false /* extractable */,\n ['deriveKey', 'deriveBits'] /* keyUsages */,\n );\n}\n","// https://stackoverflow.com/a/9458996/802047\nexport default function arrayBufferToBase64String(buffer: ArrayBuffer) {\n let binary = '';\n const bytes = new Uint8Array(buffer);\n const len = bytes.byteLength;\n for (let ii = 0; ii < len; ii++) {\n binary += String.fromCharCode(bytes[ii]);\n }\n return window.btoa(binary);\n}\n","import { SolanaMobileWalletAdapterError, SolanaMobileWalletAdapterErrorCode } from './errors.js';\n\ndeclare const tag: unique symbol;\nexport type AssociationPort = number & { readonly [tag]: 'AssociationPort' };\n\nexport function getRandomAssociationPort(): AssociationPort {\n return assertAssociationPort(49152 + Math.floor(Math.random() * (65535 - 49152 + 1)));\n}\n\nexport function assertAssociationPort(port: number): AssociationPort {\n if (port < 49152 || port > 65535) {\n throw new SolanaMobileWalletAdapterError(\n SolanaMobileWalletAdapterErrorCode.ERROR_ASSOCIATION_PORT_OUT_OF_RANGE,\n `Association port number must be between 49152 and 65535. ${port} given.`,\n { port },\n );\n }\n return port as AssociationPort;\n}\n","export default function getStringWithURLUnsafeCharactersReplaced(unsafeBase64EncodedString: string): string {\n return unsafeBase64EncodedString.replace(\n /[/+=]/g,\n (m) =>\n ({\n '/': '_',\n '+': '-',\n '=': '.',\n })[m] as string,\n );\n}\n","import arrayBufferToBase64String from './arrayBufferToBase64String.js';\nimport { assertAssociationPort } from './associationPort.js';\nimport { SolanaMobileWalletAdapterError, SolanaMobileWalletAdapterErrorCode } from './errors.js';\nimport getStringWithURLUnsafeBase64CharactersReplaced from './getStringWithURLUnsafeBase64CharactersReplaced.js';\nimport { ProtocolVersion } from './types.js';\nimport { fromUint8Array } from './base64Utils.js';\n\nconst INTENT_NAME = 'solana-wallet';\n\nfunction getPathParts(pathString: string) {\n return (\n pathString\n // Strip leading and trailing slashes\n .replace(/(^\\/+|\\/+$)/g, '')\n // Return an array of directories\n .split('/')\n );\n}\n\nfunction getIntentURL(methodPathname: string, intentUrlBase?: string) {\n let baseUrl: URL | null = null;\n if (intentUrlBase) {\n try {\n baseUrl = new URL(intentUrlBase);\n } catch {} // eslint-disable-line no-empty\n if (baseUrl?.protocol !== 'https:') {\n throw new SolanaMobileWalletAdapterError(\n SolanaMobileWalletAdapterErrorCode.ERROR_FORBIDDEN_WALLET_BASE_URL,\n 'Base URLs supplied by wallets must be valid `https` URLs',\n );\n }\n }\n baseUrl ||= new URL(`${INTENT_NAME}:/`);\n const pathname = methodPathname.startsWith('/')\n ? // Method is an absolute path. Replace it wholesale.\n methodPathname\n : // Method is a relative path. Merge it with the existing one.\n [...getPathParts(baseUrl.pathname), ...getPathParts(methodPathname)].join('/');\n return new URL(pathname, baseUrl);\n}\n\nexport default async function getAssociateAndroidIntentURL(\n associationPublicKey: CryptoKey,\n putativePort: number,\n associationURLBase?: string,\n protocolVersions: ProtocolVersion[] = ['v1'],\n): Promise<URL> {\n const associationPort = assertAssociationPort(putativePort);\n const exportedKey = await crypto.subtle.exportKey('raw', associationPublicKey);\n const encodedKey = arrayBufferToBase64String(exportedKey);\n const url = getIntentURL('v1/associate/local', associationURLBase);\n url.searchParams.set('association', getStringWithURLUnsafeBase64CharactersReplaced(encodedKey));\n url.searchParams.set('port', `${associationPort}`);\n protocolVersions.forEach((version) => {\n url.searchParams.set('v', version);\n });\n return url;\n}\n\nexport async function getRemoteAssociateAndroidIntentURL(\n associationPublicKey: CryptoKey,\n hostAuthority: string,\n reflectorId: Uint8Array,\n associationURLBase?: string,\n protocolVersions: ProtocolVersion[] = ['v1'],\n): Promise<URL> {\n const exportedKey = await crypto.subtle.exportKey('raw', associationPublicKey);\n const encodedKey = arrayBufferToBase64String(exportedKey);\n const url = getIntentURL('v1/associate/remote', associationURLBase);\n url.searchParams.set('association', getStringWithURLUnsafeBase64CharactersReplaced(encodedKey));\n url.searchParams.set('reflector', `${hostAuthority}`);\n url.searchParams.set('id', `${fromUint8Array(reflectorId, true)}`);\n protocolVersions.forEach((version) => {\n url.searchParams.set('v', version);\n });\n return url;\n}\n","import { decryptMessage, encryptMessage } from './encryptedMessage.js';\nimport { SolanaMobileWalletAdapterProtocolError } from './errors.js';\nimport { SharedSecret } from './parseHelloRsp.js';\n\ninterface JSONRPCRequest<TParams> {\n id: number;\n jsonrpc: '2.0';\n method: string;\n params: TParams;\n}\n\ntype JSONRPCResponse<TMessage> = {\n id: number;\n jsonrpc: '2.0';\n result: TMessage;\n};\n\nexport async function encryptJsonRpcMessage<TParams>(\n jsonRpcMessage: JSONRPCRequest<TParams>,\n sharedSecret: SharedSecret,\n) {\n const plaintext = JSON.stringify(jsonRpcMessage);\n const sequenceNumber = jsonRpcMessage.id;\n return encryptMessage(plaintext, sequenceNumber, sharedSecret);\n}\n\nexport async function decryptJsonRpcMessage<TMessage>(message: ArrayBuffer, sharedSecret: SharedSecret) {\n const plaintext = await decryptMessage(message, sharedSecret);\n const jsonRpcMessage = JSON.parse(plaintext);\n if (Object.hasOwnProperty.call(jsonRpcMessage, 'error')) {\n throw new SolanaMobileWalletAdapterProtocolError<typeof jsonRpcMessage.error.code>(\n jsonRpcMessage.id,\n jsonRpcMessage.error.code,\n jsonRpcMessage.error.message,\n );\n }\n return jsonRpcMessage as JSONRPCResponse<TMessage>;\n}\n","import { ENCODED_PUBLIC_KEY_LENGTH_BYTES } from './encryptedMessage';\n\n/**\n * A secret agreed upon by the app and the wallet. Used as\n * a symmetric key to encrypt and decrypt messages over an\n * unsecured channel.\n */\nexport type SharedSecret = CryptoKey;\n\nexport default async function parseHelloRsp(\n payloadBuffer: ArrayBuffer, // The X9.62-encoded wallet endpoint ephemeral ECDH public keypoint.\n associationPublicKey: CryptoKey,\n ecdhPrivateKey: CryptoKey,\n): Promise<SharedSecret> {\n const [associationPublicKeyBuffer, walletPublicKey] = await Promise.all([\n crypto.subtle.exportKey('raw', associationPublicKey),\n crypto.subtle.importKey(\n 'raw',\n payloadBuffer.slice(0, ENCODED_PUBLIC_KEY_LENGTH_BYTES),\n { name: 'ECDH', namedCurve: 'P-256' },\n false /* extractable */,\n [] /* keyUsages */,\n ),\n ]);\n const sharedSecret = await crypto.subtle.deriveBits({ name: 'ECDH', public: walletPublicKey }, ecdhPrivateKey, 256);\n const ecdhSecretKey = await crypto.subtle.importKey(\n 'raw',\n sharedSecret,\n 'HKDF',\n false /* extractable */,\n ['deriveKey'] /* keyUsages */,\n );\n const aesKeyMaterialVal = await crypto.subtle.deriveKey(\n {\n name: 'HKDF',\n hash: 'SHA-256',\n salt: new Uint8Array(associationPublicKeyBuffer),\n info: new Uint8Array(),\n },\n ecdhSecretKey,\n { name: 'AES-GCM', length: 128 },\n false /* extractable */,\n ['encrypt', 'decrypt'],\n );\n return aesKeyMaterialVal as SharedSecret;\n}\n","import { decryptMessage } from './encryptedMessage';\nimport { SolanaMobileWalletAdapterError, SolanaMobileWalletAdapterErrorCode } from './errors';\nimport { SharedSecret } from './parseHelloRsp';\nimport { ProtocolVersion, SessionProperties } from './types';\n\nexport default async function parseSessionProps(\n message: ArrayBuffer,\n sharedSecret: SharedSecret,\n): Promise<SessionProperties> {\n const plaintext = await decryptMessage(message, sharedSecret);\n const jsonProperties = JSON.parse(plaintext);\n let protocolVersion: ProtocolVersion = 'legacy';\n if (Object.hasOwnProperty.call(jsonProperties, 'v')) {\n switch (jsonProperties.v) {\n case 1:\n case '1':\n case 'v1':\n protocolVersion = 'v1';\n break;\n case 'legacy':\n protocolVersion = 'legacy';\n break;\n default:\n throw new SolanaMobileWalletAdapterError(\n SolanaMobileWalletAdapterErrorCode.ERROR_INVALID_PROTOCOL_VERSION,\n `Unknown/unsupported protocol version: ${jsonProperties.v}`,\n );\n }\n }\n return <SessionProperties>{\n protocol_version: protocolVersion,\n };\n}\n","import { AssociationPort, getRandomAssociationPort } from './associationPort.js';\nimport { SolanaMobileWalletAdapterError, SolanaMobileWalletAdapterErrorCode } from './errors.js';\nimport getAssociateAndroidIntentURL from './getAssociateAndroidIntentURL.js';\n\n// Typescript `enums` thwart tree-shaking. See https://bargsten.org/jsts/enums/\nconst Browser = {\n Firefox: 0,\n Other: 1,\n} as const;\ntype BrowserEnum = (typeof Browser)[keyof typeof Browser];\n\nfunction assertUnreachable(x: never): never {\n return x;\n}\n\nfunction getBrowser(): BrowserEnum {\n return navigator.userAgent.indexOf('Firefox/') !== -1 ? Browser.Firefox : Browser.Other;\n}\n\nfunction getDetectionPromise() {\n // Chrome and others silently fail if a custom protocol is not supported.\n // For these, we wait to see if the browser is navigated away from in\n // a reasonable amount of time (ie. the native wallet opened).\n return new Promise<void>((resolve, reject) => {\n function cleanup() {\n clearTimeout(timeoutId);\n window.removeEventListener('blur', handleBlur);\n }\n function handleBlur() {\n cleanup();\n resolve();\n }\n window.addEventListener('blur', handleBlur);\n const timeoutId = setTimeout(() => {\n cleanup();\n reject();\n }, 3000);\n });\n}\n\nlet _frame: HTMLIFrameElement | null = null;\nfunction launchUrlThroughHiddenFrame(url: URL) {\n if (_frame == null) {\n _frame = document.createElement('iframe');\n _frame.style.display = 'none';\n document.body.appendChild(_frame);\n }\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n _frame.contentWindow!.location.href = url.toString();\n}\n\nasync function launchAssociation(associationUrl: URL) {\n if (associationUrl.protocol === 'https:') {\n // The association URL is an Android 'App Link' or iOS 'Universal Link'.\n // These are regular web URLs that are designed to launch an app if it\n // is installed or load the actual target webpage if not.\n window.location.assign(associationUrl);\n } else {\n // The association URL has a custom protocol (eg. `solana-wallet:`)\n try {\n const browser = getBrowser();\n switch (browser) {\n case Browser.Firefox:\n // If a custom protocol is not supported in Firefox, it throws.\n launchUrlThroughHiddenFrame(associationUrl);\n // If we reached this line, it's supported.\n break;\n case Browser.Other: {\n const detectionPromise = getDetectionPromise();\n window.location.assign(associationUrl);\n await detectionPromise;\n break;\n }\n default:\n assertUnreachable(browser);\n }\n } catch (e) {\n throw new SolanaMobileWalletAdapterError(\n SolanaMobileWalletAdapterErrorCode.ERROR_WALLET_NOT_FOUND,\n 'Found no installed wallet that supports the mobile wallet protocol.',\n );\n }\n }\n}\n\nexport async function startSession(\n associationPublicKey: CryptoKey,\n associationURLBase?: string,\n): Promise<AssociationPort> {\n const randomAssociationPort = getRandomAssociationPort();\n const associationUrl = await getAssociateAndroidIntentURL(\n associationPublicKey,\n randomAssociationPort,\n associationURLBase,\n );\n await launchAssociation(associationUrl);\n return randomAssociationPort;\n}\n","import { fromUint8Array, toUint8Array } from './base64Utils.js';\nimport createHelloReq from './createHelloReq.js';\nimport createMobileWalletProxy from './createMobileWalletProxy.js';\nimport { SEQUENCE_NUMBER_BYTES } from './createSequenceNumberVector.js';\nimport { ENCODED_PUBLIC_KEY_LENGTH_BYTES } from './encryptedMessage.js';\nimport {\n SolanaMobileWalletAdapterError,\n SolanaMobileWalletAdapterErrorCode,\n SolanaMobileWalletAdapterProtocolError,\n} from './errors.js';\nimport generateAssociationKeypair from './generateAssociationKeypair.js';\nimport generateECDHKeypair from './generateECDHKeypair.js';\nimport { getRemoteAssociateAndroidIntentURL } from './getAssociateAndroidIntentURL.js';\nimport { decryptJsonRpcMessage, encryptJsonRpcMessage } from './jsonRpcMessage.js';\nimport parseHelloRsp, { SharedSecret } from './parseHelloRsp.js';\nimport parseSessionProps from './parseSessionProps.js';\nimport { startSession } from './startSession.js';\nimport {\n AssociationKeypair,\n MobileWallet,\n RemoteMobileWallet,\n RemoteScenario,\n RemoteWalletAssociationConfig,\n Scenario,\n SessionProperties,\n WalletAssociationConfig,\n} from './types.js';\n\nconst WEBSOCKET_CONNECTION_CONFIG = {\n /**\n * 300 milliseconds is a generally accepted threshold for what someone\n * would consider an acceptable response time for a user interface\n * after having performed a low-attention tapping task. We set the initial\n * interval at which we wait for the wallet to set up the websocket at\n * half this, as per the Nyquist frequency, with a progressive backoff\n * sequence from there. The total wait time is 30s, which allows for the\n * user to be presented with a disambiguation dialog, select a wallet, and\n * for the wallet app to subsequently start.\n */\n retryDelayScheduleMs: [150, 150, 200, 500, 500, 750, 750, 1000],\n timeoutMs: 30000,\n} as const;\nconst WEBSOCKET_PROTOCOL_BINARY = 'com.solana.mobilewalletadapter.v1';\nconst WEBSOCKET_PROTOCOL_BASE64 = 'com.solana.mobilewalletadapter.v1.base64';\ntype PROTOCOL_ENCODING = 'binary' | 'base64';\n\ntype JsonResponsePromises<T> = Record<\n number,\n Readonly<{ resolve: (value?: T | PromiseLike<T>) => void; reject: (reason?: unknown) => void }>\n>;\n\ntype State =\n | { __type: 'connected'; sharedSecret: SharedSecret; sessionProperties: SessionProperties }\n | { __type: 'connecting'; associationKeypair: AssociationKeypair }\n | { __type: 'disconnected' }\n | { __type: 'hello_req_sent'; associationPublicKey: CryptoKey; ecdhPrivateKey: CryptoKey };\n\ntype RemoteState = State | { __type: 'reflector_id_received'; reflectorId: ArrayBuffer };\n\nfunction assertSecureContext() {\n if (typeof window === 'undefined' || window.isSecureContext !== true) {\n throw new SolanaMobileWalletAdapterError(\n SolanaMobileWalletAdapterErrorCode.ERROR_SECURE_CONTEXT_REQUIRED,\n 'The mobile wallet adapter protocol must be used in a secure context (`https`).',\n );\n }\n}\n\nfunction assertSecureEndpointSpecificURI(walletUriBase: string) {\n let url: URL;\n try {\n url = new URL(walletUriBase);\n } catch {\n throw new SolanaMobileWalletAdapterError(\n SolanaMobileWalletAdapterErrorCode.ERROR_FORBIDDEN_WALLET_BASE_URL,\n 'Invalid base URL supplied by wallet',\n );\n }\n if (url.protocol !== 'https:') {\n throw new SolanaMobileWalletAdapterError(\n SolanaMobileWalletAdapterErrorCode.ERROR_FORBIDDEN_WALLET_BASE_URL,\n 'Base URLs supplied by wallets must be valid `https` URLs',\n );\n }\n}\n\nfunction getSequenceNumberFromByteArray(byteArray: ArrayBuffer): number {\n const view = new DataView(byteArray);\n return view.getUint32(0, /* littleEndian */ false);\n}\n\nfunction decodeVarLong(byteArray: ArrayBuffer): { value: number; offset: number } {\n var bytes = new Uint8Array(byteArray),\n l = byteArray.byteLength,\n limit = 10,\n value = 0,\n offset = 0,\n b;\n do {\n if (offset >= l || offset > limit) throw new RangeError('Failed to decode varint');\n b = bytes[offset++];\n value |= (b & 0x7f) << (7 * offset);\n } while (b >= 0x80);\n\n return { value, offset };\n}\n\nfunction getReflectorIdFromByteArray(byteArray: ArrayBuffer): Uint8Array {\n let { value: length, offset } = decodeVarLong(byteArray);\n return new Uint8Array(byteArray.slice(offset, offset + length));\n}\n\nexport async function transact<TReturn>(\n callback: (wallet: MobileWallet) => TReturn,\n config?: WalletAssociationConfig,\n): Promise<TReturn> {\n const { wallet, close } = await startScenario(config);\n try {\n return await callback(await wallet);\n } finally {\n close();\n }\n}\n\nexport async function startScenario(config?: WalletAssociationConfig): Promise<Scenario> {\n assertSecureContext();\n const associationKeypair = await generateAssociationKeypair();\n const sessionPort = await startSession(associationKeypair.publicKey, config?.baseUri);\n const websocketURL = `ws://localhost:${sessionPort}/solana-wallet`;\n let connectionStartTime: number;\n const getNextRetryDelayMs = (() => {\n const schedule = [...WEBSOCKET_CONNECTION_CONFIG.retryDelayScheduleMs];\n return () => (schedule.length > 1 ? (schedule.shift() as number) : schedule[0]);\n })();\n let nextJsonRpcMessageId = 1;\n let lastKnownInboundSequenceNumber = 0;\n let state: State = { __type: 'disconnected' };\n let socket: WebSocket;\n let sessionEstablished = false;\n let handleForceClose: () => void;\n return {\n close: () => {\n socket.close();\n handleForceClose();\n },\n wallet: new Promise((resolve, reject) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const jsonRpcResponsePromises: JsonResponsePromises<any> = {};\n const handleOpen = async () => {\n if (state.__type !== 'connecting') {\n console.warn(\n 'Expected adapter state to be `connecting` at the moment the websocket opens. ' +\n `Got \\`${state.__type}\\`.`,\n );\n return;\n }\n socket.removeEventListener('open', handleOpen);\n\n // previous versions of this library and walletlib incorrectly implemented the MWA session\n // establishment protocol for local connections. The dapp is supposed to wait for the\n // APP_PING message before sending the HELLO_REQ. Instead, the dapp was sending the HELLO_REQ\n // immediately upon connection to the websocket server regardless of wether or not an\n // APP_PING was sent by the wallet/websocket server. We must continue to support this behavior\n // in case the user is using a wallet that has not updated their walletlib implementation.\n const { associationKeypair } = state;\n const ecdhKeypair = await generateECDHKeypair();\n socket.send(await createHelloReq(ecdhKeypair.publicKey, associationKeypair.privateKey));\n state = {\n __type: 'hello_req_sent',\n associationPublicKey: associationKeypair.publicKey,\n ecdhPrivateKey: ecdhKeypair.privateKey,\n };\n };\n const handleClose = (evt: CloseEvent) => {\n if (evt.wasClean) {\n state = { __type: 'disconnected' };\n } else {\n reject(\n new SolanaMobileWalletAdapterError(\n SolanaMobileWalletAdapterErrorCode.ERROR_SESSION_CLOSED,\n `The wallet session dropped unexpectedly (${evt.code}: ${evt.reason}).`,\n { closeEvent: evt },\n ),\n );\n }\n disposeSocket();\n };\n const handleError = async (_evt: Event) => {\n disposeSocket();\n if (Date.now() - connectionStartTime >= WEBSOCKET_CONNECTION_CONFIG.timeoutMs) {\n reject(\n new SolanaMobileWalletAdapterError(\n SolanaMobileWalletAdapterErrorCode.ERROR_SESSION_TIMEOUT,\n `Failed to connect to the wallet websocket at ${websocketURL}.`,\n ),\n );\n } else {\n await new Promise((resolve) => {\n const retryDelayMs = getNextRetryDelayMs();\n retryWaitTimeoutId = window.setTimeout(resolve, retryDelayMs);\n });\n attemptSocketConnection();\n }\n };\n const handleMessage = async (evt: MessageEvent<Blob>) => {\n const responseBuffer = await evt.data.arrayBuffer();\n switch (state.__type) {\n case 'connecting':\n if (responseBuffer.byteLength !== 0) {\n throw new Error('Encountered unexpected message while connecting');\n }\n const ecdhKeypair = await generateECDHKeypair();\n socket.send(await createHelloReq(ecdhKeypair.publicKey, associationKeypair.privateKey));\n state = {\n __type: 'hello_req_sent',\n associationPublicKey: associationKeypair.publicKey,\n ecdhPrivateKey: ecdhKeypair.privateKey,\n };\n break;\n case 'connected':\n try {\n const sequenceNumberVector = responseBuffer.slice(0, SEQUENCE_NUMBER_BYTES);\n const sequenceNumber = getSequenceNumberFromByteArray(sequenceNumberVector);\n if (sequenceNumber !== lastKnownInboundSequenceNumber + 1) {\n throw new Error('Encrypted message has invalid sequence number');\n }\n lastKnownInboundSequenceNumber = sequenceNumber;\n const jsonRpcMessage = await decryptJsonRpcMessage(responseBuffer, state.sharedSecret);\n const responsePromise = jsonRpcResponsePromises[jsonRpcMessage.id];\n delete jsonRpcResponsePromises[jsonRpcMessage.id];\n responsePromise.resolve(jsonRpcMessage.result);\n } catch (e) {\n if (e instanceof SolanaMobileWalletAdapterProtocolError) {\n const responsePromise = jsonRpcResponsePromises[e.jsonRpcMessageId];\n delete jsonRpcResponsePromises[e.jsonRpcMessageId];\n responsePromise.reject(e);\n } else {\n throw e;\n }\n }\n break;\n case 'hello_req_sent': {\n // if we receive an APP_PING message (empty message), resend the HELLO_REQ (see above)\n if (responseBuffer.byteLength === 0) {\n const ecdhKeypair = await generateECDHKeypair();\n socket.send(await createHelloReq(ecdhKeypair.publicKey, associationKeypair.privateKey));\n state = {\n __type: 'hello_req_sent',\n associationPublicKey: associationKeypair.publicKey,\n ecdhPrivateKey: ecdhKeypair.privateKey,\n };\n break;\n }\n const sharedSecret = await parseHelloRsp(\n responseBuffer,\n state.associationPublicKey,\n state.ecdhPrivateKey,\n );\n const sessionPropertiesBuffer = responseBuffer.slice(ENCODED_PUBLIC_KEY_LENGTH_BYTES);\n const sessionProperties =\n sessionPropertiesBuffer.byteLength !== 0\n ? await (async () => {\n const sequenceNumberVector = sessionPropertiesBuffer.slice(\n 0,\n SEQUENCE_NUMBER_BYTES,\n );\n const sequenceNumber = getSequenceNumberFromByteArray(sequenceNumberVector);\n if (sequenceNumber !== lastKnownInboundSequenceNumber + 1) {\n throw new Error('Encrypted message has invalid sequence number');\n }\n lastKnownInboundSequenceNumber = sequenceNumber;\n return parseSessionProps(sessionPropertiesBuffer, sharedSecret);\n })()\n : <SessionProperties>{ protocol_version: 'legacy' };\n state = { __type: 'connected', sharedSecret, sessionProperties };\n const wallet = createMobileWalletProxy(\n sessionProperties.protocol_version,\n async (method, params) => {\n const id = nextJsonRpcMessageId++;\n socket.send(\n await encryptJsonRpcMessage(\n {\n id,\n jsonrpc: '2.0' as const,\n method,\n params: params ?? {},\n },\n sharedSecret,\n ),\n );\n return new Promise((resolve, reject) => {\n jsonRpcResponsePromises[id] = {\n resolve(result) {\n switch (method) {\n case 'authorize':\n case 'reauthorize': {\n const { wallet_uri_base } = result as Awaited<\n ReturnType<MobileWallet['authorize' | 'reauthorize']>\n >;\n if (wallet_uri_base != null) {\n try {\n assertSecureEndpointSpecificURI(wallet_uri_base);\n } catch (e) {\n reject(e);\n return;\n }\n }\n break;\n }\n }\n resolve(result);\n },\n reject,\n };\n });\n },\n );\n sessionEstablished = true;\n try {\n resolve(wallet);\n } catch (e) {\n reject(e);\n }\n break;\n }\n }\n };\n handleForceClose = () => {\n socket.removeEventListener('message', handleMessage);\n disposeSocket();\n if (!sessionEstablished) {\n reject(\n new SolanaMobileWalletAdapterError(\n SolanaMobileWalletAdapterErrorCode.ERROR_SESSION_CLOSED,\n `The wallet session was closed before connection.`,\n { closeEvent: new CloseEvent('socket was closed before connection') },\n ),\n );\n }\n };\n let disposeSocket: () => void;\n let retryWaitTimeoutId: number;\n const attemptSocketConnection = () => {\n if (disposeSocket) {\n disposeSocket();\n }\n state = { __type: 'connecting', associationKeypair };\n if (connectionStartTime === undefined) {\n connectionStartTime = Date.now();\n }\n socket = new WebSocket(websocketURL, [WEBSOCKET_PROTOCOL_BINARY]);\n socket.addEventListener('open', handleOpen);\n socket.addEventListener('close', handleClose);\n socket.addEventListener('error', handleError);\n socket.addEventListener('message', handleMessage);\n disposeSocket = () => {\n window.clearTimeout(retryWaitTimeoutId);\n socket.removeEventListener('open', handleOpen);\n socket.removeEventListener('close', handleClose);\n socket.removeEventListener('error', handleError);\n socket.removeEventListener('message', handleMessage);\n };\n };\n attemptSocketConnection();\n }),\n };\n}\n\nexport async function startRemoteScenario(config: RemoteWalletAssociationConfig): Promise<RemoteScenario> {\n assertSecureContext();\n const associationKeypair = await generateAssociationKeypair();\n const websocketURL = `wss://${config?.remoteHostAuthority}/reflect`;\n let connectionStartTime: number;\n const getNextRetryDelayMs = (() => {\n const schedule = [...WEBSOCKET_CONNECTION_CONFIG.retryDelayScheduleMs];\n return () => (schedule.length > 1 ? (schedule.shift() as number) : schedule[0]);\n })();\n let nextJsonRpcMessageId = 1;\n let lastKnownInboundSequenceNumber = 0;\n let encoding: PROTOCOL_ENCODING;\n let state: RemoteState = { __type: 'disconnected' };\n let socket: WebSocket;\n let disposeSocket: () => void;\n let decodeBytes = async (evt: MessageEvent<string | Blob>) => {\n if (encoding == 'base64') {\n // base64 encoding\n const message = (await evt.data) as string;\n return toUint8Array(message).buffer;\n } else {\n return await (evt.data as Blob).arrayBuffer();\n }\n };\n // Reflector Connection Phase\n // here we connect to the reflector and wait for the REFLECTOR_ID message\n // so we build the association URL and return that back to the caller\n const associationUrl = await new Promise<URL>((resolve, reject) => {\n const handleOpen = async () => {\n if (state.__type !== 'connecting') {\n console.warn(\n 'Expected adapter state to be `connecting` at the moment the websocket opens. ' +\n `Got \\`${state.__type}\\`.`,\n );\n return;\n }\n if (socket.protocol.includes(WEBSOCKET_PROTOCOL_BASE64)) {\n encoding = 'base64';\n } else {\n encoding = 'binary';\n }\n socket.removeEventListener('open', handleOpen);\n };\n const handleClose = (evt: CloseEvent) => {\n if (evt.wasClean) {\n state = { __type: 'disconnected' };\n } else {\n reject(\n new SolanaMobileWalletAdapterError(\n SolanaMobileWalletAdapterErrorCode.ERROR_SESSION_CLOSED,\n `The wallet session dropped unexpectedly (${evt.code}: ${evt.reason}).`,\n { closeEvent: evt },\n ),\n );\n }\n disposeSocket();\n };\n const handleError = async (_evt: Event) => {\n disposeSocket();\n if (Date.now() - connectionStartTime >= WEBSOCKET_CONNECTION_CONFIG.timeoutMs) {\n reject(\n new SolanaMobileWalletAdapterError(\n SolanaMobileWalletAdapterErrorCode.ERROR_SESSION_TIMEOUT,\n `Failed to connect to the wallet websocket at ${websocketURL}.`,\n ),\n );\n } else {\n await new Promise((resolve) => {\n const retryDelayMs = getNextRetryDelayMs();\n retryWaitTimeoutId = window.setTimeout(resolve, retryDelayMs);\n });\n attemptSocketConnection();\n }\n };\n const handleReflectorIdMessage = async (evt: MessageEvent<string | Blob>) => {\n const responseBuffer = await decodeBytes(evt);\n if (state.__type === 'connecting') {\n if (responseBuffer.byteLength == 0) {\n throw new Error('Encountered unexpected message while connecting');\n }\n const reflectorId = getReflectorIdFromByteArray(responseBuffer);\n state = {\n __type: 'reflector_id_received',\n reflectorId: reflectorId,\n };\n const associationUrl = await getRemoteAssociateAndroidIntentURL(\n associationKeypair.publicKey,\n config.remoteHostAuthority,\n reflectorId,\n config?.baseUri,\n );\n socket.removeEventListener('message', handleReflectorIdMessage);\n resolve(associationUrl);\n }\n };\n let retryWaitTimeoutId: number;\n const attemptSocketConnection = () => {\n if (disposeSocket) {\n disposeSocket();\n }\n state = { __type: 'connecting', associationKeypair };\n if (connectionStartTime === undefined) {\n connectionStartTime = Date.now();\n }\n socket = new WebSocket(websocketURL, [WEBSOCKET_PROTOCOL_BINARY, WEBSOCKET_PROTOCOL_BASE64]);\n socket.addEventListener('open', handleOpen);\n socket.addEventListener('close', handleClose);\n socket.addEventListener('error', handleError);\n socket.addEventListener('message', handleReflectorIdMessage);\n disposeSocket = () => {\n window.clearTimeout(retryWaitTimeoutId);\n socket.removeEventListener('open', handleOpen);\n socket.removeEventListener('close', handleClose);\n socket.removeEventListener('error', handleError);\n socket.removeEventListener('message', handleReflectorIdMessage);\n };\n };\n attemptSocketConnection();\n });\n // Wallet Connection Phase\n // here we return the association URL (containing the reflector ID) to the caller +\n // a promise that will resolve the MobileWallet object once the wallet connects.\n let sessionEstablished = false;\n let handleClose: () => void;\n return {\n associationUrl,\n close: () => {\n socket.close();\n handleClose();\n },\n wallet: new Promise((resolve, reject) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const jsonRpcResponsePromises: JsonResponsePromises<any> = {};\n const handleMessage = async (evt: MessageEvent<string | Blob>) => {\n const responseBuffer = await decodeBytes(evt);\n switch (state.__type) {\n case 'reflector_id_received':\n if (responseBuffer.byteLength !== 0) {\n throw new Error('Encountered unexpected message while awaiting reflection');\n }\n const ecdhKeypair = await generateECDHKeypair();\n const binaryMsg = await createHelloReq(ecdhKeypair.publicKey, associationKeypair.privateKey);\n if (encoding == 'base64') {\n socket.send(fromUint8Array(binaryMsg));\n } else {\n socket.send(binaryMsg);\n }\n state = {\n __type: 'hello_req_sent',\n associationPublicKey: associationKeypair.publicKey,\n ecdhPrivateKey: ecdhKeypair.privateKey,\n };\n break;\n case 'connected':\n try {\n const sequenceNumberVector = responseBuffer.slice(0, SEQUENCE_NUMBER_BYTES);\n const sequenceNumber = getSequenceNumberFromByteArray(sequenceNumberVector);\n if (sequenceNumber !== lastKnownInboundSequenceNumber + 1) {\n throw new Error('Encrypted message has invalid sequence number');\n }\n lastKnownInboundSequenceNumber = sequenceNumber;\n const jsonRpcMessage = await decryptJsonRpcMessage(responseBuffer, state.sharedSecret);\n const responsePromise = jsonRpcResponsePromises[jsonRpcMessage.id];\n delete jsonRpcResponsePromises[jsonRpcMessage.id];\n responsePromise.resolve(jsonRpcMessage.result);\n } catch (e) {\n if (e instanceof SolanaMobileWalletAdapterProtocolError) {\n const responsePromise = jsonRpcResponsePromises[e.jsonRpcMessageId];\n delete jsonRpcResponsePromises[e.jsonRpcMessageId];\n responsePromise.reject(e);\n } else {\n throw e;\n }\n }\n break;\n case 'hello_req_sent': {\n const sharedSecret = await parseHelloRsp(\n responseBuffer,\n state.associationPublicKey,\n state.ecdhPrivateKey,\n );\n const sessionPropertiesBuffer = responseBuffer.slice(ENCODED_PUBLIC_KEY_LENGTH_BYTES);\n const sessionProperties =\n sessionPropertiesBuffer.byteLength !== 0\n ? await (async () => {\n const sequenceNumberVector = sessionPropertiesBuffer.slice(\n 0,\n SEQUENCE_NUMBER_BYTES,\n );\n const sequenceNumber = getSequenceNumberFromByteArray(sequenceNumberVector);\n if (sequenceNumber !== lastKnownInboundSequenceNumber + 1) {\n throw new Error('Encrypted message has invalid sequence number');\n }\n lastKnownInboundSequenceNumber = sequenceNumber;\n return parseSessionProps(sessionPropertiesBuffer, sharedSecret);\n })()\n : <SessionProperties>{ protocol_version: 'legacy' };\n state = { __type: 'connected', sharedSecret, sessionProperties };\n const wallet = createMobileWalletProxy(\n sessionProperties.protocol_version,\n async (method, params) => {\n const id = nextJsonRpcMessageId++;\n const binaryMsg = await encryptJsonRpcMessage(\n {\n id,\n jsonrpc: '2.0' as const,\n method,\n params: params ?? {},\n },\n sharedSecret,\n );\n if (encoding == 'base64') {\n socket.send(fromUint8Array(binaryMsg));\n } else {\n socket.send(binaryMsg);\n }\n return new Promise((resolve, reject) => {\n jsonRpcResponsePromises[id] = {\n resolve(result) {\n switch (method) {\n case 'authorize':\n case 'reauthorize': {\n const { wallet_uri_base } = result as Awaited<\n ReturnType<MobileWallet['authorize' | 'reauthorize']>\n >;\n if (wallet_uri_base != null) {\n try {\n assertSecureEndpointSpecificURI(wallet_uri_base);\n } catch (e) {\n reject(e);\n return;\n }\n }\n break;\n }\n }\n resolve(result);\n },\n reject,\n };\n });\n },\n );\n sessionEstablished = true;\n try {\n resolve(wallet);\n } catch (e) {\n reject(e);\n }\n break;\n }\n }\n };\n socket.addEventListener('message', handleMessage);\n handleClose = () => {\n socket.removeEventListener('message', handleMessage);\n disposeSocket();\n if (!sessionEstablished) {\n reject(\n new SolanaMobileWalletAdapterError(\n SolanaMobileWalletAdapterErrorCode.ERROR_SESSION_CLOSED,\n `The wallet session was closed before connection.`,\n { closeEvent: new CloseEvent('socket was closed before connection') },\n ),\n );\n }\n };\n }),\n };\n}\n"],"mappings":";;;;AACA,MAAa,qCAAqC;CAC9C,qCAAqC;CACrC,iCAAiC;CACjC,iCAAiC;CACjC,+BAA+B;CAC/B,sBAAsB;CACtB,uBAAuB;CACvB,wBAAwB;CACxB,gCAAgC;CAChC,6BAA6B;CAC7B,+BAA+B;CAC/B,6BAA6B;CAChC;AA0BD,IAAa,iCAAb,cAA+G,MAAM;CACjH;CACA;CACA,YACI,GAAG,MAGL;EACE,MAAM,CAAC,MAAM,SAAS,QAAQ;AAC9B,QAAM,QAAQ;AACd,OAAK,OAAO;AACZ,OAAK,OAAO;AACZ,OAAK,OAAO;;;AAOpB,MAAa,6CAA6C;CAEtD,4BAA4B;CAC5B,wBAAwB;CACxB,kBAAkB;CAClB,qBAAqB;CACrB,yBAAyB;CACzB,6BAA6B;CAChC;AAiBD,IAAa,yCAAb,cAEU,MAAM;CACZ;CACA;CACA;CACA,YACI,GAAG,MAQL;EACE,MAAM,CAAC,kBAAkB,MAAM,SAAS,QAAQ;AAChD,QAAM,QAAQ;AACd,OAAK,OAAO;AACZ,OAAK,OAAO;AACZ,OAAK,mBAAmB;AACxB,OAAK,OAAO;;;;;ACxGpB,SAAgB,OAAO,OAAuB;AAC1C,QAAO,OAAO,KAAK,MAAM;;AAG7B,SAAgBA,iBAAe,WAAuB,SAA2B;CAC7E,MAAM,SAAS,OAAO,KAAK,OAAO,aAAa,KAAK,MAAM,GAAG,UAAU,CAAC;AACxE,KAAI,QACA,QAAO,OAAO,QAAQ,OAAO,IAAI,CAAC,QAAQ,OAAO,IAAI,CAAC,QAAQ,OAAO,GAAG;KACrE,QAAO;;AAGlB,SAAgB,aAAa,wBAA4C;AACrE,QAAO,IAAI,WACP,OACK,KAAK,uBAAuB,CAC5B,MAAM,GAAG,CACT,KAAK,MAAM,EAAE,WAAW,EAAE,CAAC,CACnC;;;;ACjBL,eAA8B,eAAe,eAA0B,8BAAyC;CAC5G,MAAM,kBAAkB,MAAM,OAAO,OAAO,UAAU,OAAO,cAAc;CAC3E,MAAM,kBAAkB,MAAM,OAAO,OAAO,KACxC;EAAE,MAAM;EAAW,MAAM;EAAS,EAClC,8BACA,gBACH;CACD,MAAM,WAAW,IAAI,WAAW,gBAAgB,aAAa,gBAAgB,WAAW;AACxF,UAAS,IAAI,IAAI,WAAW,gBAAgB,EAAE,EAAE;AAChD,UAAS,IAAI,IAAI,WAAW,gBAAgB,EAAE,gBAAgB,WAAW;AACzE,QAAO;;;;ACNX,SAAgB,kBAAkB,SAAsE;AACpG,SAAA,GAAA,6BAAA,yBAA+B,QAAQ;;AAG3C,SAAgB,2BAA2B,SAAsE;AAC7G,QAAO,OAAO,kBAAkB,QAAQ,CAAC,CAAC,QAAQ,OAAO,IAAI,CAAC,QAAQ,OAAO,IAAI,CAAC,QAAQ,OAAO,GAAG;;;;AC8JxG,MAAa,yBAAyB;AACtC,MAAa,2BAA2B;AACxC,MAAa,yBAAyB;;;ACtKtC,SAAgB,eAAe,WAA+B;AAC1D,SAAA,GAAA,uBAAA,mBAAyB,CAAC,OAAO,UAAU;;AAG/C,SAAgB,eAAe,qBAAqC;AAChE,QAAO,eAAe,aAAa,oBAAoB,CAAC;;;;;;;;;;;ACa5D,SAAwB,wBAIpB,iBACA,wBACY;AACZ,QAAO,IAAI,MAAoB,EAAE,EAAkB;EAC/C,IAA4C,QAAsB,GAAgB;AAK9E,OAAI,MAAM,OACN,QAAO;AAEX,OAAI,OAAO,MAAM,KACb,QAAO,KAAK,eAAgB,aAAuD;IAC/E,MAAM,EAAE,QAAQ,WAAW,0BAA0B,GAAG,aAAa,gBAAgB;IACrF,MAAM,SAAU,MAAM,uBAAuB,QAAQ,OAAO;AAI5D,QAAI,WAAW,eAAgB,OAAe,mBAAmB,CAAE,OAAe,eAC7E,QAAe,oBAAoB,MAAM,eACrC,OAAoD,iBACrD,QACA,uBACH;AAEL,WAAO,2BAA2B,GAAG,QAAQ,gBAAgB;;AAGrE,UAAO,OAAO;;EAElB,iBAAiB;AACb,UAAO;;EAEX,iBAAiB;AACb,UAAO;;EAEd,CAAC;;;;;;;;;;;AAYN,SAAS,0BACL,YACA,cACA,iBACF;CACE,IAAI,SAAS;CACb,IAAI,SAAiB,WAChB,UAAU,CACV,QAAQ,WAAW,WAAW,IAAI,OAAO,aAAa,GAAG,CACzD,aAAa;AAClB,SAAQ,YAAR;EACI,KAAK,aAAa;GACd,IAAI,EAAE,UAAU;AAChB,OAAI,oBAAoB,UAAU;AAC9B,YAAQ,OAAR;KACI,KAAK;AACD,cAAQ;AACR;KAEJ,KAAK;AACD,cAAQ;AACR;KAEJ,KAAK;AACD,cAAQ;AACR;KAEJ,QACI,SAAS,OAAe;;AAG/B,WAAe,UAAU;UACvB;AACH,YAAQ,OAAR;KACI,KAAK;KACL,KAAK;AACD,cAAQ,UAAU;AAClB;KAEJ,KAAK;AACD,cAAQ;AACR;;AAGP,WAAoD,QAAQ;;;EAGrE,KAAK,eAAe;GAChB,MAAM,EAAE,YAAY,aAAa;AACjC,OAAI,WACA,SAAQ,iBAAR;IACI,KAAK;AACD,cAAS;AACT,cAAS;MAAc;MAAsB;MAAU;AACvD;IAEJ;AACI,cAAS;AACT;;AAIZ;;;AAGR,QAAO;EAAE;EAAQ;EAAQ;;;;;;;;;;AAW7B,SAAS,2BACL,QACA,UACA,iBAC8C;AAC9C,SAAQ,QAAR;EACI,KAAK,mBAAmB;GACpB,MAAM,eAAe;AACrB,WAAQ,iBAAR;IACI,KAAK,UAAU;KACX,MAAM,WAAoC,CAAC,uBAAuB;AAClE,SAAI,aAAa,iCAAiC,KAC9C,UAAS,KAAK,yBAAyB;AAE3C,YAAO;MACH,GAAG;MACO;MACb;;IAEL,KAAK,KACD,QAAO;KACH,GAAG;KACH,qCAAqC;KACrC,8BAA8B,aAAa,SAAS,SAAS,yBAAyB;KACzF;;;;AAKjB,QAAO;;AAGX,eAAe,eACX,eACA,qBACA,wBACF;CACE,MAAM,SAAS,cAAc,UAAU,OAAO,SAAS;CACvD,MAAM,UAAW,oBAA4C,SAAS,GAAG;CACzE,MAAM,cAAc,2BAA2B;EAAE,GAAG;EAAe;EAAQ,SAAS,eAAe,QAAQ;EAAE,CAAC;CAM9G,MAAM,gBAAgB,cALI,MAAO,uBAAuB,iBAAiB;EACrE,WAAW,CAAC,QAAQ;EACpB,UAAU,CAAC,YAAY;EAC1B,CAAC,EAEmD,gBAAgB,GAAG;CACxE,MAAM,gBAAgBC,iBAAe,cAAc,MAAM,GAAG,cAAc,SAAS,GAAG,CAAC;CACvF,MAAM,YAAYA,iBAAe,cAAc,MAAM,cAAc,SAAS,GAAG,CAAC;AAShF,QARmC;EACtB;EAIT,gBAAgB,cAAc,UAAU,IAAI,cAAc;EAC1D;EACH;;AC3ML,SAAwB,2BAA2B,gBAAoC;AACnF,KAAI,kBAAkB,WAClB,OAAM,IAAI,MAAM,8EAA8E;CAElG,MAAM,4BAAY,IAAI,YAAA,EAAkC;AAC3C,KAAI,SAAS,UAAU,CAC/B,UAAU,GAAG,gBAAmC,MAAM;AAC3D,QAAO,IAAI,WAAW,UAAU;;;;ACNpC,MAAM,8BAA8B;AAGpC,eAAsB,eAAe,WAAmB,gBAAwB,cAA4B;CACxG,MAAM,uBAAuB,2BAA2B,eAAe;CACvE,MAAM,uBAAuB,IAAI,WAAW,4BAA4B;AACxE,QAAO,gBAAgB,qBAAqB;CAC5C,MAAM,aAAa,MAAM,OAAO,OAAO,QACnC,mBAAmB,sBAAsB,qBAAqB,EAC9D,cACA,IAAI,aAAa,CAAC,OAAO,UAAU,CACtC;CACD,MAAM,WAAW,IAAI,WACjB,qBAAqB,aAAa,qBAAqB,aAAa,WAAW,WAClF;AACD,UAAS,IAAI,IAAI,WAAW,qBAAqB,EAAE,EAAE;AACrD,UAAS,IAAI,IAAI,WAAW,qBAAqB,EAAE,qBAAqB,WAAW;AACnF,UAAS,IAAI,IAAI,WAAW,WAAW,EAAE,qBAAqB,aAAa,qBAAqB,WAAW;AAC3G,QAAO;;AAGX,eAAsB,eAAe,SAAsB,cAA4B;CACnF,MAAM,uBAAuB,QAAQ,MAAM,GAAA,EAAyB;CACpE,MAAM,uBAAuB,QAAQ,MAAA,GAAA,IAET,4BAC3B;CACD,MAAM,aAAa,QAAQ,MAAA,IAA8B,4BAA4B;CACrF,MAAM,kBAAkB,MAAM,OAAO,OAAO,QACxC,mBAAmB,sBAAsB,qBAAqB,EAC9D,cACA,WACH;AAED,QADkB,gBAAgB,CAAC,OAAO,gBAAgB;;AAI9D,SAAS,mBAAmB,gBAA6B,sBAAmC;AACxF,QAAO;EACH,gBAAgB;EAChB,IAAI;EACJ,MAAM;EACN,WAAW;EACd;;AAGL,IAAI;AACJ,SAAS,iBAAiB;AACtB,KAAI,iBAAiB,KAAA,EACjB,gBAAe,IAAI,YAAY,QAAQ;AAE3C,QAAO;;;;ACtDX,eAA8B,6BAAqD;AAC/E,QAAO,MAAM,OAAO,OAAO,YACvB;EACI,MAAM;EACN,YAAY;EACf,EACD,OACA,CAAC,OAAO,CACX;;;;ACRL,eAA8B,sBAA8C;AACxE,QAAO,MAAM,OAAO,OAAO,YACvB;EACI,MAAM;EACN,YAAY;EACf,EACD,OACA,CAAC,aAAa,aAAa,CAC9B;;;;ACPL,SAAwB,0BAA0B,QAAqB;CACnE,IAAI,SAAS;CACb,MAAM,QAAQ,IAAI,WAAW,OAAO;CACpC,MAAM,MAAM,MAAM;AAClB,MAAK,IAAI,KAAK,GAAG,KAAK,KAAK,KACvB,WAAU,OAAO,aAAa,MAAM,IAAI;AAE5C,QAAO,OAAO,KAAK,OAAO;;;;ACH9B,SAAgB,2BAA4C;AACxD,QAAO,sBAAsB,QAAQ,KAAK,MAAM,KAAK,QAAQ,GAAI,MAAmB,CAAC;;AAGzF,SAAgB,sBAAsB,MAA+B;AACjE,KAAI,OAAO,SAAS,OAAO,MACvB,OAAM,IAAI,+BACN,mCAAmC,qCACnC,4DAA4D,KAAK,UACjE,EAAE,MAAM,CACX;AAEL,QAAO;;;;ACjBX,SAAwB,yCAAyC,2BAA2C;AACxG,QAAO,0BAA0B,QAC7B,WACC,OACI;EACG,KAAK;EACL,KAAK;EACL,KAAK;EACR,EAAE,GACV;;;;ACFL,MAAM,cAAc;AAEpB,SAAS,aAAa,YAAoB;AACtC,QACI,WAEK,QAAQ,gBAAgB,GAAG,CAE3B,MAAM,IAAI;;AAIvB,SAAS,aAAa,gBAAwB,eAAwB;CAClE,IAAI,UAAsB;AAC1B,KAAI,eAAe;AACf,MAAI;AACA,aAAU,IAAI,IAAI,cAAc;UAC5B;AACR,MAAI,SAAS,aAAa,SACtB,OAAM,IAAI,+BACN,mCAAmC,iCACnC,2DACH;;AAGT,aAAY,IAAI,IAAI,GAAG,YAAY,IAAI;CACvC,MAAM,WAAW,eAAe,WAAW,IAAI,GAEzC,iBAEA,CAAC,GAAG,aAAa,QAAQ,SAAS,EAAE,GAAG,aAAa,eAAe,CAAC,CAAC,KAAK,IAAI;AACpF,QAAO,IAAI,IAAI,UAAU,QAAQ;;AAGrC,eAA8B,6BAC1B,sBACA,cACA,oBACA,mBAAsC,CAAC,KAAK,EAChC;CACZ,MAAM,kBAAkB,sBAAsB,aAAa;CAE3D,MAAM,aAAa,0BADC,MAAM,OAAO,OAAO,UAAU,OAAO,qBAAqB,CACrB;CACzD,MAAM,MAAM,aAAa,sBAAsB,mBAAmB;AAClE,KAAI,aAAa,IAAI,eAAeC,yCAA+C,WAAW,CAAC;AAC/F,KAAI,aAAa,IAAI,QAAQ,GAAG,kBAAkB;AAClD,kBAAiB,SAAS,YAAY;AAClC,MAAI,aAAa,IAAI,KAAK,QAAQ;GACpC;AACF,QAAO;;AAGX,eAAsB,mCAClB,sBACA,eACA,aACA,oBACA,mBAAsC,CAAC,KAAK,EAChC;CAEZ,MAAM,aAAa,0BADC,MAAM,OAAO,OAAO,UAAU,OAAO,qBAAqB,CACrB;CACzD,MAAM,MAAM,aAAa,uBAAuB,mBAAmB;AACnE,KAAI,aAAa,IAAI,eAAeA,yCAA+C,WAAW,CAAC;AAC/F,KAAI,aAAa,IAAI,aAAa,GAAG,gBAAgB;AACrD,KAAI,aAAa,IAAI,MAAM,GAAGC,iBAAe,aAAa,KAAK,GAAG;AAClE,kBAAiB,SAAS,YAAY;AAClC,MAAI,aAAa,IAAI,KAAK,QAAQ;GACpC;AACF,QAAO;;;;AC1DX,eAAsB,sBAClB,gBACA,cACF;CACE,MAAM,YAAY,KAAK,UAAU,eAAe;CAChD,MAAM,iBAAiB,eAAe;AACtC,QAAO,eAAe,WAAW,gBAAgB,aAAa;;AAGlE,eAAsB,sBAAgC,SAAsB,cAA4B;CACpG,MAAM,YAAY,MAAM,eAAe,SAAS,aAAa;CAC7D,MAAM,iBAAiB,KAAK,MAAM,UAAU;AAC5C,KAAI,OAAO,eAAe,KAAK,gBAAgB,QAAQ,CACnD,OAAM,IAAI,uCACN,eAAe,IACf,eAAe,MAAM,MACrB,eAAe,MAAM,QACxB;AAEL,QAAO;;;;AC3BX,eAA8B,cAC1B,eACA,sBACA,gBACqB;CACrB,MAAM,CAAC,4BAA4B,mBAAmB,MAAM,QAAQ,IAAI,CACpE,OAAO,OAAO,UAAU,OAAO,qBAAqB,EACpD,OAAO,OAAO,UACV,OACA,cAAc,MAAM,GAAA,GAAmC,EACvD;EAAE,MAAM;EAAQ,YAAY;EAAS,EACrC,OACA,EAAE,CACL,CACJ,CAAC;CACF,MAAM,eAAe,MAAM,OAAO,OAAO,WAAW;EAAE,MAAM;EAAQ,QAAQ;EAAiB,EAAE,gBAAgB,IAAI;CACnH,MAAM,gBAAgB,MAAM,OAAO,OAAO,UACtC,OACA,cACA,QACA,OACA,CAAC,YAAY,CAChB;AAaD,QAZ0B,MAAM,OAAO,OAAO,UAC1C;EACI,MAAM;EACN,MAAM;EACN,MAAM,IAAI,WAAW,2BAA2B;EAChD,MAAM,IAAI,YAAY;EACzB,EACD,eACA;EAAE,MAAM;EAAW,QAAQ;EAAK,EAChC,OACA,CAAC,WAAW,UAAU,CACzB;;;;ACtCL,eAA8B,kBAC1B,SACA,cAC0B;CAC1B,MAAM,YAAY,MAAM,eAAe,SAAS,aAAa;CAC7D,MAAM,iBAAiB,KAAK,MAAM,UAAU;CAC5C,IAAI,kBAAmC;AACvC,KAAI,OAAO,eAAe,KAAK,gBAAgB,IAAI,CAC/C,SAAQ,eAAe,GAAvB;EACI,KAAK;EACL,KAAK;EACL,KAAK;AACD,qBAAkB;AAClB;EACJ,KAAK;AACD,qBAAkB;AAClB;EACJ,QACI,OAAM,IAAI,+BACN,mCAAmC,gCACnC,yCAAyC,eAAe,IAC3D;;AAGb,QAA0B,EACtB,kBAAkB,iBACrB;;;;AC1BL,MAAM,UAAU;CACZ,SAAS;CACT,OAAO;CACV;AAGD,SAAS,kBAAkB,GAAiB;AACxC,QAAO;;AAGX,SAAS,aAA0B;AAC/B,QAAO,UAAU,UAAU,QAAQ,WAAW,KAAK,KAAK,QAAQ,UAAU,QAAQ;;AAGtF,SAAS,sBAAsB;AAI3B,QAAO,IAAI,SAAe,SAAS,WAAW;EAC1C,SAAS,UAAU;AACf,gBAAa,UAAU;AACvB,UAAO,oBAAoB,QAAQ,WAAW;;EAElD,SAAS,aAAa;AAClB,YAAS;AACT,YAAS;;AAEb,SAAO,iBAAiB,QAAQ,WAAW;EAC3C,MAAM,YAAY,iBAAiB;AAC/B,YAAS;AACT,WAAQ;KACT,IAAK;GACV;;AAGN,IAAI,SAAmC;AACvC,SAAS,4BAA4B,KAAU;AAC3C,KAAI,UAAU,MAAM;AAChB,WAAS,SAAS,cAAc,SAAS;AACzC,SAAO,MAAM,UAAU;AACvB,WAAS,KAAK,YAAY,OAAO;;AAGrC,QAAO,cAAe,SAAS,OAAO,IAAI,UAAU;;AAGxD,eAAe,kBAAkB,gBAAqB;AAClD,KAAI,eAAe,aAAa,SAI5B,QAAO,SAAS,OAAO,eAAe;KAGtC,KAAI;EACA,MAAM,UAAU,YAAY;AAC5B,UAAQ,SAAR;GACI,KAAK,QAAQ;AAET,gCAA4B,eAAe;AAE3C;GACJ,KAAK,QAAQ,OAAO;IAChB,MAAM,mBAAmB,qBAAqB;AAC9C,WAAO,SAAS,OAAO,eAAe;AACtC,UAAM;AACN;;GAEJ,QACI,mBAAkB,QAAQ;;UAE7B,GAAG;AACR,QAAM,IAAI,+BACN,mCAAmC,wBACnC,sEACH;;;AAKb,eAAsB,aAClB,sBACA,oBACwB;CACxB,MAAM,wBAAwB,0BAA0B;AAMxD,OAAM,kBALiB,MAAM,6BACzB,sBACA,uBACA,mBACH,CACsC;AACvC,QAAO;;;;ACpEX,MAAM,8BAA8B;CAWhC,sBAAsB;EAAC;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;CAC/D,WAAW;CACd;AACD,MAAM,4BAA4B;AAClC,MAAM,4BAA4B;AAgBlC,SAAS,sBAAsB;AAC3B,KAAI,OAAO,WAAW,eAAe,OAAO,oBAAoB,KAC5D,OAAM,IAAI,+BACN,mCAAmC,+BACnC,iFACH;;AAIT,SAAS,gCAAgC,eAAuB;CAC5D,IAAI;AACJ,KAAI;AACA,QAAM,IAAI,IAAI,cAAc;SACxB;AACJ,QAAM,IAAI,+BACN,mCAAmC,iCACnC,sCACH;;AAEL,KAAI,IAAI,aAAa,SACjB,OAAM,IAAI,+BACN,mCAAmC,iCACnC,2DACH;;AAIT,SAAS,+BAA+B,WAAgC;AAEpE,QADa,IAAI,SAAS,UAAU,CACxB,UAAU,GAAsB,MAAM;;AAGtD,SAAS,cAAc,WAA2D;CAC9E,IAAI,QAAQ,IAAI,WAAW,UAAU,EACjC,IAAI,UAAU,YACd,QAAQ,IACR,QAAQ,GACR,SAAS,GACT;AACJ,IAAG;AACC,MAAI,UAAU,KAAK,SAAS,MAAO,OAAM,IAAI,WAAW,0BAA0B;AAClF,MAAI,MAAM;AACV,YAAU,IAAI,QAAU,IAAI;UACvB,KAAK;AAEd,QAAO;EAAE;EAAO;EAAQ;;AAG5B,SAAS,4BAA4B,WAAoC;CACrE,IAAI,EAAE,OAAO,QAAQ,WAAW,cAAc,UAAU;AACxD,QAAO,IAAI,WAAW,UAAU,MAAM,QAAQ,SAAS,OAAO,CAAC;;AAGnE,eAAsB,SAClB,UACA,QACgB;CAChB,MAAM,EAAE,QAAQ,UAAU,MAAM,cAAc,OAAO;AACrD,KAAI;AACA,SAAO,MAAM,SAAS,MAAM,OAAO;WAC7B;AACN,SAAO;;;AAIf,eAAsB,cAAc,QAAqD;AACrF,sBAAqB;CACrB,MAAM,qBAAqB,MAAM,4BAA4B;CAE7D,MAAM,eAAe,kBADD,MAAM,aAAa,mBAAmB,WAAW,QAAQ,QAAQ,CAClC;CACnD,IAAI;CACJ,MAAM,6BAA6B;EAC/B,MAAM,WAAW,CAAC,GAAG,4BAA4B,qBAAqB;AACtE,eAAc,SAAS,SAAS,IAAK,SAAS,OAAO,GAAc,SAAS;KAC5E;CACJ,IAAI,uBAAuB;CAC3B,IAAI,iCAAiC;CACrC,IAAI,QAAe,EAAE,QAAQ,gBAAgB;CAC7C,IAAI;CACJ,IAAI,qBAAqB;CACzB,IAAI;AACJ,QAAO;EACH,aAAa;AACT,UAAO,OAAO;AACd,qBAAkB;;EAEtB,QAAQ,IAAI,SAAS,SAAS,WAAW;GAErC,MAAM,0BAAqD,EAAE;GAC7D,MAAM,aAAa,YAAY;AAC3B,QAAI,MAAM,WAAW,cAAc;AAC/B,aAAQ,KACJ,wFACa,MAAM,OAAO,KAC7B;AACD;;AAEJ,WAAO,oBAAoB,QAAQ,WAAW;IAQ9C,MAAM,EAAE,uBAAuB;IAC/B,MAAM,cAAc,MAAM,qBAAqB;AAC/C,WAAO,KAAK,MAAM,eAAe,YAAY,WAAW,mBAAmB,WAAW,CAAC;AACvF,YAAQ;KACJ,QAAQ;KACR,sBAAsB,mBAAmB;KACzC,gBAAgB,YAAY;KAC/B;;GAEL,MAAM,eAAe,QAAoB;AACrC,QAAI,IAAI,SACJ,SAAQ,EAAE,QAAQ,gBAAgB;QAElC,QACI,IAAI,+BACA,mCAAmC,sBACnC,4CAA4C,IAAI,KAAK,IAAI,IAAI,OAAO,KACpE,EAAE,YAAY,KAAK,CACtB,CACJ;AAEL,mBAAe;;GAEnB,MAAM,cAAc,OAAO,SAAgB;AACvC,mBAAe;AACf,QAAI,KAAK,KAAK,GAAG,uBAAuB,4BAA4B,UAChE,QACI,IAAI,+BACA,mCAAmC,uBACnC,gDAAgD,aAAa,GAChE,CACJ;SACE;AACH,WAAM,IAAI,SAAS,YAAY;MAC3B,MAAM,eAAe,qBAAqB;AAC1C,2BAAqB,OAAO,WAAW,SAAS,aAAa;OAC/D;AACF,8BAAyB;;;GAGjC,MAAM,gBAAgB,OAAO,QAA4B;IACrD,MAAM,iBAAiB,MAAM,IAAI,KAAK,aAAa;AACnD,YAAQ,MAAM,QAAd;KACI,KAAK;AACD,UAAI,eAAe,eAAe,EAC9B,OAAM,IAAI,MAAM,kDAAkD;MAEtE,MAAM,cAAc,MAAM,qBAAqB;AAC/C,aAAO,KAAK,MAAM,eAAe,YAAY,WAAW,mBAAmB,WAAW,CAAC;AACvF,cAAQ;OACJ,QAAQ;OACR,sBAAsB,mBAAmB;OACzC,gBAAgB,YAAY;OAC/B;AACD;KACJ,KAAK;AACD,UAAI;OAEA,MAAM,iBAAiB,+BADM,eAAe,MAAM,GAAA,EAAyB,CACA;AAC3E,WAAI,mBAAmB,iCAAiC,EACpD,OAAM,IAAI,MAAM,gDAAgD;AAEpE,wCAAiC;OACjC,MAAM,iBAAiB,MAAM,sBAAsB,gBAAgB,MAAM,aAAa;OACtF,MAAM,kBAAkB,wBAAwB,eAAe;AAC/D,cAAO,wBAAwB,eAAe;AAC9C,uBAAgB,QAAQ,eAAe,OAAO;eACzC,GAAG;AACR,WAAI,aAAa,wCAAwC;QACrD,MAAM,kBAAkB,wBAAwB,EAAE;AAClD,eAAO,wBAAwB,EAAE;AACjC,wBAAgB,OAAO,EAAE;aAEzB,OAAM;;AAGd;KACJ,KAAK,kBAAkB;AAEnB,UAAI,eAAe,eAAe,GAAG;OACjC,MAAM,cAAc,MAAM,qBAAqB;AAC/C,cAAO,KAAK,MAAM,eAAe,YAAY,WAAW,mBAAmB,WAAW,CAAC;AACvF,eAAQ;QACJ,QAAQ;QACR,sBAAsB,mBAAmB;QACzC,gBAAgB,YAAY;QAC/B;AACD;;MAEJ,MAAM,eAAe,MAAM,cACvB,gBACA,MAAM,sBACN,MAAM,eACT;MACD,MAAM,0BAA0B,eAAe,MAAA,GAAsC;MACrF,MAAM,oBACF,wBAAwB,eAAe,IACjC,OAAO,YAAY;OAKf,MAAM,iBAAiB,+BAJM,wBAAwB,MACjD,GAAA,EAEH,CAC0E;AAC3E,WAAI,mBAAmB,iCAAiC,EACpD,OAAM,IAAI,MAAM,gDAAgD;AAEpE,wCAAiC;AACjC,cAAO,kBAAkB,yBAAyB,aAAa;UAC/D,GACe,EAAE,kBAAkB,UAAU;AAC3D,cAAQ;OAAE,QAAQ;OAAa;OAAc;OAAmB;MAChE,MAAM,SAAS,wBACX,kBAAkB,kBAClB,OAAO,QAAQ,WAAW;OACtB,MAAM,KAAK;AACX,cAAO,KACH,MAAM,sBACF;QACI;QACA,SAAS;QACT;QACA,QAAQ,UAAU,EAAE;QACvB,EACD,aACH,CACJ;AACD,cAAO,IAAI,SAAS,SAAS,WAAW;AACpC,gCAAwB,MAAM;SAC1B,QAAQ,QAAQ;AACZ,kBAAQ,QAAR;WACI,KAAK;WACL,KAAK,eAAe;YAChB,MAAM,EAAE,oBAAoB;AAG5B,gBAAI,mBAAmB,KACnB,KAAI;AACA,6CAAgC,gBAAgB;qBAC3C,GAAG;AACR,oBAAO,EAAE;AACT;;AAGR;;;AAGR,kBAAQ,OAAO;;SAEnB;SACH;SACH;QAET;AACD,2BAAqB;AACrB,UAAI;AACA,eAAQ,OAAO;eACV,GAAG;AACR,cAAO,EAAE;;AAEb;;;;AAIZ,4BAAyB;AACrB,WAAO,oBAAoB,WAAW,cAAc;AACpD,mBAAe;AACf,QAAI,CAAC,mBACD,QACI,IAAI,+BACA,mCAAmC,sBACnC,oDACA,EAAE,YAAY,IAAI,WAAW,sCAAsC,EAAE,CACxE,CACJ;;GAGT,IAAI;GACJ,IAAI;GACJ,MAAM,gCAAgC;AAClC,QAAI,cACA,gBAAe;AAEnB,YAAQ;KAAE,QAAQ;KAAc;KAAoB;AACpD,QAAI,wBAAwB,KAAA,EACxB,uBAAsB,KAAK,KAAK;AAEpC,aAAS,IAAI,UAAU,cAAc,CAAC,0BAA0B,CAAC;AACjE,WAAO,iBAAiB,QAAQ,WAAW;AAC3C,WAAO,iBAAiB,SAAS,YAAY;AAC7C,WAAO,iBAAiB,SAAS,YAAY;AAC7C,WAAO,iBAAiB,WAAW,cAAc;AACjD,0BAAsB;AAClB,YAAO,aAAa,mBAAmB;AACvC,YAAO,oBAAoB,QAAQ,WAAW;AAC9C,YAAO,oBAAoB,SAAS,YAAY;AAChD,YAAO,oBAAoB,SAAS,YAAY;AAChD,YAAO,oBAAoB,WAAW,cAAc;;;AAG5D,4BAAyB;IAC3B;EACL;;AAGL,eAAsB,oBAAoB,QAAgE;AACtG,sBAAqB;CACrB,MAAM,qBAAqB,MAAM,4BAA4B;CAC7D,MAAM,eAAe,SAAS,QAAQ,oBAAoB;CAC1D,IAAI;CACJ,MAAM,6BAA6B;EAC/B,MAAM,WAAW,CAAC,GAAG,4BAA4B,qBAAqB;AACtE,eAAc,SAAS,SAAS,IAAK,SAAS,OAAO,GAAc,SAAS;KAC5E;CACJ,IAAI,uBAAuB;CAC3B,IAAI,iCAAiC;CACrC,IAAI;CACJ,IAAI,QAAqB,EAAE,QAAQ,gBAAgB;CACnD,IAAI;CACJ,IAAI;CACJ,IAAI,cAAc,OAAO,QAAqC;AAC1D,MAAI,YAAY,SAGZ,QAAO,aADU,MAAM,IAAI,KACC,CAAC;MAE7B,QAAO,MAAO,IAAI,KAAc,aAAa;;CAMrD,MAAM,iBAAiB,MAAM,IAAI,SAAc,SAAS,WAAW;EAC/D,MAAM,aAAa,YAAY;AAC3B,OAAI,MAAM,WAAW,cAAc;AAC/B,YAAQ,KACJ,wFACa,MAAM,OAAO,KAC7B;AACD;;AAEJ,OAAI,OAAO,SAAS,SAAS,0BAA0B,CACnD,YAAW;OAEX,YAAW;AAEf,UAAO,oBAAoB,QAAQ,WAAW;;EAElD,MAAM,eAAe,QAAoB;AACrC,OAAI,IAAI,SACJ,SAAQ,EAAE,QAAQ,gBAAgB;OAElC,QACI,IAAI,+BACA,mCAAmC,sBACnC,4CAA4C,IAAI,KAAK,IAAI,IAAI,OAAO,KACpE,EAAE,YAAY,KAAK,CACtB,CACJ;AAEL,kBAAe;;EAEnB,MAAM,cAAc,OAAO,SAAgB;AACvC,kBAAe;AACf,OAAI,KAAK,KAAK,GAAG,uBAAuB,4BAA4B,UAChE,QACI,IAAI,+BACA,mCAAmC,uBACnC,gDAAgD,aAAa,GAChE,CACJ;QACE;AACH,UAAM,IAAI,SAAS,YAAY;KAC3B,MAAM,eAAe,qBAAqB;AAC1C,0BAAqB,OAAO,WAAW,SAAS,aAAa;MAC/D;AACF,6BAAyB;;;EAGjC,MAAM,2BAA2B,OAAO,QAAqC;GACzE,MAAM,iBAAiB,MAAM,YAAY,IAAI;AAC7C,OAAI,MAAM,WAAW,cAAc;AAC/B,QAAI,eAAe,cAAc,EAC7B,OAAM,IAAI,MAAM,kDAAkD;IAEtE,MAAM,cAAc,4BAA4B,eAAe;AAC/D,YAAQ;KACJ,QAAQ;KACK;KAChB;IACD,MAAM,iBAAiB,MAAM,mCACzB,mBAAmB,WACnB,OAAO,qBACP,aACA,QAAQ,QACX;AACD,WAAO,oBAAoB,WAAW,yBAAyB;AAC/D,YAAQ,eAAe;;;EAG/B,IAAI;EACJ,MAAM,gCAAgC;AAClC,OAAI,cACA,gBAAe;AAEnB,WAAQ;IAAE,QAAQ;IAAc;IAAoB;AACpD,OAAI,wBAAwB,KAAA,EACxB,uBAAsB,KAAK,KAAK;AAEpC,YAAS,IAAI,UAAU,cAAc,CAAC,2BAA2B,0BAA0B,CAAC;AAC5F,UAAO,iBAAiB,QAAQ,WAAW;AAC3C,UAAO,iBAAiB,SAAS,YAAY;AAC7C,UAAO,iBAAiB,SAAS,YAAY;AAC7C,UAAO,iBAAiB,WAAW,yBAAyB;AAC5D,yBAAsB;AAClB,WAAO,aAAa,mBAAmB;AACvC,WAAO,oBAAoB,QAAQ,WAAW;AAC9C,WAAO,oBAAoB,SAAS,YAAY;AAChD,WAAO,oBAAoB,SAAS,YAAY;AAChD,WAAO,oBAAoB,WAAW,yBAAyB;;;AAGvE,2BAAyB;GAC3B;CAIF,IAAI,qBAAqB;CACzB,IAAI;AACJ,QAAO;EACH;EACA,aAAa;AACT,UAAO,OAAO;AACd,gBAAa;;EAEjB,QAAQ,IAAI,SAAS,SAAS,WAAW;GAErC,MAAM,0BAAqD,EAAE;GAC7D,MAAM,gBAAgB,OAAO,QAAqC;IAC9D,MAAM,iBAAiB,MAAM,YAAY,IAAI;AAC7C,YAAQ,MAAM,QAAd;KACI,KAAK;AACD,UAAI,eAAe,eAAe,EAC9B,OAAM,IAAI,MAAM,2DAA2D;MAE/E,MAAM,cAAc,MAAM,qBAAqB;MAC/C,MAAM,YAAY,MAAM,eAAe,YAAY,WAAW,mBAAmB,WAAW;AAC5F,UAAI,YAAY,SACZ,QAAO,KAAKC,iBAAe,UAAU,CAAC;UAEtC,QAAO,KAAK,UAAU;AAE1B,cAAQ;OACJ,QAAQ;OACR,sBAAsB,mBAAmB;OACzC,gBAAgB,YAAY;OAC/B;AACD;KACJ,KAAK;AACD,UAAI;OAEA,MAAM,iBAAiB,+BADM,eAAe,MAAM,GAAA,EAAyB,CACA;AAC3E,WAAI,mBAAmB,iCAAiC,EACpD,OAAM,IAAI,MAAM,gDAAgD;AAEpE,wCAAiC;OACjC,MAAM,iBAAiB,MAAM,sBAAsB,gBAAgB,MAAM,aAAa;OACtF,MAAM,kBAAkB,wBAAwB,eAAe;AAC/D,cAAO,wBAAwB,eAAe;AAC9C,uBAAgB,QAAQ,eAAe,OAAO;eACzC,GAAG;AACR,WAAI,aAAa,wCAAwC;QACrD,MAAM,kBAAkB,wBAAwB,EAAE;AAClD,eAAO,wBAAwB,EAAE;AACjC,wBAAgB,OAAO,EAAE;aAEzB,OAAM;;AAGd;KACJ,KAAK,kBAAkB;MACnB,MAAM,eAAe,MAAM,cACvB,gBACA,MAAM,sBACN,MAAM,eACT;MACD,MAAM,0BAA0B,eAAe,MAAA,GAAsC;MACrF,MAAM,oBACF,wBAAwB,eAAe,IACjC,OAAO,YAAY;OAKf,MAAM,iBAAiB,+BAJM,wBAAwB,MACjD,GAAA,EAEH,CAC0E;AAC3E,WAAI,mBAAmB,iCAAiC,EACpD,OAAM,IAAI,MAAM,gDAAgD;AAEpE,wCAAiC;AACjC,cAAO,kBAAkB,yBAAyB,aAAa;UAC/D,GACe,EAAE,kBAAkB,UAAU;AAC3D,cAAQ;OAAE,QAAQ;OAAa;OAAc;OAAmB;MAChE,MAAM,SAAS,wBACX,kBAAkB,kBAClB,OAAO,QAAQ,WAAW;OACtB,MAAM,KAAK;OACX,MAAM,YAAY,MAAM,sBACpB;QACI;QACA,SAAS;QACT;QACA,QAAQ,UAAU,EAAE;QACvB,EACD,aACH;AACD,WAAI,YAAY,SACZ,QAAO,KAAKA,iBAAe,UAAU,CAAC;WAEtC,QAAO,KAAK,UAAU;AAE1B,cAAO,IAAI,SAAS,SAAS,WAAW;AACpC,gCAAwB,MAAM;SAC1B,QAAQ,QAAQ;AACZ,kBAAQ,QAAR;WACI,KAAK;WACL,KAAK,eAAe;YAChB,MAAM,EAAE,oBAAoB;AAG5B,gBAAI,mBAAmB,KACnB,KAAI;AACA,6CAAgC,gBAAgB;qBAC3C,GAAG;AACR,oBAAO,EAAE;AACT;;AAGR;;;AAGR,kBAAQ,OAAO;;SAEnB;SACH;SACH;QAET;AACD,2BAAqB;AACrB,UAAI;AACA,eAAQ,OAAO;eACV,GAAG;AACR,cAAO,EAAE;;AAEb;;;;AAIZ,UAAO,iBAAiB,WAAW,cAAc;AACjD,uBAAoB;AAChB,WAAO,oBAAoB,WAAW,cAAc;AACpD,mBAAe;AACf,QAAI,CAAC,mBACD,QACI,IAAI,+BACA,mCAAmC,sBACnC,oDACA,EAAE,YAAY,IAAI,WAAW,sCAAsC,EAAE,CACxE,CACJ;;IAGX;EACL"}
|
|
1
|
+
{"version":3,"file":"index.browser.js","names":["fromUint8Array","fromUint8Array","getStringWithURLUnsafeBase64CharactersReplaced","fromUint8Array","fromUint8Array"],"sources":["../../src/errors.ts","../../src/base64Utils.ts","../../src/createHelloReq.ts","../../src/base58Utils.ts","../../src/createSIWSMessage.ts","../../src/types.ts","../../src/createMobileWalletProxy.ts","../../src/createSequenceNumberVector.ts","../../src/encryptedMessage.ts","../../src/generateAssociationKeypair.ts","../../src/generateECDHKeypair.ts","../../src/arrayBufferToBase64String.ts","../../src/associationPort.ts","../../src/getStringWithURLUnsafeBase64CharactersReplaced.ts","../../src/getAssociateAndroidIntentURL.ts","../../src/jsonRpcMessage.ts","../../src/parseHelloRsp.ts","../../src/parseSessionProps.ts","../../src/startSession.ts","../../src/transact.ts"],"sourcesContent":["// Typescript `enums` thwart tree-shaking. See https://bargsten.org/jsts/enums/\nexport const SolanaMobileWalletAdapterErrorCode = {\n ERROR_ASSOCIATION_PORT_OUT_OF_RANGE: 'ERROR_ASSOCIATION_PORT_OUT_OF_RANGE',\n ERROR_REFLECTOR_ID_OUT_OF_RANGE: 'ERROR_REFLECTOR_ID_OUT_OF_RANGE',\n ERROR_FORBIDDEN_WALLET_BASE_URL: 'ERROR_FORBIDDEN_WALLET_BASE_URL',\n ERROR_SECURE_CONTEXT_REQUIRED: 'ERROR_SECURE_CONTEXT_REQUIRED',\n ERROR_SESSION_CLOSED: 'ERROR_SESSION_CLOSED',\n ERROR_SESSION_TIMEOUT: 'ERROR_SESSION_TIMEOUT',\n ERROR_WALLET_NOT_FOUND: 'ERROR_WALLET_NOT_FOUND',\n ERROR_INVALID_PROTOCOL_VERSION: 'ERROR_INVALID_PROTOCOL_VERSION',\n ERROR_BROWSER_NOT_SUPPORTED: 'ERROR_BROWSER_NOT_SUPPORTED',\n ERROR_LOOPBACK_ACCESS_BLOCKED: 'ERROR_LOOPBACK_ACCESS_BLOCKED',\n ERROR_ASSOCIATION_CANCELLED: 'ERROR_ASSOCIATION_CANCELLED',\n} as const;\ntype SolanaMobileWalletAdapterErrorCodeEnum =\n (typeof SolanaMobileWalletAdapterErrorCode)[keyof typeof SolanaMobileWalletAdapterErrorCode];\n\ntype ErrorDataTypeMap = {\n [SolanaMobileWalletAdapterErrorCode.ERROR_ASSOCIATION_PORT_OUT_OF_RANGE]: {\n port: number;\n };\n [SolanaMobileWalletAdapterErrorCode.ERROR_REFLECTOR_ID_OUT_OF_RANGE]: {\n id: number;\n };\n [SolanaMobileWalletAdapterErrorCode.ERROR_FORBIDDEN_WALLET_BASE_URL]: undefined;\n [SolanaMobileWalletAdapterErrorCode.ERROR_SECURE_CONTEXT_REQUIRED]: undefined;\n [SolanaMobileWalletAdapterErrorCode.ERROR_SESSION_CLOSED]: {\n closeEvent: CloseEvent;\n };\n [SolanaMobileWalletAdapterErrorCode.ERROR_SESSION_TIMEOUT]: undefined;\n [SolanaMobileWalletAdapterErrorCode.ERROR_WALLET_NOT_FOUND]: undefined;\n [SolanaMobileWalletAdapterErrorCode.ERROR_INVALID_PROTOCOL_VERSION]: undefined;\n [SolanaMobileWalletAdapterErrorCode.ERROR_BROWSER_NOT_SUPPORTED]: undefined;\n [SolanaMobileWalletAdapterErrorCode.ERROR_LOOPBACK_ACCESS_BLOCKED]: undefined;\n [SolanaMobileWalletAdapterErrorCode.ERROR_ASSOCIATION_CANCELLED]: {\n event: Event | undefined;\n };\n};\n\nexport class SolanaMobileWalletAdapterError<TErrorCode extends SolanaMobileWalletAdapterErrorCodeEnum> extends Error {\n data: ErrorDataTypeMap[TErrorCode] | undefined;\n code: TErrorCode;\n constructor(\n ...args: ErrorDataTypeMap[TErrorCode] extends Record<string, unknown>\n ? [code: TErrorCode, message: string, data: ErrorDataTypeMap[TErrorCode]]\n : [code: TErrorCode, message: string]\n ) {\n const [code, message, data] = args;\n super(message);\n this.code = code;\n this.data = data;\n this.name = 'SolanaMobileWalletAdapterError';\n }\n}\n\ntype JSONRPCErrorCode = number;\n\n// Typescript `enums` thwart tree-shaking. See https://bargsten.org/jsts/enums/\nexport const SolanaMobileWalletAdapterProtocolErrorCode = {\n // Keep these in sync with `mobilewalletadapter/common/ProtocolContract.java`.\n ERROR_AUTHORIZATION_FAILED: -1,\n ERROR_INVALID_PAYLOADS: -2,\n ERROR_NOT_SIGNED: -3,\n ERROR_NOT_SUBMITTED: -4,\n ERROR_TOO_MANY_PAYLOADS: -5,\n ERROR_ATTEST_ORIGIN_ANDROID: -100,\n} as const;\ntype SolanaMobileWalletAdapterProtocolErrorCodeEnum =\n (typeof SolanaMobileWalletAdapterProtocolErrorCode)[keyof typeof SolanaMobileWalletAdapterProtocolErrorCode];\n\ntype ProtocolErrorDataTypeMap = {\n [SolanaMobileWalletAdapterProtocolErrorCode.ERROR_AUTHORIZATION_FAILED]: undefined;\n [SolanaMobileWalletAdapterProtocolErrorCode.ERROR_INVALID_PAYLOADS]: undefined;\n [SolanaMobileWalletAdapterProtocolErrorCode.ERROR_NOT_SIGNED]: undefined;\n [SolanaMobileWalletAdapterProtocolErrorCode.ERROR_NOT_SUBMITTED]: undefined;\n [SolanaMobileWalletAdapterProtocolErrorCode.ERROR_TOO_MANY_PAYLOADS]: undefined;\n [SolanaMobileWalletAdapterProtocolErrorCode.ERROR_ATTEST_ORIGIN_ANDROID]: {\n attest_origin_uri: string;\n challenge: string;\n context: string;\n };\n};\n\nexport class SolanaMobileWalletAdapterProtocolError<\n TErrorCode extends SolanaMobileWalletAdapterProtocolErrorCodeEnum,\n> extends Error {\n data: ProtocolErrorDataTypeMap[TErrorCode] | undefined;\n code: TErrorCode | JSONRPCErrorCode;\n jsonRpcMessageId: number;\n constructor(\n ...args: ProtocolErrorDataTypeMap[TErrorCode] extends Record<string, unknown>\n ? [\n jsonRpcMessageId: number,\n code: TErrorCode | JSONRPCErrorCode,\n message: string,\n data: ProtocolErrorDataTypeMap[TErrorCode],\n ]\n : [jsonRpcMessageId: number, code: TErrorCode | JSONRPCErrorCode, message: string]\n ) {\n const [jsonRpcMessageId, code, message, data] = args;\n super(message);\n this.code = code;\n this.data = data;\n this.jsonRpcMessageId = jsonRpcMessageId;\n this.name = 'SolanaMobileWalletAdapterProtocolError';\n }\n}\n","export function encode(input: string): string {\n return window.btoa(input);\n}\n\nexport function fromUint8Array(byteArray: Uint8Array, urlsafe?: boolean): string {\n const base64 = window.btoa(String.fromCharCode.call(null, ...byteArray));\n if (urlsafe) {\n return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n } else return base64;\n}\n\nexport function toUint8Array(base64EncodedByteArray: string): Uint8Array {\n return new Uint8Array(\n window\n .atob(base64EncodedByteArray)\n .split('')\n .map((c) => c.charCodeAt(0)),\n );\n}\n","export default async function createHelloReq(ecdhPublicKey: CryptoKey, associationKeypairPrivateKey: CryptoKey) {\n const publicKeyBuffer = await crypto.subtle.exportKey('raw', ecdhPublicKey);\n const signatureBuffer = await crypto.subtle.sign(\n { hash: 'SHA-256', name: 'ECDSA' },\n associationKeypairPrivateKey,\n publicKeyBuffer,\n );\n const response = new Uint8Array(publicKeyBuffer.byteLength + signatureBuffer.byteLength);\n response.set(new Uint8Array(publicKeyBuffer), 0);\n response.set(new Uint8Array(signatureBuffer), publicKeyBuffer.byteLength);\n return response;\n}\n","import { getBase58Decoder } from '@solana/codecs-strings';\n\nimport { toUint8Array } from './base64Utils.js';\n\nexport function fromUint8Array(byteArray: Uint8Array): string {\n return getBase58Decoder().decode(byteArray);\n}\n\nexport function base64ToBase58(base64EncodedString: string): string {\n return fromUint8Array(toUint8Array(base64EncodedString));\n}\n","import { createSignInMessageText, SolanaSignInInputWithRequiredFields } from '@solana/wallet-standard-util';\n\nimport { encode } from './base64Utils.js';\nimport { SignInPayload } from './types.js';\n\nexport function createSIWSMessage(payload: SolanaSignInInputWithRequiredFields & SignInPayload): string {\n return createSignInMessageText(payload);\n}\n\nexport function createSIWSMessageBase64Url(payload: SolanaSignInInputWithRequiredFields & SignInPayload): string {\n return encode(createSIWSMessage(payload)).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, ''); // convert to base64url encoding;\n}\n","import type { SolanaSignInInput } from '@solana/wallet-standard-features';\nimport type { TransactionVersion } from '@solana/web3.js';\nimport type { IdentifierArray, IdentifierString, WalletAccount, WalletIcon } from '@wallet-standard/core';\n\nexport type Account =\n | Readonly<{\n address: Base64EncodedAddress;\n label?: string;\n icon?: WalletIcon;\n chains?: IdentifierArray;\n features?: IdentifierArray;\n }>\n | WalletAccount;\n\n/**\n * Properties that wallets may present to users when an app\n * asks for authorization to execute privileged methods (see\n * {@link PrivilegedMethods}).\n */\nexport type AppIdentity = Readonly<{\n uri?: string;\n icon?: string;\n name?: string;\n}>;\n\n/**\n * An ephemeral elliptic-curve keypair on the P-256 curve.\n * This public key is used to create the association token.\n * The private key is used during session establishment.\n */\nexport type AssociationKeypair = CryptoKeyPair;\n\nexport type ProtocolVersion = 'v1' | 'legacy';\n\nexport type SessionProperties = Readonly<{\n protocol_version: ProtocolVersion;\n}>;\n\n/**\n * The context returned from a wallet after having authorized a given\n * account for use with a given application. You can cache this and\n * use it later to invoke privileged methods.\n */\nexport type AuthorizationResult = Readonly<{\n accounts: Account[];\n auth_token: AuthToken;\n wallet_uri_base: string;\n sign_in_result?: SignInResult;\n}>;\n\nexport type AuthToken = string;\n\nexport type Base64EncodedAddress = string;\n\ntype Base64EncodedSignature = string;\n\ntype Base64EncodedMessage = string;\n\ntype Base64EncodedSignedMessage = string;\n\ntype Base64EncodedSignedTransaction = string;\n\nexport type Base64EncodedTransaction = string;\n\n/**\n * @deprecated Replaced by the 'chain' parameter, which adds multi-chain capability as per MWA 2.0 spec.\n */\nexport type Cluster = 'devnet' | 'testnet' | 'mainnet-beta';\n\nexport type Chain = IdentifierString | Cluster;\n\nexport type Finality = 'confirmed' | 'finalized' | 'processed';\n\nexport type WalletAssociationConfig = Readonly<{\n baseUri?: string;\n}>;\n\nexport type RemoteWalletAssociationConfig = WalletAssociationConfig &\n Readonly<{\n remoteHostAuthority: string;\n }>;\n\nexport interface AuthorizeAPI {\n /**\n * @deprecated Replaced by updated authorize() method, which adds MWA 2.0 spec support.\n */\n authorize(params: { cluster: Cluster; identity: AppIdentity }): Promise<AuthorizationResult>;\n\n authorize(params: {\n identity: AppIdentity;\n chain?: Chain;\n features?: IdentifierArray;\n addresses?: string[];\n auth_token?: AuthToken;\n sign_in_payload?: SignInPayload;\n }): Promise<AuthorizationResult>;\n}\nexport interface CloneAuthorizationAPI {\n cloneAuthorization(params: { auth_token: AuthToken }): Promise<Readonly<{ auth_token: AuthToken }>>;\n}\nexport interface DeauthorizeAPI {\n deauthorize(params: { auth_token: AuthToken }): Promise<Readonly<Record<string, never>>>;\n}\n\nexport interface GetCapabilitiesAPI {\n getCapabilities(): Promise<\n Readonly<{\n max_transactions_per_request: number;\n max_messages_per_request: number;\n supported_transaction_versions: ReadonlyArray<TransactionVersion>;\n features: IdentifierArray;\n /**\n * @deprecated Replaced by features array.\n */\n supports_clone_authorization: boolean;\n /**\n * @deprecated Replaced by features array.\n */\n supports_sign_and_send_transactions: boolean;\n }>\n >;\n}\nexport interface ReauthorizeAPI {\n reauthorize(params: { auth_token: AuthToken; identity: AppIdentity }): Promise<AuthorizationResult>;\n}\nexport interface SignMessagesAPI {\n signMessages(params: {\n addresses: Base64EncodedAddress[];\n payloads: Base64EncodedMessage[];\n }): Promise<Readonly<{ signed_payloads: Base64EncodedSignedMessage[] }>>;\n}\nexport interface SignTransactionsAPI {\n signTransactions(params: {\n payloads: Base64EncodedTransaction[];\n }): Promise<Readonly<{ signed_payloads: Base64EncodedSignedTransaction[] }>>;\n}\nexport interface SignAndSendTransactionsAPI {\n signAndSendTransactions(params: {\n options?: Readonly<{\n min_context_slot?: number;\n commitment?: string;\n skip_preflight?: boolean;\n max_retries?: number;\n wait_for_commitment_to_send_next_transaction?: boolean;\n }>;\n payloads: Base64EncodedTransaction[];\n }): Promise<Readonly<{ signatures: Base64EncodedSignature[] }>>;\n}\n\nexport interface MobileWallet\n extends\n AuthorizeAPI,\n CloneAuthorizationAPI,\n DeauthorizeAPI,\n GetCapabilitiesAPI,\n ReauthorizeAPI,\n SignMessagesAPI,\n SignTransactionsAPI,\n SignAndSendTransactionsAPI {}\n\nexport interface TerminateSessionAPI {\n terminateSession(): void;\n}\n\nexport interface RemoteMobileWallet extends MobileWallet, TerminateSessionAPI {}\n\n// optional features\nexport const SolanaSignTransactions = 'solana:signTransactions';\nexport const SolanaCloneAuthorization = 'solana:cloneAuthorization';\nexport const SolanaSignInWithSolana = 'solana:signInWithSolana';\n\nexport type SignInPayload =\n | Readonly<{\n domain?: string;\n address?: string;\n statement?: string;\n uri?: string;\n version?: string;\n chainId?: string;\n nonce?: string;\n issuedAt?: string;\n expirationTime?: string;\n notBefore?: string;\n requestId?: string;\n resources?: readonly string[];\n }>\n | SolanaSignInInput;\n\nexport type SignInPayloadWithRequiredFields = Partial<SignInPayload> &\n Required<Pick<SignInPayload, 'domain' | 'address'>>;\n\nexport type SignInResult = Readonly<{\n address: Base64EncodedAddress;\n signed_message: Base64EncodedSignedMessage;\n signature: Base64EncodedSignature;\n signature_type?: string;\n}>;\n\nexport type Scenario = Readonly<{\n wallet: Promise<MobileWallet>;\n close: () => void;\n}>;\n\nexport type RemoteScenario = Scenario &\n Readonly<{\n associationUrl: URL;\n }>;\n","import type { IdentifierArray } from '@wallet-standard/core';\n\nimport { base64ToBase58 } from './base58Utils.js';\nimport { fromUint8Array, toUint8Array } from './base64Utils.js';\nimport { createSIWSMessageBase64Url } from './createSIWSMessage.js';\nimport {\n AuthorizationResult,\n Cluster,\n MobileWallet,\n ProtocolVersion,\n SignInPayload,\n SignInResult,\n SolanaCloneAuthorization,\n SolanaSignTransactions,\n} from './types.js';\n\n/**\n * Creates a {@link MobileWallet} proxy that handles backwards compatibility and API to RPC conversion.\n *\n * @param protocolVersion the protocol version in use for this session/request\n * @param protocolRequestHandler callback function that handles sending the RPC request to the wallet endpoint.\n * @returns a {@link MobileWallet} proxy\n */\nexport default function createMobileWalletProxy<\n TMethodName extends keyof MobileWallet,\n TReturn extends Awaited<ReturnType<MobileWallet[TMethodName]>>,\n>(\n protocolVersion: ProtocolVersion,\n protocolRequestHandler: (method: string, params: Parameters<MobileWallet[TMethodName]>[0]) => Promise<unknown>,\n): MobileWallet {\n return new Proxy<MobileWallet>({} as MobileWallet, {\n get<TMethodName extends keyof MobileWallet>(target: MobileWallet, p: TMethodName) {\n // Wrapping a Proxy in a promise results in the Proxy being asked for a 'then' property so must\n // return null if 'then' is called on this proxy to let the 'resolve()' call know this is not a promise.\n // see: https://stackoverflow.com/a/53890904\n // @ts-expect-error `then` is not part of the wallet API, but the proxy must explicitly return null.\n if (p === 'then') {\n return null;\n }\n if (target[p] == null) {\n target[p] = async function (inputParams: Parameters<MobileWallet[TMethodName]>[0]) {\n const { method, params } = handleMobileWalletRequest(p, inputParams, protocolVersion);\n const result = (await protocolRequestHandler(method, params)) as Awaited<\n ReturnType<MobileWallet[TMethodName]>\n >;\n // if the request tried to sign in but the wallet did not return a sign in result, fallback on message signing\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if (method === 'authorize' && (params as any).sign_in_payload && !(result as any).sign_in_result) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (result as any).sign_in_result = await signInFallback(\n (params as Parameters<MobileWallet['authorize']>[0]).sign_in_payload as SignInPayload,\n result as Awaited<ReturnType<MobileWallet['authorize']>>,\n protocolRequestHandler,\n );\n }\n return handleMobileWalletResponse(p, result, protocolVersion) as TReturn;\n } as MobileWallet[TMethodName];\n }\n return target[p];\n },\n defineProperty() {\n return false;\n },\n deleteProperty() {\n return false;\n },\n });\n}\n\n/**\n * Handles all {@link MobileWallet} API requests and determines the correct MWA RPC method and params to call.\n * This handles backwards compatibility, based on the provided @protocolVersion.\n *\n * @param methodName the name of {@link MobileWallet} method that was called\n * @param methodParams the parameters that were passed to the method\n * @param protocolVersion the protocol version in use for this session/request\n * @returns the RPC request method and params that should be sent to the wallet endpoint\n */\nfunction handleMobileWalletRequest<TMethodName extends keyof MobileWallet>(\n methodName: TMethodName,\n methodParams: Parameters<MobileWallet[TMethodName]>[0],\n protocolVersion: ProtocolVersion,\n) {\n let params = methodParams;\n let method: string = methodName\n .toString()\n .replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`)\n .toLowerCase();\n switch (methodName) {\n case 'authorize': {\n const authorizeParams = params as Parameters<MobileWallet['authorize']>[0] & { cluster?: Cluster };\n let { chain } = authorizeParams;\n if (protocolVersion === 'legacy') {\n switch (chain) {\n case 'solana:testnet': {\n chain = 'testnet';\n break;\n }\n case 'solana:devnet': {\n chain = 'devnet';\n break;\n }\n case 'solana:mainnet': {\n chain = 'mainnet-beta';\n break;\n }\n default: {\n chain = authorizeParams.cluster;\n }\n }\n authorizeParams.cluster = chain as Cluster | undefined;\n params = authorizeParams;\n } else {\n switch (chain) {\n case 'testnet':\n case 'devnet': {\n chain = `solana:${chain}`;\n break;\n }\n case 'mainnet-beta': {\n chain = 'solana:mainnet';\n break;\n }\n }\n authorizeParams.chain = chain;\n params = authorizeParams;\n }\n }\n // fall through\n case 'reauthorize': {\n const { auth_token, identity } = params as Parameters<MobileWallet['authorize' | 'reauthorize']>[0];\n if (auth_token) {\n switch (protocolVersion) {\n case 'legacy': {\n method = 'reauthorize';\n params = { auth_token: auth_token, identity: identity };\n break;\n }\n default: {\n method = 'authorize';\n break;\n }\n }\n }\n break;\n }\n }\n return { method, params };\n}\n\n/**\n * Handles all {@link MobileWallet} API responses and modifies the response for backwards compatibility, if needed\n *\n * @param method the {@link MobileWallet} method that was called\n * @param response the original response that was returned by the method call\n * @param protocolVersion the protocol version in use for this session/request\n * @returns the possibly modified response\n */\nfunction handleMobileWalletResponse<TMethodName extends keyof MobileWallet>(\n method: TMethodName,\n response: Awaited<ReturnType<MobileWallet[TMethodName]>>,\n protocolVersion: ProtocolVersion,\n): Awaited<ReturnType<MobileWallet[TMethodName]>> {\n switch (method) {\n case 'getCapabilities': {\n const capabilities = response as Awaited<ReturnType<MobileWallet['getCapabilities']>>;\n switch (protocolVersion) {\n case 'legacy': {\n const features: `${string}:${string}`[] = [SolanaSignTransactions];\n if (capabilities.supports_clone_authorization === true) {\n features.push(SolanaCloneAuthorization);\n }\n return {\n ...capabilities,\n features: features as IdentifierArray,\n } as Awaited<ReturnType<MobileWallet[TMethodName]>>;\n }\n case 'v1': {\n return {\n ...capabilities,\n supports_sign_and_send_transactions: true,\n supports_clone_authorization: capabilities.features.includes(SolanaCloneAuthorization),\n } as Awaited<ReturnType<MobileWallet[TMethodName]>>;\n }\n }\n }\n }\n return response;\n}\n\nasync function signInFallback(\n signInPayload: SignInPayload,\n authorizationResult: Awaited<ReturnType<MobileWallet['authorize']>>,\n protocolRequestHandler: (method: string, params: Parameters<MobileWallet['signMessages']>[0]) => Promise<unknown>,\n) {\n const domain = signInPayload.domain ?? window.location.host;\n const address = (authorizationResult as AuthorizationResult).accounts[0].address;\n const siwsMessage = createSIWSMessageBase64Url({ ...signInPayload, domain, address: base64ToBase58(address) });\n const signMessageResult = await (protocolRequestHandler('sign_messages', {\n addresses: [address],\n payloads: [siwsMessage],\n }) as Promise<Awaited<ReturnType<MobileWallet['signMessages']>>>);\n\n const signedPayload = toUint8Array(signMessageResult.signed_payloads[0]);\n const signedMessage = fromUint8Array(signedPayload.slice(0, signedPayload.length - 64));\n const signature = fromUint8Array(signedPayload.slice(signedPayload.length - 64));\n const signInResult: SignInResult = {\n address: address,\n // Workaround: some wallets have been observed to only reply with the message signature.\n // This is non-compliant with the spec, but in the interest of maximizing compatibility,\n // detect this case and reuse the original message.\n signed_message: signedMessage.length == 0 ? siwsMessage : signedMessage,\n signature,\n };\n return signInResult;\n}\n","export const SEQUENCE_NUMBER_BYTES = 4;\n\nexport default function createSequenceNumberVector(sequenceNumber: number): Uint8Array {\n if (sequenceNumber >= 4294967296) {\n throw new Error('Outbound sequence number overflow. The maximum sequence number is 32-bytes.');\n }\n const byteArray = new ArrayBuffer(SEQUENCE_NUMBER_BYTES);\n const view = new DataView(byteArray);\n view.setUint32(0, sequenceNumber, /* littleEndian */ false);\n return new Uint8Array(byteArray);\n}\n","import createSequenceNumberVector, { SEQUENCE_NUMBER_BYTES } from './createSequenceNumberVector.js';\nimport { SharedSecret } from './parseHelloRsp.js';\n\nconst INITIALIZATION_VECTOR_BYTES = 12;\nexport const ENCODED_PUBLIC_KEY_LENGTH_BYTES = 65;\n\nexport async function encryptMessage(plaintext: string, sequenceNumber: number, sharedSecret: SharedSecret) {\n const sequenceNumberVector = createSequenceNumberVector(sequenceNumber);\n const initializationVector = new Uint8Array(INITIALIZATION_VECTOR_BYTES);\n crypto.getRandomValues(initializationVector);\n const ciphertext = await crypto.subtle.encrypt(\n getAlgorithmParams(sequenceNumberVector, initializationVector),\n sharedSecret,\n new TextEncoder().encode(plaintext),\n );\n const response = new Uint8Array(\n sequenceNumberVector.byteLength + initializationVector.byteLength + ciphertext.byteLength,\n );\n response.set(new Uint8Array(sequenceNumberVector), 0);\n response.set(new Uint8Array(initializationVector), sequenceNumberVector.byteLength);\n response.set(new Uint8Array(ciphertext), sequenceNumberVector.byteLength + initializationVector.byteLength);\n return response;\n}\n\nexport async function decryptMessage(message: ArrayBuffer, sharedSecret: SharedSecret) {\n const sequenceNumberVector = message.slice(0, SEQUENCE_NUMBER_BYTES);\n const initializationVector = message.slice(\n SEQUENCE_NUMBER_BYTES,\n SEQUENCE_NUMBER_BYTES + INITIALIZATION_VECTOR_BYTES,\n );\n const ciphertext = message.slice(SEQUENCE_NUMBER_BYTES + INITIALIZATION_VECTOR_BYTES);\n const plaintextBuffer = await crypto.subtle.decrypt(\n getAlgorithmParams(sequenceNumberVector, initializationVector),\n sharedSecret,\n ciphertext,\n );\n const plaintext = getUtf8Decoder().decode(plaintextBuffer);\n return plaintext;\n}\n\nfunction getAlgorithmParams(sequenceNumber: ArrayBuffer, initializationVector: ArrayBuffer) {\n return {\n additionalData: sequenceNumber,\n iv: initializationVector,\n name: 'AES-GCM',\n tagLength: 128, // 16 byte tag => 128 bits\n };\n}\n\nlet _utf8Decoder: TextDecoder | undefined;\nfunction getUtf8Decoder() {\n if (_utf8Decoder === undefined) {\n _utf8Decoder = new TextDecoder('utf-8');\n }\n return _utf8Decoder;\n}\n","export default async function generateAssociationKeypair(): Promise<CryptoKeyPair> {\n return await crypto.subtle.generateKey(\n {\n name: 'ECDSA',\n namedCurve: 'P-256',\n },\n false /* extractable */,\n ['sign'] /* keyUsages */,\n );\n}\n","export default async function generateECDHKeypair(): Promise<CryptoKeyPair> {\n return await crypto.subtle.generateKey(\n {\n name: 'ECDH',\n namedCurve: 'P-256',\n },\n false /* extractable */,\n ['deriveKey', 'deriveBits'] /* keyUsages */,\n );\n}\n","// https://stackoverflow.com/a/9458996/802047\nexport default function arrayBufferToBase64String(buffer: ArrayBuffer) {\n let binary = '';\n const bytes = new Uint8Array(buffer);\n const len = bytes.byteLength;\n for (let ii = 0; ii < len; ii++) {\n binary += String.fromCharCode(bytes[ii]);\n }\n return window.btoa(binary);\n}\n","import { SolanaMobileWalletAdapterError, SolanaMobileWalletAdapterErrorCode } from './errors.js';\n\ndeclare const tag: unique symbol;\nexport type AssociationPort = number & { readonly [tag]: 'AssociationPort' };\n\nexport function getRandomAssociationPort(): AssociationPort {\n return assertAssociationPort(49152 + Math.floor(Math.random() * (65535 - 49152 + 1)));\n}\n\nexport function assertAssociationPort(port: number): AssociationPort {\n if (port < 49152 || port > 65535) {\n throw new SolanaMobileWalletAdapterError(\n SolanaMobileWalletAdapterErrorCode.ERROR_ASSOCIATION_PORT_OUT_OF_RANGE,\n `Association port number must be between 49152 and 65535. ${port} given.`,\n { port },\n );\n }\n return port as AssociationPort;\n}\n","export default function getStringWithURLUnsafeCharactersReplaced(unsafeBase64EncodedString: string): string {\n return unsafeBase64EncodedString.replace(\n /[/+=]/g,\n (m) =>\n ({\n '/': '_',\n '+': '-',\n '=': '.',\n })[m] as string,\n );\n}\n","import arrayBufferToBase64String from './arrayBufferToBase64String.js';\nimport { assertAssociationPort } from './associationPort.js';\nimport { fromUint8Array } from './base64Utils.js';\nimport { SolanaMobileWalletAdapterError, SolanaMobileWalletAdapterErrorCode } from './errors.js';\nimport getStringWithURLUnsafeBase64CharactersReplaced from './getStringWithURLUnsafeBase64CharactersReplaced.js';\nimport { ProtocolVersion } from './types.js';\n\nconst INTENT_NAME = 'solana-wallet';\n\nfunction getPathParts(pathString: string) {\n return (\n pathString\n // Strip leading and trailing slashes\n .replace(/(^\\/+|\\/+$)/g, '')\n // Return an array of directories\n .split('/')\n );\n}\n\nfunction getIntentURL(methodPathname: string, intentUrlBase?: string) {\n let baseUrl: URL | null = null;\n if (intentUrlBase) {\n try {\n baseUrl = new URL(intentUrlBase);\n } catch {} // eslint-disable-line no-empty\n if (baseUrl?.protocol !== 'https:') {\n throw new SolanaMobileWalletAdapterError(\n SolanaMobileWalletAdapterErrorCode.ERROR_FORBIDDEN_WALLET_BASE_URL,\n 'Base URLs supplied by wallets must be valid `https` URLs',\n );\n }\n }\n baseUrl ||= new URL(`${INTENT_NAME}:/`);\n const pathname = methodPathname.startsWith('/')\n ? // Method is an absolute path. Replace it wholesale.\n methodPathname\n : // Method is a relative path. Merge it with the existing one.\n [...getPathParts(baseUrl.pathname), ...getPathParts(methodPathname)].join('/');\n return new URL(pathname, baseUrl);\n}\n\nexport default async function getAssociateAndroidIntentURL(\n associationPublicKey: CryptoKey,\n putativePort: number,\n associationURLBase?: string,\n protocolVersions: ProtocolVersion[] = ['v1'],\n): Promise<URL> {\n const associationPort = assertAssociationPort(putativePort);\n const exportedKey = await crypto.subtle.exportKey('raw', associationPublicKey);\n const encodedKey = arrayBufferToBase64String(exportedKey);\n const url = getIntentURL('v1/associate/local', associationURLBase);\n url.searchParams.set('association', getStringWithURLUnsafeBase64CharactersReplaced(encodedKey));\n url.searchParams.set('port', `${associationPort}`);\n protocolVersions.forEach((version) => {\n url.searchParams.set('v', version);\n });\n return url;\n}\n\nexport async function getRemoteAssociateAndroidIntentURL(\n associationPublicKey: CryptoKey,\n hostAuthority: string,\n reflectorId: Uint8Array,\n associationURLBase?: string,\n protocolVersions: ProtocolVersion[] = ['v1'],\n): Promise<URL> {\n const exportedKey = await crypto.subtle.exportKey('raw', associationPublicKey);\n const encodedKey = arrayBufferToBase64String(exportedKey);\n const url = getIntentURL('v1/associate/remote', associationURLBase);\n url.searchParams.set('association', getStringWithURLUnsafeBase64CharactersReplaced(encodedKey));\n url.searchParams.set('reflector', `${hostAuthority}`);\n url.searchParams.set('id', `${fromUint8Array(reflectorId, true)}`);\n protocolVersions.forEach((version) => {\n url.searchParams.set('v', version);\n });\n return url;\n}\n","import { decryptMessage, encryptMessage } from './encryptedMessage.js';\nimport { SolanaMobileWalletAdapterProtocolError } from './errors.js';\nimport { SharedSecret } from './parseHelloRsp.js';\n\ninterface JSONRPCRequest<TParams> {\n id: number;\n jsonrpc: '2.0';\n method: string;\n params: TParams;\n}\n\ntype JSONRPCResponse<TMessage> = {\n id: number;\n jsonrpc: '2.0';\n result: TMessage;\n};\n\nexport async function encryptJsonRpcMessage<TParams>(\n jsonRpcMessage: JSONRPCRequest<TParams>,\n sharedSecret: SharedSecret,\n) {\n const plaintext = JSON.stringify(jsonRpcMessage);\n const sequenceNumber = jsonRpcMessage.id;\n return encryptMessage(plaintext, sequenceNumber, sharedSecret);\n}\n\nexport async function decryptJsonRpcMessage<TMessage>(message: ArrayBuffer, sharedSecret: SharedSecret) {\n const plaintext = await decryptMessage(message, sharedSecret);\n const jsonRpcMessage = JSON.parse(plaintext);\n if (Object.hasOwnProperty.call(jsonRpcMessage, 'error')) {\n throw new SolanaMobileWalletAdapterProtocolError<typeof jsonRpcMessage.error.code>(\n jsonRpcMessage.id,\n jsonRpcMessage.error.code,\n jsonRpcMessage.error.message,\n );\n }\n return jsonRpcMessage as JSONRPCResponse<TMessage>;\n}\n","import { ENCODED_PUBLIC_KEY_LENGTH_BYTES } from './encryptedMessage.js';\n\n/**\n * A secret agreed upon by the app and the wallet. Used as\n * a symmetric key to encrypt and decrypt messages over an\n * unsecured channel.\n */\nexport type SharedSecret = CryptoKey;\n\nexport default async function parseHelloRsp(\n payloadBuffer: ArrayBuffer, // The X9.62-encoded wallet endpoint ephemeral ECDH public keypoint.\n associationPublicKey: CryptoKey,\n ecdhPrivateKey: CryptoKey,\n): Promise<SharedSecret> {\n const [associationPublicKeyBuffer, walletPublicKey] = await Promise.all([\n crypto.subtle.exportKey('raw', associationPublicKey),\n crypto.subtle.importKey(\n 'raw',\n payloadBuffer.slice(0, ENCODED_PUBLIC_KEY_LENGTH_BYTES),\n { name: 'ECDH', namedCurve: 'P-256' },\n false /* extractable */,\n [] /* keyUsages */,\n ),\n ]);\n const sharedSecret = await crypto.subtle.deriveBits({ name: 'ECDH', public: walletPublicKey }, ecdhPrivateKey, 256);\n const ecdhSecretKey = await crypto.subtle.importKey(\n 'raw',\n sharedSecret,\n 'HKDF',\n false /* extractable */,\n ['deriveKey'] /* keyUsages */,\n );\n const aesKeyMaterialVal = await crypto.subtle.deriveKey(\n {\n name: 'HKDF',\n hash: 'SHA-256',\n salt: new Uint8Array(associationPublicKeyBuffer),\n info: new Uint8Array(),\n },\n ecdhSecretKey,\n { name: 'AES-GCM', length: 128 },\n false /* extractable */,\n ['encrypt', 'decrypt'],\n );\n return aesKeyMaterialVal as SharedSecret;\n}\n","import { decryptMessage } from './encryptedMessage.js';\nimport { SolanaMobileWalletAdapterError, SolanaMobileWalletAdapterErrorCode } from './errors.js';\nimport { SharedSecret } from './parseHelloRsp.js';\nimport { ProtocolVersion, SessionProperties } from './types.js';\n\nexport default async function parseSessionProps(\n message: ArrayBuffer,\n sharedSecret: SharedSecret,\n): Promise<SessionProperties> {\n const plaintext = await decryptMessage(message, sharedSecret);\n const jsonProperties = JSON.parse(plaintext);\n let protocolVersion: ProtocolVersion = 'legacy';\n if (Object.hasOwnProperty.call(jsonProperties, 'v')) {\n switch (jsonProperties.v) {\n case 1:\n case '1':\n case 'v1':\n protocolVersion = 'v1';\n break;\n case 'legacy':\n protocolVersion = 'legacy';\n break;\n default:\n throw new SolanaMobileWalletAdapterError(\n SolanaMobileWalletAdapterErrorCode.ERROR_INVALID_PROTOCOL_VERSION,\n `Unknown/unsupported protocol version: ${jsonProperties.v}`,\n );\n }\n }\n return <SessionProperties>{\n protocol_version: protocolVersion,\n };\n}\n","import { AssociationPort, getRandomAssociationPort } from './associationPort.js';\nimport { SolanaMobileWalletAdapterError, SolanaMobileWalletAdapterErrorCode } from './errors.js';\nimport getAssociateAndroidIntentURL from './getAssociateAndroidIntentURL.js';\n\n// Typescript `enums` thwart tree-shaking. See https://bargsten.org/jsts/enums/\nconst Browser = {\n Firefox: 0,\n Other: 1,\n} as const;\ntype BrowserEnum = (typeof Browser)[keyof typeof Browser];\n\nfunction assertUnreachable(x: never): never {\n return x;\n}\n\nfunction getBrowser(): BrowserEnum {\n return navigator.userAgent.indexOf('Firefox/') !== -1 ? Browser.Firefox : Browser.Other;\n}\n\nfunction getDetectionPromise() {\n // Chrome and others silently fail if a custom protocol is not supported.\n // For these, we wait to see if the browser is navigated away from in\n // a reasonable amount of time (ie. the native wallet opened).\n return new Promise<void>((resolve, reject) => {\n function cleanup() {\n clearTimeout(timeoutId);\n window.removeEventListener('blur', handleBlur);\n }\n function handleBlur() {\n cleanup();\n resolve();\n }\n window.addEventListener('blur', handleBlur);\n const timeoutId = setTimeout(() => {\n cleanup();\n reject();\n }, 3000);\n });\n}\n\nlet _frame: HTMLIFrameElement | null = null;\nfunction launchUrlThroughHiddenFrame(url: URL) {\n if (_frame == null) {\n _frame = document.createElement('iframe');\n _frame.style.display = 'none';\n document.body.appendChild(_frame);\n }\n\n _frame.contentWindow!.location.href = url.toString();\n}\n\nasync function launchAssociation(associationUrl: URL) {\n if (associationUrl.protocol === 'https:') {\n // The association URL is an Android 'App Link' or iOS 'Universal Link'.\n // These are regular web URLs that are designed to launch an app if it\n // is installed or load the actual target webpage if not.\n window.location.assign(associationUrl);\n } else {\n // The association URL has a custom protocol (eg. `solana-wallet:`)\n try {\n const browser = getBrowser();\n switch (browser) {\n case Browser.Firefox:\n // If a custom protocol is not supported in Firefox, it throws.\n launchUrlThroughHiddenFrame(associationUrl);\n // If we reached this line, it's supported.\n break;\n case Browser.Other: {\n const detectionPromise = getDetectionPromise();\n window.location.assign(associationUrl);\n await detectionPromise;\n break;\n }\n default:\n assertUnreachable(browser);\n }\n } catch {\n throw new SolanaMobileWalletAdapterError(\n SolanaMobileWalletAdapterErrorCode.ERROR_WALLET_NOT_FOUND,\n 'Found no installed wallet that supports the mobile wallet protocol.',\n );\n }\n }\n}\n\nexport async function startSession(\n associationPublicKey: CryptoKey,\n associationURLBase?: string,\n): Promise<AssociationPort> {\n const randomAssociationPort = getRandomAssociationPort();\n const associationUrl = await getAssociateAndroidIntentURL(\n associationPublicKey,\n randomAssociationPort,\n associationURLBase,\n );\n await launchAssociation(associationUrl);\n return randomAssociationPort;\n}\n","import { fromUint8Array, toUint8Array } from './base64Utils.js';\nimport createHelloReq from './createHelloReq.js';\nimport createMobileWalletProxy from './createMobileWalletProxy.js';\nimport { SEQUENCE_NUMBER_BYTES } from './createSequenceNumberVector.js';\nimport { ENCODED_PUBLIC_KEY_LENGTH_BYTES } from './encryptedMessage.js';\nimport {\n SolanaMobileWalletAdapterError,\n SolanaMobileWalletAdapterErrorCode,\n SolanaMobileWalletAdapterProtocolError,\n} from './errors.js';\nimport generateAssociationKeypair from './generateAssociationKeypair.js';\nimport generateECDHKeypair from './generateECDHKeypair.js';\nimport { getRemoteAssociateAndroidIntentURL } from './getAssociateAndroidIntentURL.js';\nimport { decryptJsonRpcMessage, encryptJsonRpcMessage } from './jsonRpcMessage.js';\nimport parseHelloRsp, { SharedSecret } from './parseHelloRsp.js';\nimport parseSessionProps from './parseSessionProps.js';\nimport { startSession } from './startSession.js';\nimport {\n AssociationKeypair,\n MobileWallet,\n RemoteScenario,\n RemoteWalletAssociationConfig,\n Scenario,\n SessionProperties,\n WalletAssociationConfig,\n} from './types.js';\n\nconst WEBSOCKET_CONNECTION_CONFIG = {\n /**\n * 300 milliseconds is a generally accepted threshold for what someone\n * would consider an acceptable response time for a user interface\n * after having performed a low-attention tapping task. We set the initial\n * interval at which we wait for the wallet to set up the websocket at\n * half this, as per the Nyquist frequency, with a progressive backoff\n * sequence from there. The total wait time is 30s, which allows for the\n * user to be presented with a disambiguation dialog, select a wallet, and\n * for the wallet app to subsequently start.\n */\n retryDelayScheduleMs: [150, 150, 200, 500, 500, 750, 750, 1000],\n timeoutMs: 30000,\n} as const;\nconst WEBSOCKET_PROTOCOL_BINARY = 'com.solana.mobilewalletadapter.v1';\nconst WEBSOCKET_PROTOCOL_BASE64 = 'com.solana.mobilewalletadapter.v1.base64';\ntype PROTOCOL_ENCODING = 'binary' | 'base64';\n\ntype JsonResponsePromises<T> = Record<\n number,\n Readonly<{ resolve: (value?: T | PromiseLike<T>) => void; reject: (reason?: unknown) => void }>\n>;\n\ntype State =\n | { __type: 'connected'; sharedSecret: SharedSecret; sessionProperties: SessionProperties }\n | { __type: 'connecting'; associationKeypair: AssociationKeypair }\n | { __type: 'disconnected' }\n | { __type: 'hello_req_sent'; associationPublicKey: CryptoKey; ecdhPrivateKey: CryptoKey };\n\ntype RemoteState = State | { __type: 'reflector_id_received'; reflectorId: ArrayBuffer };\n\nfunction assertSecureContext() {\n if (typeof window === 'undefined' || window.isSecureContext !== true) {\n throw new SolanaMobileWalletAdapterError(\n SolanaMobileWalletAdapterErrorCode.ERROR_SECURE_CONTEXT_REQUIRED,\n 'The mobile wallet adapter protocol must be used in a secure context (`https`).',\n );\n }\n}\n\nfunction assertSecureEndpointSpecificURI(walletUriBase: string) {\n let url: URL;\n try {\n url = new URL(walletUriBase);\n } catch {\n throw new SolanaMobileWalletAdapterError(\n SolanaMobileWalletAdapterErrorCode.ERROR_FORBIDDEN_WALLET_BASE_URL,\n 'Invalid base URL supplied by wallet',\n );\n }\n if (url.protocol !== 'https:') {\n throw new SolanaMobileWalletAdapterError(\n SolanaMobileWalletAdapterErrorCode.ERROR_FORBIDDEN_WALLET_BASE_URL,\n 'Base URLs supplied by wallets must be valid `https` URLs',\n );\n }\n}\n\nfunction getSequenceNumberFromByteArray(byteArray: ArrayBuffer): number {\n const view = new DataView(byteArray);\n return view.getUint32(0, /* littleEndian */ false);\n}\n\nfunction decodeVarLong(byteArray: ArrayBuffer): { value: number; offset: number } {\n const bytes = new Uint8Array(byteArray);\n const l = byteArray.byteLength;\n const limit = 10;\n let value = 0,\n offset = 0,\n b;\n do {\n if (offset >= l || offset > limit) throw new RangeError('Failed to decode varint');\n b = bytes[offset++];\n value |= (b & 0x7f) << (7 * offset);\n } while (b >= 0x80);\n\n return { value, offset };\n}\n\nfunction getReflectorIdFromByteArray(byteArray: ArrayBuffer): Uint8Array {\n const { value: length, offset } = decodeVarLong(byteArray);\n return new Uint8Array(byteArray.slice(offset, offset + length));\n}\n\nexport async function transact<TReturn>(\n callback: (wallet: MobileWallet) => TReturn,\n config?: WalletAssociationConfig,\n): Promise<TReturn> {\n const { wallet, close } = await startScenario(config);\n try {\n return await callback(await wallet);\n } finally {\n close();\n }\n}\n\nexport async function startScenario(config?: WalletAssociationConfig): Promise<Scenario> {\n assertSecureContext();\n const associationKeypair = await generateAssociationKeypair();\n const sessionPort = await startSession(associationKeypair.publicKey, config?.baseUri);\n const websocketURL = `ws://localhost:${sessionPort}/solana-wallet`;\n let connectionStartTime: number;\n const getNextRetryDelayMs = (() => {\n const schedule = [...WEBSOCKET_CONNECTION_CONFIG.retryDelayScheduleMs];\n return () => (schedule.length > 1 ? (schedule.shift() as number) : schedule[0]);\n })();\n let nextJsonRpcMessageId = 1;\n let lastKnownInboundSequenceNumber = 0;\n let state: State = { __type: 'disconnected' };\n let socket: WebSocket;\n let sessionEstablished = false;\n let handleForceClose: () => void;\n return {\n close: () => {\n socket.close();\n handleForceClose();\n },\n wallet: new Promise((resolve, reject) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const jsonRpcResponsePromises: JsonResponsePromises<any> = {};\n const handleOpen = async () => {\n if (state.__type !== 'connecting') {\n console.warn(\n 'Expected adapter state to be `connecting` at the moment the websocket opens. ' +\n `Got \\`${state.__type}\\`.`,\n );\n return;\n }\n socket.removeEventListener('open', handleOpen);\n\n // previous versions of this library and walletlib incorrectly implemented the MWA session\n // establishment protocol for local connections. The dapp is supposed to wait for the\n // APP_PING message before sending the HELLO_REQ. Instead, the dapp was sending the HELLO_REQ\n // immediately upon connection to the websocket server regardless of wether or not an\n // APP_PING was sent by the wallet/websocket server. We must continue to support this behavior\n // in case the user is using a wallet that has not updated their walletlib implementation.\n const { associationKeypair } = state;\n const ecdhKeypair = await generateECDHKeypair();\n socket.send(await createHelloReq(ecdhKeypair.publicKey, associationKeypair.privateKey));\n state = {\n __type: 'hello_req_sent',\n associationPublicKey: associationKeypair.publicKey,\n ecdhPrivateKey: ecdhKeypair.privateKey,\n };\n };\n const handleClose = (evt: CloseEvent) => {\n if (evt.wasClean) {\n state = { __type: 'disconnected' };\n } else {\n reject(\n new SolanaMobileWalletAdapterError(\n SolanaMobileWalletAdapterErrorCode.ERROR_SESSION_CLOSED,\n `The wallet session dropped unexpectedly (${evt.code}: ${evt.reason}).`,\n { closeEvent: evt },\n ),\n );\n }\n disposeSocket();\n };\n const handleError = async (_evt: Event) => {\n disposeSocket();\n if (Date.now() - connectionStartTime >= WEBSOCKET_CONNECTION_CONFIG.timeoutMs) {\n reject(\n new SolanaMobileWalletAdapterError(\n SolanaMobileWalletAdapterErrorCode.ERROR_SESSION_TIMEOUT,\n `Failed to connect to the wallet websocket at ${websocketURL}.`,\n ),\n );\n } else {\n await new Promise((resolve) => {\n const retryDelayMs = getNextRetryDelayMs();\n retryWaitTimeoutId = window.setTimeout(resolve, retryDelayMs);\n });\n attemptSocketConnection();\n }\n };\n const handleMessage = async (evt: MessageEvent<Blob>) => {\n const responseBuffer = await evt.data.arrayBuffer();\n switch (state.__type) {\n case 'connecting': {\n if (responseBuffer.byteLength !== 0) {\n throw new Error('Encountered unexpected message while connecting');\n }\n const ecdhKeypair = await generateECDHKeypair();\n socket.send(await createHelloReq(ecdhKeypair.publicKey, associationKeypair.privateKey));\n state = {\n __type: 'hello_req_sent',\n associationPublicKey: associationKeypair.publicKey,\n ecdhPrivateKey: ecdhKeypair.privateKey,\n };\n break;\n }\n case 'connected':\n try {\n const sequenceNumberVector = responseBuffer.slice(0, SEQUENCE_NUMBER_BYTES);\n const sequenceNumber = getSequenceNumberFromByteArray(sequenceNumberVector);\n if (sequenceNumber !== lastKnownInboundSequenceNumber + 1) {\n throw new Error('Encrypted message has invalid sequence number');\n }\n lastKnownInboundSequenceNumber = sequenceNumber;\n const jsonRpcMessage = await decryptJsonRpcMessage(responseBuffer, state.sharedSecret);\n const responsePromise = jsonRpcResponsePromises[jsonRpcMessage.id];\n delete jsonRpcResponsePromises[jsonRpcMessage.id];\n responsePromise.resolve(jsonRpcMessage.result);\n } catch (e) {\n if (e instanceof SolanaMobileWalletAdapterProtocolError) {\n const responsePromise = jsonRpcResponsePromises[e.jsonRpcMessageId];\n delete jsonRpcResponsePromises[e.jsonRpcMessageId];\n responsePromise.reject(e);\n } else {\n throw e;\n }\n }\n break;\n case 'hello_req_sent': {\n // if we receive an APP_PING message (empty message), resend the HELLO_REQ (see above)\n if (responseBuffer.byteLength === 0) {\n const ecdhKeypair = await generateECDHKeypair();\n socket.send(await createHelloReq(ecdhKeypair.publicKey, associationKeypair.privateKey));\n state = {\n __type: 'hello_req_sent',\n associationPublicKey: associationKeypair.publicKey,\n ecdhPrivateKey: ecdhKeypair.privateKey,\n };\n break;\n }\n const sharedSecret = await parseHelloRsp(\n responseBuffer,\n state.associationPublicKey,\n state.ecdhPrivateKey,\n );\n const sessionPropertiesBuffer = responseBuffer.slice(ENCODED_PUBLIC_KEY_LENGTH_BYTES);\n const sessionProperties =\n sessionPropertiesBuffer.byteLength !== 0\n ? await (async () => {\n const sequenceNumberVector = sessionPropertiesBuffer.slice(\n 0,\n SEQUENCE_NUMBER_BYTES,\n );\n const sequenceNumber = getSequenceNumberFromByteArray(sequenceNumberVector);\n if (sequenceNumber !== lastKnownInboundSequenceNumber + 1) {\n throw new Error('Encrypted message has invalid sequence number');\n }\n lastKnownInboundSequenceNumber = sequenceNumber;\n return parseSessionProps(sessionPropertiesBuffer, sharedSecret);\n })()\n : <SessionProperties>{ protocol_version: 'legacy' };\n state = { __type: 'connected', sharedSecret, sessionProperties };\n const wallet = createMobileWalletProxy(\n sessionProperties.protocol_version,\n async (method, params) => {\n const id = nextJsonRpcMessageId++;\n socket.send(\n await encryptJsonRpcMessage(\n {\n id,\n jsonrpc: '2.0' as const,\n method,\n params: params ?? {},\n },\n sharedSecret,\n ),\n );\n return new Promise((resolve, reject) => {\n jsonRpcResponsePromises[id] = {\n resolve(result) {\n switch (method) {\n case 'authorize':\n case 'reauthorize': {\n const { wallet_uri_base } = result as Awaited<\n ReturnType<MobileWallet['authorize' | 'reauthorize']>\n >;\n if (wallet_uri_base != null) {\n try {\n assertSecureEndpointSpecificURI(wallet_uri_base);\n } catch (e) {\n reject(e);\n return;\n }\n }\n break;\n }\n }\n resolve(result);\n },\n reject,\n };\n });\n },\n );\n sessionEstablished = true;\n try {\n resolve(wallet);\n } catch (e) {\n reject(e);\n }\n break;\n }\n }\n };\n handleForceClose = () => {\n socket.removeEventListener('message', handleMessage);\n disposeSocket();\n if (!sessionEstablished) {\n reject(\n new SolanaMobileWalletAdapterError(\n SolanaMobileWalletAdapterErrorCode.ERROR_SESSION_CLOSED,\n `The wallet session was closed before connection.`,\n { closeEvent: new CloseEvent('socket was closed before connection') },\n ),\n );\n }\n };\n let disposeSocket: () => void;\n let retryWaitTimeoutId: number;\n const attemptSocketConnection = () => {\n if (disposeSocket) {\n disposeSocket();\n }\n state = { __type: 'connecting', associationKeypair };\n if (connectionStartTime === undefined) {\n connectionStartTime = Date.now();\n }\n socket = new WebSocket(websocketURL, [WEBSOCKET_PROTOCOL_BINARY]);\n socket.addEventListener('open', handleOpen);\n socket.addEventListener('close', handleClose);\n socket.addEventListener('error', handleError);\n socket.addEventListener('message', handleMessage);\n disposeSocket = () => {\n window.clearTimeout(retryWaitTimeoutId);\n socket.removeEventListener('open', handleOpen);\n socket.removeEventListener('close', handleClose);\n socket.removeEventListener('error', handleError);\n socket.removeEventListener('message', handleMessage);\n };\n };\n attemptSocketConnection();\n }),\n };\n}\n\nexport async function startRemoteScenario(config: RemoteWalletAssociationConfig): Promise<RemoteScenario> {\n assertSecureContext();\n const associationKeypair = await generateAssociationKeypair();\n const websocketURL = `wss://${config?.remoteHostAuthority}/reflect`;\n let connectionStartTime: number;\n const getNextRetryDelayMs = (() => {\n const schedule = [...WEBSOCKET_CONNECTION_CONFIG.retryDelayScheduleMs];\n return () => (schedule.length > 1 ? (schedule.shift() as number) : schedule[0]);\n })();\n let nextJsonRpcMessageId = 1;\n let lastKnownInboundSequenceNumber = 0;\n let encoding: PROTOCOL_ENCODING;\n let state: RemoteState = { __type: 'disconnected' };\n let socket: WebSocket;\n let disposeSocket: () => void;\n const decodeBytes = async (evt: MessageEvent<string | Blob>) => {\n if (encoding == 'base64') {\n // base64 encoding\n const message = (await evt.data) as string;\n return toUint8Array(message).buffer;\n } else {\n return await (evt.data as Blob).arrayBuffer();\n }\n };\n // Reflector Connection Phase\n // here we connect to the reflector and wait for the REFLECTOR_ID message\n // so we build the association URL and return that back to the caller\n const associationUrl = await new Promise<URL>((resolve, reject) => {\n const handleOpen = async () => {\n if (state.__type !== 'connecting') {\n console.warn(\n 'Expected adapter state to be `connecting` at the moment the websocket opens. ' +\n `Got \\`${state.__type}\\`.`,\n );\n return;\n }\n if (socket.protocol.includes(WEBSOCKET_PROTOCOL_BASE64)) {\n encoding = 'base64';\n } else {\n encoding = 'binary';\n }\n socket.removeEventListener('open', handleOpen);\n };\n const handleClose = (evt: CloseEvent) => {\n if (evt.wasClean) {\n state = { __type: 'disconnected' };\n } else {\n reject(\n new SolanaMobileWalletAdapterError(\n SolanaMobileWalletAdapterErrorCode.ERROR_SESSION_CLOSED,\n `The wallet session dropped unexpectedly (${evt.code}: ${evt.reason}).`,\n { closeEvent: evt },\n ),\n );\n }\n disposeSocket();\n };\n const handleError = async (_evt: Event) => {\n disposeSocket();\n if (Date.now() - connectionStartTime >= WEBSOCKET_CONNECTION_CONFIG.timeoutMs) {\n reject(\n new SolanaMobileWalletAdapterError(\n SolanaMobileWalletAdapterErrorCode.ERROR_SESSION_TIMEOUT,\n `Failed to connect to the wallet websocket at ${websocketURL}.`,\n ),\n );\n } else {\n await new Promise((resolve) => {\n const retryDelayMs = getNextRetryDelayMs();\n retryWaitTimeoutId = window.setTimeout(resolve, retryDelayMs);\n });\n attemptSocketConnection();\n }\n };\n const handleReflectorIdMessage = async (evt: MessageEvent<string | Blob>) => {\n const responseBuffer = await decodeBytes(evt);\n if (state.__type === 'connecting') {\n if (responseBuffer.byteLength == 0) {\n throw new Error('Encountered unexpected message while connecting');\n }\n const reflectorId = getReflectorIdFromByteArray(responseBuffer);\n state = {\n __type: 'reflector_id_received',\n reflectorId: reflectorId,\n };\n const associationUrl = await getRemoteAssociateAndroidIntentURL(\n associationKeypair.publicKey,\n config.remoteHostAuthority,\n reflectorId,\n config?.baseUri,\n );\n socket.removeEventListener('message', handleReflectorIdMessage);\n resolve(associationUrl);\n }\n };\n let retryWaitTimeoutId: number;\n const attemptSocketConnection = () => {\n if (disposeSocket) {\n disposeSocket();\n }\n state = { __type: 'connecting', associationKeypair };\n if (connectionStartTime === undefined) {\n connectionStartTime = Date.now();\n }\n socket = new WebSocket(websocketURL, [WEBSOCKET_PROTOCOL_BINARY, WEBSOCKET_PROTOCOL_BASE64]);\n socket.addEventListener('open', handleOpen);\n socket.addEventListener('close', handleClose);\n socket.addEventListener('error', handleError);\n socket.addEventListener('message', handleReflectorIdMessage);\n disposeSocket = () => {\n window.clearTimeout(retryWaitTimeoutId);\n socket.removeEventListener('open', handleOpen);\n socket.removeEventListener('close', handleClose);\n socket.removeEventListener('error', handleError);\n socket.removeEventListener('message', handleReflectorIdMessage);\n };\n };\n attemptSocketConnection();\n });\n // Wallet Connection Phase\n // here we return the association URL (containing the reflector ID) to the caller +\n // a promise that will resolve the MobileWallet object once the wallet connects.\n let sessionEstablished = false;\n let handleClose: () => void;\n return {\n associationUrl,\n close: () => {\n socket.close();\n handleClose();\n },\n wallet: new Promise((resolve, reject) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const jsonRpcResponsePromises: JsonResponsePromises<any> = {};\n const handleMessage = async (evt: MessageEvent<string | Blob>) => {\n const responseBuffer = await decodeBytes(evt);\n switch (state.__type) {\n case 'reflector_id_received': {\n if (responseBuffer.byteLength !== 0) {\n throw new Error('Encountered unexpected message while awaiting reflection');\n }\n const ecdhKeypair = await generateECDHKeypair();\n const binaryMsg = await createHelloReq(ecdhKeypair.publicKey, associationKeypair.privateKey);\n if (encoding == 'base64') {\n socket.send(fromUint8Array(binaryMsg));\n } else {\n socket.send(binaryMsg);\n }\n state = {\n __type: 'hello_req_sent',\n associationPublicKey: associationKeypair.publicKey,\n ecdhPrivateKey: ecdhKeypair.privateKey,\n };\n break;\n }\n case 'connected':\n try {\n const sequenceNumberVector = responseBuffer.slice(0, SEQUENCE_NUMBER_BYTES);\n const sequenceNumber = getSequenceNumberFromByteArray(sequenceNumberVector);\n if (sequenceNumber !== lastKnownInboundSequenceNumber + 1) {\n throw new Error('Encrypted message has invalid sequence number');\n }\n lastKnownInboundSequenceNumber = sequenceNumber;\n const jsonRpcMessage = await decryptJsonRpcMessage(responseBuffer, state.sharedSecret);\n const responsePromise = jsonRpcResponsePromises[jsonRpcMessage.id];\n delete jsonRpcResponsePromises[jsonRpcMessage.id];\n responsePromise.resolve(jsonRpcMessage.result);\n } catch (e) {\n if (e instanceof SolanaMobileWalletAdapterProtocolError) {\n const responsePromise = jsonRpcResponsePromises[e.jsonRpcMessageId];\n delete jsonRpcResponsePromises[e.jsonRpcMessageId];\n responsePromise.reject(e);\n } else {\n throw e;\n }\n }\n break;\n case 'hello_req_sent': {\n const sharedSecret = await parseHelloRsp(\n responseBuffer,\n state.associationPublicKey,\n state.ecdhPrivateKey,\n );\n const sessionPropertiesBuffer = responseBuffer.slice(ENCODED_PUBLIC_KEY_LENGTH_BYTES);\n const sessionProperties =\n sessionPropertiesBuffer.byteLength !== 0\n ? await (async () => {\n const sequenceNumberVector = sessionPropertiesBuffer.slice(\n 0,\n SEQUENCE_NUMBER_BYTES,\n );\n const sequenceNumber = getSequenceNumberFromByteArray(sequenceNumberVector);\n if (sequenceNumber !== lastKnownInboundSequenceNumber + 1) {\n throw new Error('Encrypted message has invalid sequence number');\n }\n lastKnownInboundSequenceNumber = sequenceNumber;\n return parseSessionProps(sessionPropertiesBuffer, sharedSecret);\n })()\n : <SessionProperties>{ protocol_version: 'legacy' };\n state = { __type: 'connected', sharedSecret, sessionProperties };\n const wallet = createMobileWalletProxy(\n sessionProperties.protocol_version,\n async (method, params) => {\n const id = nextJsonRpcMessageId++;\n const binaryMsg = await encryptJsonRpcMessage(\n {\n id,\n jsonrpc: '2.0' as const,\n method,\n params: params ?? {},\n },\n sharedSecret,\n );\n if (encoding == 'base64') {\n socket.send(fromUint8Array(binaryMsg));\n } else {\n socket.send(binaryMsg);\n }\n return new Promise((resolve, reject) => {\n jsonRpcResponsePromises[id] = {\n resolve(result) {\n switch (method) {\n case 'authorize':\n case 'reauthorize': {\n const { wallet_uri_base } = result as Awaited<\n ReturnType<MobileWallet['authorize' | 'reauthorize']>\n >;\n if (wallet_uri_base != null) {\n try {\n assertSecureEndpointSpecificURI(wallet_uri_base);\n } catch (e) {\n reject(e);\n return;\n }\n }\n break;\n }\n }\n resolve(result);\n },\n reject,\n };\n });\n },\n );\n sessionEstablished = true;\n try {\n resolve(wallet);\n } catch (e) {\n reject(e);\n }\n break;\n }\n }\n };\n socket.addEventListener('message', handleMessage);\n handleClose = () => {\n socket.removeEventListener('message', handleMessage);\n disposeSocket();\n if (!sessionEstablished) {\n reject(\n new SolanaMobileWalletAdapterError(\n SolanaMobileWalletAdapterErrorCode.ERROR_SESSION_CLOSED,\n `The wallet session was closed before connection.`,\n { closeEvent: new CloseEvent('socket was closed before connection') },\n ),\n );\n }\n };\n }),\n };\n}\n"],"mappings":"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"}
|