@tezos-x/octez.connect-wallet 5.0.0-beta.6 → 5.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/client/WalletClient.js +11 -1
- package/dist/cjs/client/WalletClient.js.map +1 -1
- package/dist/cjs/interceptors/IncomingRequestInterceptor.d.ts +8 -5
- package/dist/cjs/interceptors/IncomingRequestInterceptor.js +85 -92
- package/dist/cjs/interceptors/IncomingRequestInterceptor.js.map +1 -1
- package/dist/cjs/interceptors/OutgoingResponseInterceptor.d.ts +10 -5
- package/dist/cjs/interceptors/OutgoingResponseInterceptor.js +195 -144
- package/dist/cjs/interceptors/OutgoingResponseInterceptor.js.map +1 -1
- package/dist/esm/client/WalletClient.js +11 -1
- package/dist/esm/client/WalletClient.js.map +1 -1
- package/dist/esm/interceptors/IncomingRequestInterceptor.d.ts +8 -5
- package/dist/esm/interceptors/IncomingRequestInterceptor.js +98 -109
- package/dist/esm/interceptors/IncomingRequestInterceptor.js.map +1 -1
- package/dist/esm/interceptors/OutgoingResponseInterceptor.d.ts +10 -5
- package/dist/esm/interceptors/OutgoingResponseInterceptor.js +202 -172
- package/dist/esm/interceptors/OutgoingResponseInterceptor.js.map +1 -1
- package/dist/octez.connect.wallet.min.js +1 -1
- package/package.json +7 -6
|
@@ -13,6 +13,7 @@ exports.WalletClient = void 0;
|
|
|
13
13
|
const octez_connect_core_1 = require("@tezos-x/octez.connect-core");
|
|
14
14
|
const octez_connect_utils_1 = require("@tezos-x/octez.connect-utils");
|
|
15
15
|
const octez_connect_types_1 = require("@tezos-x/octez.connect-types");
|
|
16
|
+
const octez_connect_blockchain_tezos_1 = require("@tezos-x/octez.connect-blockchain-tezos");
|
|
16
17
|
const WalletP2PTransport_1 = require("../transports/WalletP2PTransport");
|
|
17
18
|
const IncomingRequestInterceptor_1 = require("../interceptors/IncomingRequestInterceptor");
|
|
18
19
|
const OutgoingResponseInterceptor_1 = require("../interceptors/OutgoingResponseInterceptor");
|
|
@@ -46,6 +47,11 @@ class WalletClient extends octez_connect_core_1.Client {
|
|
|
46
47
|
this.pendingRequests = [];
|
|
47
48
|
this.permissionManager = new octez_connect_core_1.PermissionManager(this.storage);
|
|
48
49
|
this.appMetadataManager = new octez_connect_core_1.AppMetadataManager(this.storage);
|
|
50
|
+
// Tezos is the default chain: the wrapped-only pipeline needs the
|
|
51
|
+
// registry handler for every request/response, so registration is no
|
|
52
|
+
// longer a consumer obligation. addBlockchain stays public — a later
|
|
53
|
+
// registration under 'tezos' overrides this default.
|
|
54
|
+
this.addBlockchain(new octez_connect_blockchain_tezos_1.TezosBlockchain());
|
|
49
55
|
}
|
|
50
56
|
init() {
|
|
51
57
|
const _super = Object.create(null, {
|
|
@@ -98,6 +104,10 @@ class WalletClient extends octez_connect_core_1.Client {
|
|
|
98
104
|
}
|
|
99
105
|
}
|
|
100
106
|
else {
|
|
107
|
+
// Legacy flat v2 dialect (a v4.8.x dApp): served transparently — the
|
|
108
|
+
// flat request is already the shape wallet apps consume, and the
|
|
109
|
+
// response is emitted back in the same dialect (see
|
|
110
|
+
// OutgoingResponseInterceptor).
|
|
101
111
|
const typedMessage = message;
|
|
102
112
|
if (typedMessage.type === octez_connect_types_1.BeaconMessageType.Disconnect) {
|
|
103
113
|
return this.disconnect(typedMessage.senderId);
|
|
@@ -139,7 +149,7 @@ class WalletClient extends octez_connect_core_1.Client {
|
|
|
139
149
|
backendUrl
|
|
140
150
|
].join(' ');
|
|
141
151
|
const bytes = (0, octez_connect_utils_1.toHex)(constructedString);
|
|
142
|
-
const payloadBytes =
|
|
152
|
+
const payloadBytes = `05` + `01${bytes.length.toString(16).padStart(8, '0')}${bytes}`;
|
|
143
153
|
return {
|
|
144
154
|
challenge,
|
|
145
155
|
payloadToSign: payloadBytes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WalletClient.js","sourceRoot":"","sources":["../../../src/client/WalletClient.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Serializer,\n Client,\n LocalStorage,\n PermissionManager,\n AppMetadataManager,\n getSenderId,\n Logger,\n NOTIFICATION_ORACLE_URL,\n usesWrappedMessages\n} from '@tezos-x/octez.connect-core'\n\nimport { ExposedPromise, toHex } from '@tezos-x/octez.connect-utils'\n\nimport {\n ConnectionContext,\n BeaconRequestMessage,\n BeaconMessageType,\n AcknowledgeResponseInput,\n ExtendedP2PPairingResponse,\n ExtendedPeerInfo,\n PeerInfo,\n DisconnectMessage,\n TransportType,\n BeaconRequestOutputMessage,\n BeaconResponseInputMessage,\n AppMetadata,\n PermissionInfo,\n TransportStatus,\n BeaconMessage,\n BeaconMessageWrapper,\n BeaconBaseMessage,\n StorageKey,\n PushToken,\n PostMessagePairingRequest,\n ExtendedPostMessagePairingRequest,\n P2PPairingRequest,\n ExtendedP2PPairingRequest,\n WalletConnectPairingRequest,\n ExtendedWalletConnectPairingRequest\n} from '@tezos-x/octez.connect-types'\nimport { WalletClientOptions } from './WalletClientOptions'\nimport { WalletP2PTransport } from '../transports/WalletP2PTransport'\nimport { IncomingRequestInterceptor } from '../interceptors/IncomingRequestInterceptor'\nimport { OutgoingResponseInterceptor } from '../interceptors/OutgoingResponseInterceptor'\n\nconst logger = new Logger('WalletClient')\n\n/**\n * @publicapi\n *\n * The WalletClient has to be used in the wallet. It handles all the logic related to connecting to beacon-compatible\n * dapps and handling/responding to requests.\n *\n * @warning For browser extensions: The WalletClient maintains a persistent connection that polls relay servers\n * every 30 seconds. Call `destroy()` when the client is no longer needed to stop polling and free resources.\n * For extensions, consider conditional initialization - only connect when there are existing peers or when\n * a new pairing request arrives. See the README for lifecycle management best practices.\n *\n * @category Wallet\n */\nexport class WalletClient extends Client {\n /**\n * Returns whether or not the transport is connected\n */\n protected readonly _isConnected: ExposedPromise<boolean> = new ExposedPromise()\n public get isConnected(): Promise<boolean> {\n return this._isConnected.promise\n }\n\n private readonly permissionManager: PermissionManager\n private readonly appMetadataManager: AppMetadataManager\n\n /**\n * This array stores pending requests, meaning requests we received and have not yet handled / sent a response.\n */\n private pendingRequests: [\n BeaconRequestMessage | BeaconMessageWrapper<BeaconBaseMessage>,\n ConnectionContext\n ][] = []\n\n constructor(config: WalletClientOptions) {\n super({\n storage: config && config.storage ? config.storage : new LocalStorage(),\n ...config\n })\n this.permissionManager = new PermissionManager(this.storage)\n this.appMetadataManager = new AppMetadataManager(this.storage)\n }\n\n public async init(): Promise<TransportType> {\n const keyPair = await this.keyPair // We wait for keypair here so the P2P Transport creation is not delayed and causing issues\n const p2pTransport = new WalletP2PTransport(\n this.name,\n keyPair,\n this.storage,\n this.matrixNodes,\n this.iconUrl,\n this.appUrl\n )\n\n return super.init(p2pTransport)\n }\n\n /**\n * This method initiates a connection to the P2P network and registers a callback that will be called\n * whenever a message is received.\n *\n * @param newMessageCallback The callback that will be invoked for every message the transport receives.\n */\n public async connect(\n newMessageCallback: (\n message: BeaconRequestOutputMessage,\n connectionContext: ConnectionContext\n ) => void\n ): Promise<void> {\n this.handleResponse = async (\n message: BeaconRequestMessage | BeaconMessageWrapper<BeaconBaseMessage> | DisconnectMessage,\n connectionContext: ConnectionContext\n ): Promise<void> => {\n // Define valid request types that wallets should process\n const validRequestTypes = [\n BeaconMessageType.PermissionRequest,\n BeaconMessageType.OperationRequest,\n BeaconMessageType.SignPayloadRequest,\n BeaconMessageType.BroadcastRequest,\n BeaconMessageType.ProofOfEventChallengeRequest,\n BeaconMessageType.SimulatedProofOfEventChallengeRequest,\n BeaconMessageType.BlockchainRequest,\n BeaconMessageType.ChangeAccountRequest\n ]\n\n if (usesWrappedMessages(message.version)) {\n const typedMessage = message as BeaconMessageWrapper<BeaconBaseMessage>\n\n if (typedMessage.message.type === BeaconMessageType.Disconnect) {\n return this.disconnect(typedMessage.senderId)\n }\n\n // Filter out response types (echoed back from Matrix room)\n if (!validRequestTypes.includes(typedMessage.message.type)) {\n return\n }\n\n if (!this.pendingRequests.some((request) => request[0].id === message.id)) {\n this.pendingRequests.push([typedMessage, connectionContext])\n\n await this.sendAcknowledgeResponse(typedMessage, connectionContext)\n\n await IncomingRequestInterceptor.intercept({\n message: typedMessage,\n connectionInfo: connectionContext,\n appMetadataManager: this.appMetadataManager,\n interceptorCallback: newMessageCallback\n })\n }\n } else {\n const typedMessage = message as BeaconRequestMessage | DisconnectMessage\n\n if (typedMessage.type === BeaconMessageType.Disconnect) {\n return this.disconnect(typedMessage.senderId)\n }\n\n // Filter out response types (echoed back from Matrix room)\n if (!validRequestTypes.includes(typedMessage.type)) {\n return\n }\n\n if (!this.pendingRequests.some((request) => request[0].id === message.id)) {\n this.pendingRequests.push([typedMessage, connectionContext])\n\n if (typedMessage.version && typedMessage.version !== '1') {\n await this.sendAcknowledgeResponse(typedMessage, connectionContext)\n }\n\n await IncomingRequestInterceptor.intercept({\n message: typedMessage,\n connectionInfo: connectionContext,\n appMetadataManager: this.appMetadataManager,\n interceptorCallback: newMessageCallback\n })\n }\n }\n }\n\n return this._connect()\n }\n\n public async getRegisterPushChallenge(\n backendUrl: string,\n accountPublicKey: string,\n oracleUrl: string = NOTIFICATION_ORACLE_URL\n ) {\n // Check if account is already registered\n const challengeResponse = await fetch(`${oracleUrl}/challenge`)\n if (!challengeResponse.ok) {\n throw new Error(\n `getRegisterPushChallenge failed: ${challengeResponse.status} ${challengeResponse.statusText}`\n )\n }\n const challenge: { id: string; timestamp: string } = await challengeResponse.json()\n\n const constructedString = [\n 'Tezos Signed Message: ',\n challenge.id,\n challenge.timestamp,\n accountPublicKey,\n backendUrl\n ].join(' ')\n\n const bytes = toHex(constructedString)\n const payloadBytes = '05' + '01' + bytes.length.toString(16).padStart(8, '0') + bytes\n\n return {\n challenge,\n payloadToSign: payloadBytes\n }\n }\n\n public async registerPush(\n challenge: { id: string; timestamp: string },\n signature: string,\n backendUrl: string,\n accountPublicKey: string,\n protocolIdentifier: string,\n deviceId: string,\n oracleUrl: string = NOTIFICATION_ORACLE_URL\n ): Promise<PushToken> {\n const tokens = await this.storage.get(StorageKey.PUSH_TOKENS)\n const token = tokens.find(\n (el) => el.publicKey === accountPublicKey && el.backendUrl === backendUrl\n )\n if (token) {\n return token\n }\n\n const registerResponse = await fetch(`${oracleUrl}/register`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n name: this.name,\n challenge,\n accountPublicKey,\n signature,\n backendUrl,\n protocolIdentifier,\n deviceId\n })\n })\n if (!registerResponse.ok) {\n throw new Error(\n `registerPush failed: ${registerResponse.status} ${registerResponse.statusText}`\n )\n }\n const register: {\n accessToken: string\n managementToken: string\n message: string\n success: boolean\n } = await registerResponse.json()\n\n const newToken = {\n publicKey: accountPublicKey,\n backendUrl,\n accessToken: register.accessToken,\n managementToken: register.managementToken\n }\n\n tokens.push(newToken)\n\n await this.storage.set(StorageKey.PUSH_TOKENS, tokens)\n\n return newToken\n }\n\n /**\n * The method will attempt to initiate a connection using the active transport.\n */\n public async _connect(attempts: number = 3): Promise<void> {\n const transport: WalletP2PTransport = (await this.transport) as WalletP2PTransport\n if (attempts == 0 || transport.connectionStatus !== TransportStatus.NOT_CONNECTED) {\n return\n }\n\n try {\n await transport.connect()\n } catch (err: any) {\n logger.warn('_connect', err.message)\n await transport.disconnect()\n await this._connect(--attempts)\n return\n }\n\n transport\n .addListener(async (message: unknown, connectionInfo: ConnectionContext) => {\n if (typeof message === 'string') {\n const peer = await this.findPeer(connectionInfo.id)\n const protocolVersion = this.getPeerProtocolVersion(peer)\n const deserializedMessage = (await new Serializer(protocolVersion).deserialize(\n message\n )) as BeaconRequestMessage\n this.handleResponse(deserializedMessage, connectionInfo)\n }\n })\n .catch((error) => logger.log('_connect', error))\n this._isConnected.resolve(true)\n }\n\n /**\n * This method sends a response for a specific request back to the DApp\n *\n * @param message The BeaconResponseMessage that will be sent back to the DApp\n */\n public async respond(message: BeaconResponseInputMessage): Promise<void> {\n logger.log('RESPONSE', message)\n const request = this.pendingRequests.find(\n (pendingRequest) => pendingRequest[0].id === message.id\n )\n if (!request) {\n throw new Error('No matching request found!')\n }\n\n this.pendingRequests = this.pendingRequests.filter(\n (pendingRequest) => pendingRequest[0].id !== message.id\n )\n\n await OutgoingResponseInterceptor.intercept({\n senderId: await getSenderId(await this.beaconId),\n request: request[0],\n message,\n ownAppMetadata: await this.getOwnAppMetadata(),\n permissionManager: this.permissionManager,\n appMetadataManager: this.appMetadataManager,\n interceptorCallback: async (response: BeaconMessage): Promise<void> => {\n await this.respondToMessage(response, request[1])\n },\n blockchains: this.blockchains\n })\n }\n\n public async getAppMetadataList(): Promise<AppMetadata[]> {\n return this.appMetadataManager.getAppMetadataList()\n }\n\n public async getAppMetadata(senderId: string): Promise<AppMetadata | undefined> {\n return this.appMetadataManager.getAppMetadata(senderId)\n }\n\n public async removeAppMetadata(senderId: string): Promise<void> {\n return this.appMetadataManager.removeAppMetadata(senderId)\n }\n\n public async removeAllAppMetadata(): Promise<void> {\n return this.appMetadataManager.removeAllAppMetadata()\n }\n\n public async getPermissions(): Promise<PermissionInfo[]> {\n return this.permissionManager.getPermissions()\n }\n\n public async getPermission(accountIdentifier: string): Promise<PermissionInfo | undefined> {\n return this.permissionManager.getPermission(accountIdentifier)\n }\n\n public async removePermission(accountIdentifier: string, senderId: string): Promise<void> {\n return this.permissionManager.removePermission(accountIdentifier, senderId)\n }\n\n public async removeAllPermissions(): Promise<void> {\n return this.permissionManager.removeAllPermissions()\n }\n\n private async getPeerInfo(peer: PeerInfo): Promise<ExtendedPeerInfo> {\n const senderId = await getSenderId(peer.publicKey)\n const protocolVersion = this.getPeerProtocolVersion(peer)\n\n if (peer instanceof PostMessagePairingRequest || peer instanceof ExtendedPostMessagePairingRequest) {\n const base = peer as PostMessagePairingRequest & {\n icon?: string\n appUrl?: string\n }\n\n return new ExtendedPostMessagePairingRequest(\n base.id,\n base.name,\n base.publicKey,\n base.version,\n senderId,\n protocolVersion,\n base.icon,\n base.appUrl\n )\n }\n\n if (peer instanceof P2PPairingRequest || peer instanceof ExtendedP2PPairingRequest) {\n const base = peer as P2PPairingRequest & {\n relayServer: string\n icon?: string\n appUrl?: string\n }\n\n return new ExtendedP2PPairingRequest(\n base.id,\n base.name,\n base.publicKey,\n base.version,\n base.relayServer,\n senderId,\n protocolVersion,\n base.icon,\n base.appUrl\n )\n }\n\n if (\n peer instanceof WalletConnectPairingRequest ||\n peer instanceof ExtendedWalletConnectPairingRequest\n ) {\n const base = peer as ExtendedWalletConnectPairingRequest & {\n uri: string\n icon?: string\n appUrl?: string\n }\n\n return new ExtendedWalletConnectPairingRequest(\n base.id,\n base.name,\n base.publicKey,\n base.version,\n senderId,\n base.uri,\n protocolVersion,\n base.icon,\n base.appUrl\n )\n }\n\n return {\n ...peer,\n senderId,\n protocolVersion\n }\n }\n\n /**\n * Add a new peer to the known peers\n * @param peer The new peer to add\n */\n public async addPeer(peer: PeerInfo, sendPairingResponse: boolean = true): Promise<void> {\n return (await this.transport).addPeer(await this.getPeerInfo(peer), sendPairingResponse)\n }\n\n public async removePeer(\n peer: ExtendedP2PPairingResponse,\n sendDisconnectToPeer: boolean = false\n ): Promise<void> {\n const removePeerResult = (await this.transport).removePeer(peer)\n\n await this.removePermissionsForPeers([peer])\n\n if (sendDisconnectToPeer) {\n await this.sendDisconnectToPeer(peer)\n }\n\n return removePeerResult\n }\n\n public async removeAllPeers(sendDisconnectToPeers: boolean = false): Promise<void> {\n const peers: ExtendedP2PPairingResponse[] = await (await this.transport).getPeers()\n const removePeerResult = (await this.transport).removeAllPeers()\n\n await this.removePermissionsForPeers(peers)\n\n if (sendDisconnectToPeers) {\n const disconnectPromises = peers.map((peer) => this.sendDisconnectToPeer(peer))\n\n await Promise.all(disconnectPromises)\n }\n\n return removePeerResult\n }\n\n private async removePermissionsForPeers(\n peersToRemove: ExtendedP2PPairingResponse[]\n ): Promise<void> {\n const permissions = await this.permissionManager.getPermissions()\n\n const peerIdsToRemove = peersToRemove.map((peer) => peer.senderId)\n // Remove all permissions with origin of the specified peer\n const permissionsToRemove = permissions.filter((permission) =>\n peerIdsToRemove.includes(permission.appMetadata.senderId)\n )\n const permissionIdentifiersToRemove = permissionsToRemove.map(\n (permissionInfo) => permissionInfo.accountIdentifier\n )\n await this.permissionManager.removePermissions(permissionIdentifiersToRemove)\n }\n\n /**\n * Send an acknowledge message back to the sender\n *\n * @param message The message that was received\n */\n private async sendAcknowledgeResponse(\n request: BeaconRequestMessage | BeaconMessageWrapper<BeaconBaseMessage>,\n connectionContext: ConnectionContext\n ): Promise<void> {\n // Acknowledge the message\n const acknowledgeResponse: AcknowledgeResponseInput = {\n id: request.id,\n type: BeaconMessageType.Acknowledge\n }\n\n await OutgoingResponseInterceptor.intercept({\n senderId: await getSenderId(await this.beaconId),\n request,\n message: acknowledgeResponse,\n ownAppMetadata: await this.getOwnAppMetadata(),\n permissionManager: this.permissionManager,\n appMetadataManager: this.appMetadataManager,\n interceptorCallback: async (response: BeaconMessage): Promise<void> => {\n await this.respondToMessage(response, connectionContext)\n },\n blockchains: this.blockchains\n })\n }\n\n /**\n * An internal method to send a BeaconMessage to the DApp\n *\n * @param response Send a message back to the DApp\n */\n private async respondToMessage(\n response: BeaconMessage,\n connectionContext: ConnectionContext\n ): Promise<void> {\n let peer: PeerInfo | undefined\n if (connectionContext) {\n peer = await this.findPeer(connectionContext.id)\n }\n\n const protocolVersion = this.getPeerProtocolVersion(peer)\n const serializedMessage: string = await new Serializer(protocolVersion).serialize(response)\n if (connectionContext) {\n await (await this.transport).send(serializedMessage, peer)\n } else {\n await (await this.transport).send(serializedMessage)\n }\n }\n\n private async disconnect(senderId: string) {\n const transport = await this.transport\n const peers: ExtendedPeerInfo[] = await transport.getPeers()\n const peer: ExtendedPeerInfo | undefined = peers.find((peerEl) => peerEl.senderId === senderId)\n\n if (peer) {\n await this.removePeer(peer as any)\n }\n\n return\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"WalletClient.js","sourceRoot":"","sources":["../../../src/client/WalletClient.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Serializer,\n Client,\n LocalStorage,\n PermissionManager,\n AppMetadataManager,\n getSenderId,\n Logger,\n NOTIFICATION_ORACLE_URL,\n usesWrappedMessages\n} from '@tezos-x/octez.connect-core'\n\nimport { ExposedPromise, toHex } from '@tezos-x/octez.connect-utils'\n\nimport {\n ConnectionContext,\n BeaconRequestMessage,\n BeaconMessageType,\n AcknowledgeResponseInput,\n ExtendedP2PPairingResponse,\n ExtendedPeerInfo,\n PeerInfo,\n DisconnectMessage,\n TransportType,\n BeaconRequestOutputMessage,\n BeaconResponseInputMessage,\n AppMetadata,\n PermissionInfo,\n TransportStatus,\n BeaconMessage,\n BeaconMessageWrapper,\n BeaconBaseMessage,\n StorageKey,\n PushToken,\n PostMessagePairingRequest,\n ExtendedPostMessagePairingRequest,\n P2PPairingRequest,\n ExtendedP2PPairingRequest,\n WalletConnectPairingRequest,\n ExtendedWalletConnectPairingRequest\n} from '@tezos-x/octez.connect-types'\nimport { TezosBlockchain } from '@tezos-x/octez.connect-blockchain-tezos'\nimport { WalletP2PTransport } from '../transports/WalletP2PTransport'\nimport { IncomingRequestInterceptor } from '../interceptors/IncomingRequestInterceptor'\nimport { OutgoingResponseInterceptor } from '../interceptors/OutgoingResponseInterceptor'\nimport { WalletClientOptions } from './WalletClientOptions'\n\nconst logger = new Logger('WalletClient')\n\n/**\n * @publicapi\n *\n * The WalletClient has to be used in the wallet. It handles all the logic related to connecting to beacon-compatible\n * dapps and handling/responding to requests.\n *\n * @warning For browser extensions: The WalletClient maintains a persistent connection that polls relay servers\n * every 30 seconds. Call `destroy()` when the client is no longer needed to stop polling and free resources.\n * For extensions, consider conditional initialization - only connect when there are existing peers or when\n * a new pairing request arrives. See the README for lifecycle management best practices.\n *\n * @category Wallet\n */\nexport class WalletClient extends Client {\n /**\n * Returns whether or not the transport is connected\n */\n protected readonly _isConnected: ExposedPromise<boolean> = new ExposedPromise()\n public get isConnected(): Promise<boolean> {\n return this._isConnected.promise\n }\n\n private readonly permissionManager: PermissionManager\n private readonly appMetadataManager: AppMetadataManager\n\n /**\n * This array stores pending requests, meaning requests we received and have not yet handled / sent a response.\n */\n private pendingRequests: [\n BeaconRequestMessage | BeaconMessageWrapper<BeaconBaseMessage>,\n ConnectionContext\n ][] = []\n\n constructor(config: WalletClientOptions) {\n super({\n storage: config && config.storage ? config.storage : new LocalStorage(),\n ...config\n })\n this.permissionManager = new PermissionManager(this.storage)\n this.appMetadataManager = new AppMetadataManager(this.storage)\n // Tezos is the default chain: the wrapped-only pipeline needs the\n // registry handler for every request/response, so registration is no\n // longer a consumer obligation. addBlockchain stays public — a later\n // registration under 'tezos' overrides this default.\n this.addBlockchain(new TezosBlockchain())\n }\n\n public async init(): Promise<TransportType> {\n const keyPair = await this.keyPair // We wait for keypair here so the P2P Transport creation is not delayed and causing issues\n const p2pTransport = new WalletP2PTransport(\n this.name,\n keyPair,\n this.storage,\n this.matrixNodes,\n this.iconUrl,\n this.appUrl\n )\n\n return super.init(p2pTransport)\n }\n\n /**\n * This method initiates a connection to the P2P network and registers a callback that will be called\n * whenever a message is received.\n *\n * @param newMessageCallback The callback that will be invoked for every message the transport receives.\n */\n public async connect(\n newMessageCallback: (\n message: BeaconRequestOutputMessage,\n connectionContext: ConnectionContext\n ) => void\n ): Promise<void> {\n this.handleResponse = async (\n message: BeaconRequestMessage | BeaconMessageWrapper<BeaconBaseMessage> | DisconnectMessage,\n connectionContext: ConnectionContext\n ): Promise<void> => {\n // Define valid request types that wallets should process\n const validRequestTypes = [\n BeaconMessageType.PermissionRequest,\n BeaconMessageType.OperationRequest,\n BeaconMessageType.SignPayloadRequest,\n BeaconMessageType.BroadcastRequest,\n BeaconMessageType.ProofOfEventChallengeRequest,\n BeaconMessageType.SimulatedProofOfEventChallengeRequest,\n BeaconMessageType.BlockchainRequest,\n BeaconMessageType.ChangeAccountRequest\n ]\n\n if (usesWrappedMessages(message.version)) {\n const typedMessage = message as BeaconMessageWrapper<BeaconBaseMessage>\n\n if (typedMessage.message.type === BeaconMessageType.Disconnect) {\n return this.disconnect(typedMessage.senderId)\n }\n\n // Filter out response types (echoed back from Matrix room)\n if (!validRequestTypes.includes(typedMessage.message.type)) {\n return\n }\n\n if (!this.pendingRequests.some((request) => request[0].id === message.id)) {\n this.pendingRequests.push([typedMessage, connectionContext])\n\n await this.sendAcknowledgeResponse(typedMessage, connectionContext)\n\n await IncomingRequestInterceptor.intercept({\n message: typedMessage,\n connectionInfo: connectionContext,\n appMetadataManager: this.appMetadataManager,\n interceptorCallback: newMessageCallback\n })\n }\n } else {\n // Legacy flat v2 dialect (a v4.8.x dApp): served transparently — the\n // flat request is already the shape wallet apps consume, and the\n // response is emitted back in the same dialect (see\n // OutgoingResponseInterceptor).\n const typedMessage = message as BeaconRequestMessage | DisconnectMessage\n\n if (typedMessage.type === BeaconMessageType.Disconnect) {\n return this.disconnect(typedMessage.senderId)\n }\n\n // Filter out response types (echoed back from Matrix room)\n if (!validRequestTypes.includes(typedMessage.type)) {\n return\n }\n\n if (!this.pendingRequests.some((request) => request[0].id === message.id)) {\n this.pendingRequests.push([typedMessage, connectionContext])\n\n if (typedMessage.version && typedMessage.version !== '1') {\n await this.sendAcknowledgeResponse(typedMessage, connectionContext)\n }\n\n await IncomingRequestInterceptor.intercept({\n message: typedMessage,\n connectionInfo: connectionContext,\n appMetadataManager: this.appMetadataManager,\n interceptorCallback: newMessageCallback\n })\n }\n }\n }\n\n return this._connect()\n }\n\n public async getRegisterPushChallenge(\n backendUrl: string,\n accountPublicKey: string,\n oracleUrl: string = NOTIFICATION_ORACLE_URL\n ) {\n // Check if account is already registered\n const challengeResponse = await fetch(`${oracleUrl}/challenge`)\n if (!challengeResponse.ok) {\n throw new Error(\n `getRegisterPushChallenge failed: ${challengeResponse.status} ${challengeResponse.statusText}`\n )\n }\n const challenge: { id: string; timestamp: string } = await challengeResponse.json()\n\n const constructedString = [\n 'Tezos Signed Message: ',\n challenge.id,\n challenge.timestamp,\n accountPublicKey,\n backendUrl\n ].join(' ')\n\n const bytes = toHex(constructedString)\n const payloadBytes = `05` + `01${ bytes.length.toString(16).padStart(8, '0') }${bytes}`\n\n return {\n challenge,\n payloadToSign: payloadBytes\n }\n }\n\n public async registerPush(\n challenge: { id: string; timestamp: string },\n signature: string,\n backendUrl: string,\n accountPublicKey: string,\n protocolIdentifier: string,\n deviceId: string,\n oracleUrl: string = NOTIFICATION_ORACLE_URL\n ): Promise<PushToken> {\n const tokens = await this.storage.get(StorageKey.PUSH_TOKENS)\n const token = tokens.find(\n (el) => el.publicKey === accountPublicKey && el.backendUrl === backendUrl\n )\n if (token) {\n return token\n }\n\n const registerResponse = await fetch(`${oracleUrl}/register`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n name: this.name,\n challenge,\n accountPublicKey,\n signature,\n backendUrl,\n protocolIdentifier,\n deviceId\n })\n })\n if (!registerResponse.ok) {\n throw new Error(\n `registerPush failed: ${registerResponse.status} ${registerResponse.statusText}`\n )\n }\n const register: {\n accessToken: string\n managementToken: string\n message: string\n success: boolean\n } = await registerResponse.json()\n\n const newToken = {\n publicKey: accountPublicKey,\n backendUrl,\n accessToken: register.accessToken,\n managementToken: register.managementToken\n }\n\n tokens.push(newToken)\n\n await this.storage.set(StorageKey.PUSH_TOKENS, tokens)\n\n return newToken\n }\n\n /**\n * The method will attempt to initiate a connection using the active transport.\n */\n public async _connect(attempts: number = 3): Promise<void> {\n const transport: WalletP2PTransport = (await this.transport) as WalletP2PTransport\n if (attempts == 0 || transport.connectionStatus !== TransportStatus.NOT_CONNECTED) {\n return\n }\n\n try {\n await transport.connect()\n } catch (err: any) {\n logger.warn('_connect', err.message)\n await transport.disconnect()\n await this._connect(--attempts)\n\n return\n }\n\n transport\n .addListener(async (message: unknown, connectionInfo: ConnectionContext) => {\n if (typeof message === 'string') {\n const peer = await this.findPeer(connectionInfo.id)\n const protocolVersion = this.getPeerProtocolVersion(peer)\n const deserializedMessage = (await new Serializer(protocolVersion).deserialize(\n message\n )) as BeaconRequestMessage\n this.handleResponse(deserializedMessage, connectionInfo)\n }\n })\n .catch((error) => logger.log('_connect', error))\n this._isConnected.resolve(true)\n }\n\n /**\n * This method sends a response for a specific request back to the DApp\n *\n * @param message The BeaconResponseMessage that will be sent back to the DApp\n */\n public async respond(message: BeaconResponseInputMessage): Promise<void> {\n logger.log('RESPONSE', message)\n const request = this.pendingRequests.find(\n (pendingRequest) => pendingRequest[0].id === message.id\n )\n if (!request) {\n throw new Error('No matching request found!')\n }\n\n this.pendingRequests = this.pendingRequests.filter(\n (pendingRequest) => pendingRequest[0].id !== message.id\n )\n\n await OutgoingResponseInterceptor.intercept({\n senderId: await getSenderId(await this.beaconId),\n request: request[0],\n message,\n ownAppMetadata: await this.getOwnAppMetadata(),\n permissionManager: this.permissionManager,\n appMetadataManager: this.appMetadataManager,\n interceptorCallback: async (response: BeaconMessage): Promise<void> => {\n await this.respondToMessage(response, request[1])\n },\n blockchains: this.blockchains\n })\n }\n\n public async getAppMetadataList(): Promise<AppMetadata[]> {\n return this.appMetadataManager.getAppMetadataList()\n }\n\n public async getAppMetadata(senderId: string): Promise<AppMetadata | undefined> {\n return this.appMetadataManager.getAppMetadata(senderId)\n }\n\n public async removeAppMetadata(senderId: string): Promise<void> {\n return this.appMetadataManager.removeAppMetadata(senderId)\n }\n\n public async removeAllAppMetadata(): Promise<void> {\n return this.appMetadataManager.removeAllAppMetadata()\n }\n\n public async getPermissions(): Promise<PermissionInfo[]> {\n return this.permissionManager.getPermissions()\n }\n\n public async getPermission(accountIdentifier: string): Promise<PermissionInfo | undefined> {\n return this.permissionManager.getPermission(accountIdentifier)\n }\n\n public async removePermission(accountIdentifier: string, senderId: string): Promise<void> {\n return this.permissionManager.removePermission(accountIdentifier, senderId)\n }\n\n public async removeAllPermissions(): Promise<void> {\n return this.permissionManager.removeAllPermissions()\n }\n\n private async getPeerInfo(peer: PeerInfo): Promise<ExtendedPeerInfo> {\n const senderId = await getSenderId(peer.publicKey)\n const protocolVersion = this.getPeerProtocolVersion(peer)\n\n if (peer instanceof PostMessagePairingRequest || peer instanceof ExtendedPostMessagePairingRequest) {\n const base = peer as PostMessagePairingRequest & {\n icon?: string\n appUrl?: string\n }\n\n return new ExtendedPostMessagePairingRequest(\n base.id,\n base.name,\n base.publicKey,\n base.version,\n senderId,\n protocolVersion,\n base.icon,\n base.appUrl\n )\n }\n\n if (peer instanceof P2PPairingRequest || peer instanceof ExtendedP2PPairingRequest) {\n const base = peer as P2PPairingRequest & {\n relayServer: string\n icon?: string\n appUrl?: string\n }\n\n return new ExtendedP2PPairingRequest(\n base.id,\n base.name,\n base.publicKey,\n base.version,\n base.relayServer,\n senderId,\n protocolVersion,\n base.icon,\n base.appUrl\n )\n }\n\n if (\n peer instanceof WalletConnectPairingRequest ||\n peer instanceof ExtendedWalletConnectPairingRequest\n ) {\n const base = peer as ExtendedWalletConnectPairingRequest & {\n uri: string\n icon?: string\n appUrl?: string\n }\n\n return new ExtendedWalletConnectPairingRequest(\n base.id,\n base.name,\n base.publicKey,\n base.version,\n senderId,\n base.uri,\n protocolVersion,\n base.icon,\n base.appUrl\n )\n }\n\n return {\n ...peer,\n senderId,\n protocolVersion\n }\n }\n\n /**\n * Add a new peer to the known peers\n * @param peer The new peer to add\n */\n public async addPeer(peer: PeerInfo, sendPairingResponse: boolean = true): Promise<void> {\n return (await this.transport).addPeer(await this.getPeerInfo(peer), sendPairingResponse)\n }\n\n public async removePeer(\n peer: ExtendedP2PPairingResponse,\n sendDisconnectToPeer: boolean = false\n ): Promise<void> {\n const removePeerResult = (await this.transport).removePeer(peer)\n\n await this.removePermissionsForPeers([peer])\n\n if (sendDisconnectToPeer) {\n await this.sendDisconnectToPeer(peer)\n }\n\n return removePeerResult\n }\n\n public async removeAllPeers(sendDisconnectToPeers: boolean = false): Promise<void> {\n const peers: ExtendedP2PPairingResponse[] = await (await this.transport).getPeers()\n const removePeerResult = (await this.transport).removeAllPeers()\n\n await this.removePermissionsForPeers(peers)\n\n if (sendDisconnectToPeers) {\n const disconnectPromises = peers.map((peer) => this.sendDisconnectToPeer(peer))\n\n await Promise.all(disconnectPromises)\n }\n\n return removePeerResult\n }\n\n private async removePermissionsForPeers(\n peersToRemove: ExtendedP2PPairingResponse[]\n ): Promise<void> {\n const permissions = await this.permissionManager.getPermissions()\n\n const peerIdsToRemove = peersToRemove.map((peer) => peer.senderId)\n // Remove all permissions with origin of the specified peer\n const permissionsToRemove = permissions.filter((permission) =>\n peerIdsToRemove.includes(permission.appMetadata.senderId)\n )\n const permissionIdentifiersToRemove = permissionsToRemove.map(\n (permissionInfo) => permissionInfo.accountIdentifier\n )\n await this.permissionManager.removePermissions(permissionIdentifiersToRemove)\n }\n\n /**\n * Send an acknowledge message back to the sender\n *\n * @param message The message that was received\n */\n private async sendAcknowledgeResponse(\n request: BeaconRequestMessage | BeaconMessageWrapper<BeaconBaseMessage>,\n connectionContext: ConnectionContext\n ): Promise<void> {\n // Acknowledge the message\n const acknowledgeResponse: AcknowledgeResponseInput = {\n id: request.id,\n type: BeaconMessageType.Acknowledge\n }\n\n await OutgoingResponseInterceptor.intercept({\n senderId: await getSenderId(await this.beaconId),\n request,\n message: acknowledgeResponse,\n ownAppMetadata: await this.getOwnAppMetadata(),\n permissionManager: this.permissionManager,\n appMetadataManager: this.appMetadataManager,\n interceptorCallback: async (response: BeaconMessage): Promise<void> => {\n await this.respondToMessage(response, connectionContext)\n },\n blockchains: this.blockchains\n })\n }\n\n /**\n * An internal method to send a BeaconMessage to the DApp\n *\n * @param response Send a message back to the DApp\n */\n private async respondToMessage(\n response: BeaconMessage,\n connectionContext: ConnectionContext\n ): Promise<void> {\n let peer: PeerInfo | undefined\n if (connectionContext) {\n peer = await this.findPeer(connectionContext.id)\n }\n\n const protocolVersion = this.getPeerProtocolVersion(peer)\n const serializedMessage: string = await new Serializer(protocolVersion).serialize(response)\n if (connectionContext) {\n await (await this.transport).send(serializedMessage, peer)\n } else {\n await (await this.transport).send(serializedMessage)\n }\n }\n\n private async disconnect(senderId: string) {\n const transport = await this.transport\n const peers: ExtendedPeerInfo[] = await transport.getPeers()\n const peer: ExtendedPeerInfo | undefined = peers.find((peerEl) => peerEl.senderId === senderId)\n\n if (peer) {\n await this.removePeer(peer as any)\n }\n\n return\n }\n}\n"]}
|
|
@@ -1,15 +1,18 @@
|
|
|
1
|
-
import { BeaconRequestOutputMessage, ConnectionContext,
|
|
1
|
+
import { BeaconRequestOutputMessage, ConnectionContext, BeaconMessageWrapper, BeaconRequestMessage, BeaconBaseMessage } from '@tezos-x/octez.connect-types';
|
|
2
2
|
import { AppMetadataManager } from '@tezos-x/octez.connect-core';
|
|
3
3
|
interface IncomingRequestInterceptorOptions {
|
|
4
4
|
message: BeaconRequestMessage | BeaconMessageWrapper<BeaconBaseMessage>;
|
|
5
5
|
connectionInfo: ConnectionContext;
|
|
6
6
|
appMetadataManager: AppMetadataManager;
|
|
7
|
-
interceptorCallback(message: BeaconRequestOutputMessage, connectionInfo: ConnectionContext)
|
|
7
|
+
interceptorCallback: (message: BeaconRequestOutputMessage, connectionInfo: ConnectionContext) => void;
|
|
8
8
|
}
|
|
9
9
|
/**
|
|
10
10
|
* @internalapi
|
|
11
11
|
*
|
|
12
|
-
* The IncomingRequestInterceptor is used in the WalletClient to intercept an
|
|
12
|
+
* The IncomingRequestInterceptor is used in the WalletClient to intercept an
|
|
13
|
+
* incoming (wrapped) request, enrich it with app metadata, and — for Tezos
|
|
14
|
+
* payloads — normalize it to the flat request shape wallet apps consume, so
|
|
15
|
+
* apps never see envelopes or version strings.
|
|
13
16
|
*/
|
|
14
17
|
export declare class IncomingRequestInterceptor {
|
|
15
18
|
/**
|
|
@@ -18,8 +21,8 @@ export declare class IncomingRequestInterceptor {
|
|
|
18
21
|
* @param config
|
|
19
22
|
*/
|
|
20
23
|
static intercept(config: IncomingRequestInterceptorOptions): Promise<void>;
|
|
24
|
+
private static handleFlatMessage;
|
|
21
25
|
private static getAppMetadata;
|
|
22
|
-
private static
|
|
23
|
-
private static handleV3Message;
|
|
26
|
+
private static handleWrappedMessage;
|
|
24
27
|
}
|
|
25
28
|
export {};
|
|
@@ -13,10 +13,27 @@ exports.IncomingRequestInterceptor = void 0;
|
|
|
13
13
|
const octez_connect_types_1 = require("@tezos-x/octez.connect-types");
|
|
14
14
|
const octez_connect_core_1 = require("@tezos-x/octez.connect-core");
|
|
15
15
|
const logger = new octez_connect_core_1.Logger('IncomingRequestInterceptor');
|
|
16
|
+
// Chain identifiers whose wrapped payloads are normalized back to the flat
|
|
17
|
+
// request shapes Tezos wallet apps have always consumed ('xtz' is the
|
|
18
|
+
// pre-rename legacy identifier). Other chains (e.g. substrate) keep the
|
|
19
|
+
// wrapped pass-through of the generic API.
|
|
20
|
+
const TEZOS_IDENTIFIERS = ['tezos', 'xtz'];
|
|
21
|
+
// Wrapped Tezos blockchainData discriminators → the flat BeaconMessageType
|
|
22
|
+
// the wallet app receives. Values reuse the pre-fork wire strings.
|
|
23
|
+
const TEZOS_PAYLOAD_TO_FLAT_TYPE = {
|
|
24
|
+
operation_request: octez_connect_types_1.BeaconMessageType.OperationRequest,
|
|
25
|
+
sign_payload_request: octez_connect_types_1.BeaconMessageType.SignPayloadRequest,
|
|
26
|
+
broadcast_request: octez_connect_types_1.BeaconMessageType.BroadcastRequest,
|
|
27
|
+
proof_of_event_challenge_request: octez_connect_types_1.BeaconMessageType.ProofOfEventChallengeRequest,
|
|
28
|
+
simulated_proof_of_event_challenge_request: octez_connect_types_1.BeaconMessageType.SimulatedProofOfEventChallengeRequest
|
|
29
|
+
};
|
|
16
30
|
/**
|
|
17
31
|
* @internalapi
|
|
18
32
|
*
|
|
19
|
-
* The IncomingRequestInterceptor is used in the WalletClient to intercept an
|
|
33
|
+
* The IncomingRequestInterceptor is used in the WalletClient to intercept an
|
|
34
|
+
* incoming (wrapped) request, enrich it with app metadata, and — for Tezos
|
|
35
|
+
* payloads — normalize it to the flat request shape wallet apps consume, so
|
|
36
|
+
* apps never see envelopes or version strings.
|
|
20
37
|
*/
|
|
21
38
|
class IncomingRequestInterceptor {
|
|
22
39
|
/**
|
|
@@ -27,12 +44,43 @@ class IncomingRequestInterceptor {
|
|
|
27
44
|
static intercept(config) {
|
|
28
45
|
return __awaiter(this, void 0, void 0, function* () {
|
|
29
46
|
logger.log('INTERCEPTING REQUEST', config.message);
|
|
30
|
-
|
|
31
|
-
|
|
47
|
+
// Negotiated wire: flat '2' arrivals are the legacy dialect (a v4.8.x
|
|
48
|
+
// dApp) and already carry the shape wallet apps consume — they only need
|
|
49
|
+
// enrichment. Wrapped arrivals (v3+) are unwrapped and, for Tezos
|
|
50
|
+
// payloads, normalized to the same flat shapes. Anything else (absent or
|
|
51
|
+
// malformed version — untrusted input) is dropped, never dispatched.
|
|
52
|
+
if ((0, octez_connect_core_1.usesWrappedMessages)(config.message.version)) {
|
|
53
|
+
yield IncomingRequestInterceptor.handleWrappedMessage(config);
|
|
54
|
+
}
|
|
55
|
+
else if (config.message.version === '2') {
|
|
56
|
+
yield IncomingRequestInterceptor.handleFlatMessage(config);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
logger.warn('intercept', `Dropping message with unsupported version ${JSON.stringify(config.message.version)}`);
|
|
32
60
|
}
|
|
33
|
-
|
|
34
|
-
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
// Legacy flat v2 dialect: enrich with app metadata and pass through — the
|
|
64
|
+
// output shape is identical to the wrapped path's flat normalization, so
|
|
65
|
+
// wallet apps cannot tell which dialect the dApp spoke.
|
|
66
|
+
static handleFlatMessage(config) {
|
|
67
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
68
|
+
const { connectionInfo, appMetadataManager, interceptorCallback } = config;
|
|
69
|
+
const message = config.message;
|
|
70
|
+
if (message.type === octez_connect_types_1.BeaconMessageType.PermissionRequest) {
|
|
71
|
+
// TODO: Remove v1 compatibility in later version
|
|
72
|
+
let dappMetadata = message.appMetadata;
|
|
73
|
+
const legacyBeaconId = dappMetadata.beaconId;
|
|
74
|
+
if (legacyBeaconId && !dappMetadata.senderId) {
|
|
75
|
+
dappMetadata = Object.assign(Object.assign({}, dappMetadata), { senderId: legacyBeaconId });
|
|
76
|
+
delete dappMetadata.beaconId;
|
|
77
|
+
}
|
|
78
|
+
yield appMetadataManager.addAppMetadata(dappMetadata);
|
|
79
|
+
interceptorCallback(Object.assign(Object.assign({}, message), { appMetadata: dappMetadata }), connectionInfo);
|
|
80
|
+
return;
|
|
35
81
|
}
|
|
82
|
+
const appMetadata = yield IncomingRequestInterceptor.getAppMetadata(appMetadataManager, message.senderId);
|
|
83
|
+
interceptorCallback(Object.assign({ appMetadata }, message), connectionInfo);
|
|
36
84
|
});
|
|
37
85
|
}
|
|
38
86
|
static getAppMetadata(appMetadataManager, senderId) {
|
|
@@ -44,110 +92,55 @@ class IncomingRequestInterceptor {
|
|
|
44
92
|
return appMetadata;
|
|
45
93
|
});
|
|
46
94
|
}
|
|
47
|
-
static
|
|
48
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
49
|
-
const { message, connectionInfo, appMetadataManager, interceptorCallback } = config;
|
|
50
|
-
switch (message.type) {
|
|
51
|
-
case octez_connect_types_1.BeaconMessageType.PermissionRequest:
|
|
52
|
-
{
|
|
53
|
-
logger.log('PERMISSION REQUEST V*', message);
|
|
54
|
-
// TODO: Remove v1 compatibility in later version
|
|
55
|
-
if (message.appMetadata.beaconId && !message.appMetadata.senderId) {
|
|
56
|
-
message.appMetadata.senderId = message.appMetadata.beaconId;
|
|
57
|
-
delete message.appMetadata.beaconId;
|
|
58
|
-
}
|
|
59
|
-
yield appMetadataManager.addAppMetadata(message.appMetadata);
|
|
60
|
-
const request = message;
|
|
61
|
-
interceptorCallback(request, connectionInfo);
|
|
62
|
-
}
|
|
63
|
-
break;
|
|
64
|
-
case octez_connect_types_1.BeaconMessageType.OperationRequest:
|
|
65
|
-
{
|
|
66
|
-
const appMetadata = yield IncomingRequestInterceptor.getAppMetadata(appMetadataManager, message.senderId);
|
|
67
|
-
const request = Object.assign({ appMetadata }, message);
|
|
68
|
-
interceptorCallback(request, connectionInfo);
|
|
69
|
-
}
|
|
70
|
-
break;
|
|
71
|
-
case octez_connect_types_1.BeaconMessageType.SignPayloadRequest:
|
|
72
|
-
{
|
|
73
|
-
const appMetadata = yield IncomingRequestInterceptor.getAppMetadata(appMetadataManager, message.senderId);
|
|
74
|
-
const request = Object.assign({ appMetadata }, message);
|
|
75
|
-
interceptorCallback(request, connectionInfo);
|
|
76
|
-
}
|
|
77
|
-
break;
|
|
78
|
-
// TODO: ENCRYPTION
|
|
79
|
-
// case BeaconMessageType.EncryptPayloadRequest:
|
|
80
|
-
// {
|
|
81
|
-
// const appMetadata: AppMetadata = await IncomingRequestInterceptor.getAppMetadata(
|
|
82
|
-
// appMetadataManager,
|
|
83
|
-
// message.senderId
|
|
84
|
-
// )
|
|
85
|
-
// const request: EncryptPayloadRequestOutput = {
|
|
86
|
-
// appMetadata,
|
|
87
|
-
// ...message
|
|
88
|
-
// }
|
|
89
|
-
// interceptorCallback(request, connectionInfo)
|
|
90
|
-
// }
|
|
91
|
-
// break
|
|
92
|
-
case octez_connect_types_1.BeaconMessageType.BroadcastRequest:
|
|
93
|
-
{
|
|
94
|
-
const appMetadata = yield IncomingRequestInterceptor.getAppMetadata(appMetadataManager, message.senderId);
|
|
95
|
-
const request = Object.assign({ appMetadata }, message);
|
|
96
|
-
interceptorCallback(request, connectionInfo);
|
|
97
|
-
}
|
|
98
|
-
break;
|
|
99
|
-
case octez_connect_types_1.BeaconMessageType.ProofOfEventChallengeRequest:
|
|
100
|
-
{
|
|
101
|
-
const appMetadata = yield IncomingRequestInterceptor.getAppMetadata(appMetadataManager, message.senderId);
|
|
102
|
-
const request = Object.assign({ appMetadata }, message);
|
|
103
|
-
interceptorCallback(request, connectionInfo);
|
|
104
|
-
}
|
|
105
|
-
break;
|
|
106
|
-
case octez_connect_types_1.BeaconMessageType.SimulatedProofOfEventChallengeRequest:
|
|
107
|
-
{
|
|
108
|
-
const appMetadata = yield IncomingRequestInterceptor.getAppMetadata(appMetadataManager, message.senderId);
|
|
109
|
-
const request = Object.assign({ appMetadata }, message);
|
|
110
|
-
interceptorCallback(request, connectionInfo);
|
|
111
|
-
}
|
|
112
|
-
break;
|
|
113
|
-
default:
|
|
114
|
-
logger.log('intercept', 'Message not handled');
|
|
115
|
-
assertNever(message);
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
static handleV3Message(config) {
|
|
95
|
+
static handleWrappedMessage(config) {
|
|
120
96
|
return __awaiter(this, void 0, void 0, function* () {
|
|
121
97
|
const { message: msg, connectionInfo, appMetadataManager, interceptorCallback } = config;
|
|
122
|
-
const wrappedMessage = msg;
|
|
98
|
+
const wrappedMessage = msg;
|
|
123
99
|
const v3Message = wrappedMessage.message;
|
|
100
|
+
const isTezos = TEZOS_IDENTIFIERS.includes(v3Message.blockchainIdentifier);
|
|
124
101
|
switch (v3Message.type) {
|
|
125
102
|
case octez_connect_types_1.BeaconMessageType.PermissionRequest:
|
|
126
103
|
{
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
104
|
+
const appMetadata = Object.assign(Object.assign({}, v3Message.blockchainData.appMetadata), { senderId: msg.senderId // Make sure we use the actual senderId, not what the dApp told us
|
|
105
|
+
});
|
|
106
|
+
yield appMetadataManager.addAppMetadata(appMetadata);
|
|
107
|
+
if (isTezos) {
|
|
108
|
+
// Flat normalization: {type, id, senderId, version, appMetadata,
|
|
109
|
+
// network, networks?, scopes} — exactly the pre-fork shape.
|
|
110
|
+
const payload = Object.assign({}, v3Message.blockchainData);
|
|
111
|
+
delete payload.appMetadata;
|
|
112
|
+
const request = Object.assign({ type: octez_connect_types_1.BeaconMessageType.PermissionRequest, id: wrappedMessage.id, version: wrappedMessage.version, senderId: wrappedMessage.senderId, appMetadata }, payload);
|
|
113
|
+
interceptorCallback(request, connectionInfo);
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
interceptorCallback(wrappedMessage, connectionInfo);
|
|
117
|
+
}
|
|
130
118
|
}
|
|
131
119
|
break;
|
|
132
120
|
case octez_connect_types_1.BeaconMessageType.BlockchainRequest:
|
|
133
121
|
{
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
122
|
+
const blockchainRequest = v3Message;
|
|
123
|
+
const payloadType = blockchainRequest.blockchainData.type;
|
|
124
|
+
const flatType = payloadType ? TEZOS_PAYLOAD_TO_FLAT_TYPE[payloadType] : undefined;
|
|
125
|
+
if (isTezos && flatType) {
|
|
126
|
+
const appMetadata = yield IncomingRequestInterceptor.getAppMetadata(appMetadataManager, msg.senderId);
|
|
127
|
+
const payload = Object.assign({}, blockchainRequest.blockchainData);
|
|
128
|
+
delete payload.type;
|
|
129
|
+
delete payload.scope;
|
|
130
|
+
const request = Object.assign({ type: flatType, id: wrappedMessage.id, version: wrappedMessage.version, senderId: wrappedMessage.senderId, appMetadata }, payload);
|
|
131
|
+
interceptorCallback(request, connectionInfo);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
interceptorCallback(Object.assign({}, wrappedMessage), connectionInfo);
|
|
135
|
+
}
|
|
140
136
|
}
|
|
141
137
|
break;
|
|
142
138
|
default:
|
|
143
139
|
logger.log('intercept', 'Message not handled');
|
|
144
|
-
assertNever(v3Message);
|
|
140
|
+
(0, octez_connect_core_1.assertNever)(v3Message);
|
|
145
141
|
}
|
|
146
142
|
});
|
|
147
143
|
}
|
|
148
144
|
}
|
|
149
145
|
exports.IncomingRequestInterceptor = IncomingRequestInterceptor;
|
|
150
|
-
function assertNever(_message) {
|
|
151
|
-
throw new Error('Function not implemented.');
|
|
152
|
-
}
|
|
153
146
|
//# sourceMappingURL=IncomingRequestInterceptor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IncomingRequestInterceptor.js","sourceRoot":"","sources":["../../../src/interceptors/IncomingRequestInterceptor.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n BeaconRequestOutputMessage,\n BeaconMessageType,\n PermissionRequestOutput,\n AppMetadata,\n OperationRequestOutput,\n SignPayloadRequestOutput,\n BroadcastRequestOutput,\n ProofOfEventChallengeRequestOutput,\n ConnectionContext,\n BeaconRequestMessage,\n BeaconMessageWrapper,\n BlockchainRequestV3,\n PermissionRequestV3,\n BeaconBaseMessage\n // EncryptPayloadRequestOutput\n} from '@tezos-x/octez.connect-types'\nimport { AppMetadataManager, Logger, usesWrappedMessages } from '@tezos-x/octez.connect-core'\nimport { SimulatedProofOfEventChallengeRequestOutput } from '@tezos-x/octez.connect-types/dist/esm/types/beacon/messages/BeaconRequestOutputMessage'\n\nconst logger = new Logger('IncomingRequestInterceptor')\n\ninterface IncomingRequestInterceptorOptions {\n message: BeaconRequestMessage | BeaconMessageWrapper<BeaconBaseMessage>\n connectionInfo: ConnectionContext\n appMetadataManager: AppMetadataManager\n interceptorCallback(message: BeaconRequestOutputMessage, connectionInfo: ConnectionContext): void\n}\n\ninterface IncomingRequestInterceptorOptionsV2 extends IncomingRequestInterceptorOptions {\n message: BeaconRequestMessage\n}\n\ninterface IncomingRequestInterceptorOptionsV3 extends IncomingRequestInterceptorOptions {\n message: BeaconMessageWrapper<BeaconBaseMessage>\n}\n/**\n * @internalapi\n *\n * The IncomingRequestInterceptor is used in the WalletClient to intercept an incoming request and enrich it with data, like app metadata.\n */\nexport class IncomingRequestInterceptor {\n /**\n * The method that is called during the interception\n *\n * @param config\n */\n public static async intercept(config: IncomingRequestInterceptorOptions): Promise<void> {\n logger.log('INTERCEPTING REQUEST', config.message)\n\n if (config.message.version === '2') {\n IncomingRequestInterceptor.handleV2Message(config as IncomingRequestInterceptorOptionsV2)\n } else if (usesWrappedMessages(config.message.version)) {\n IncomingRequestInterceptor.handleV3Message(config as IncomingRequestInterceptorOptionsV3)\n }\n }\n\n private static async getAppMetadata(\n appMetadataManager: AppMetadataManager,\n senderId: string\n ): Promise<AppMetadata> {\n const appMetadata: AppMetadata | undefined = await appMetadataManager.getAppMetadata(senderId)\n if (!appMetadata) {\n throw new Error('AppMetadata not found')\n }\n\n return appMetadata\n }\n\n private static async handleV2Message(config: IncomingRequestInterceptorOptionsV2) {\n const {\n message,\n connectionInfo,\n appMetadataManager,\n interceptorCallback\n }: IncomingRequestInterceptorOptionsV2 = config\n\n switch (message.type) {\n case BeaconMessageType.PermissionRequest:\n {\n logger.log('PERMISSION REQUEST V*', message)\n // TODO: Remove v1 compatibility in later version\n if ((message.appMetadata as any).beaconId && !message.appMetadata.senderId) {\n message.appMetadata.senderId = (message.appMetadata as any).beaconId\n delete (message.appMetadata as any).beaconId\n }\n\n await appMetadataManager.addAppMetadata(message.appMetadata)\n const request: PermissionRequestOutput = message\n interceptorCallback(request, connectionInfo)\n }\n break\n case BeaconMessageType.OperationRequest:\n {\n const appMetadata: AppMetadata = await IncomingRequestInterceptor.getAppMetadata(\n appMetadataManager,\n message.senderId\n )\n const request: OperationRequestOutput = {\n appMetadata,\n ...message\n }\n interceptorCallback(request, connectionInfo)\n }\n break\n case BeaconMessageType.SignPayloadRequest:\n {\n const appMetadata: AppMetadata = await IncomingRequestInterceptor.getAppMetadata(\n appMetadataManager,\n message.senderId\n )\n const request: SignPayloadRequestOutput = {\n appMetadata,\n ...message\n }\n interceptorCallback(request, connectionInfo)\n }\n break\n // TODO: ENCRYPTION\n // case BeaconMessageType.EncryptPayloadRequest:\n // {\n // const appMetadata: AppMetadata = await IncomingRequestInterceptor.getAppMetadata(\n // appMetadataManager,\n // message.senderId\n // )\n // const request: EncryptPayloadRequestOutput = {\n // appMetadata,\n // ...message\n // }\n // interceptorCallback(request, connectionInfo)\n // }\n // break\n case BeaconMessageType.BroadcastRequest:\n {\n const appMetadata: AppMetadata = await IncomingRequestInterceptor.getAppMetadata(\n appMetadataManager,\n message.senderId\n )\n const request: BroadcastRequestOutput = {\n appMetadata,\n ...message\n }\n interceptorCallback(request, connectionInfo)\n }\n break\n case BeaconMessageType.ProofOfEventChallengeRequest:\n {\n const appMetadata: AppMetadata = await IncomingRequestInterceptor.getAppMetadata(\n appMetadataManager,\n message.senderId\n )\n const request: ProofOfEventChallengeRequestOutput = {\n appMetadata,\n ...message\n }\n interceptorCallback(request, connectionInfo)\n }\n break\n case BeaconMessageType.SimulatedProofOfEventChallengeRequest:\n {\n const appMetadata: AppMetadata = await IncomingRequestInterceptor.getAppMetadata(\n appMetadataManager,\n message.senderId\n )\n const request: SimulatedProofOfEventChallengeRequestOutput = {\n appMetadata,\n ...message\n }\n interceptorCallback(request, connectionInfo)\n }\n break\n default:\n logger.log('intercept', 'Message not handled')\n assertNever(message)\n }\n }\n\n private static async handleV3Message(config: IncomingRequestInterceptorOptionsV3) {\n const {\n message: msg,\n connectionInfo,\n appMetadataManager,\n interceptorCallback\n }: IncomingRequestInterceptorOptionsV3 = config\n\n const wrappedMessage:\n | BeaconMessageWrapper<PermissionRequestV3<string>>\n | BeaconMessageWrapper<BlockchainRequestV3<string>> = msg as any /* TODO: Remove any */\n\n const v3Message: PermissionRequestV3<string> | BlockchainRequestV3<string> =\n wrappedMessage.message\n\n switch (v3Message.type) {\n case BeaconMessageType.PermissionRequest:\n {\n await appMetadataManager.addAppMetadata({\n ...v3Message.blockchainData.appMetadata,\n senderId: msg.senderId\n }) // Make sure we use the actual senderId, not what the dApp told us\n const request: any /* PermissionRequestOutput */ = wrappedMessage\n interceptorCallback(request, connectionInfo)\n }\n break\n case BeaconMessageType.BlockchainRequest:\n {\n // const appMetadata: AppMetadata = await IncomingRequestInterceptor.getAppMetadata(\n // appMetadataManager,\n // msg.senderId\n // )\n const request: any /* BeaconMessageWrapper<BlockchainRequestV3<string>> */ = {\n ...wrappedMessage\n }\n interceptorCallback(request, connectionInfo)\n }\n break\n\n default:\n logger.log('intercept', 'Message not handled')\n assertNever(v3Message)\n }\n }\n}\n\nfunction assertNever(_message: never) {\n throw new Error('Function not implemented.')\n}\n"]}
|
|
1
|
+
{"version":3,"file":"IncomingRequestInterceptor.js","sourceRoot":"","sources":["../../../src/interceptors/IncomingRequestInterceptor.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n BeaconRequestOutputMessage,\n BeaconMessageType,\n AppMetadata,\n ConnectionContext,\n BeaconMessageWrapper,\n BeaconRequestMessage,\n BlockchainRequestV3,\n PermissionRequestV3,\n BeaconBaseMessage\n} from '@tezos-x/octez.connect-types'\nimport { AppMetadataManager, Logger, usesWrappedMessages, assertNever } from '@tezos-x/octez.connect-core'\n\nconst logger = new Logger('IncomingRequestInterceptor')\n\ninterface IncomingRequestInterceptorOptions {\n message: BeaconRequestMessage | BeaconMessageWrapper<BeaconBaseMessage>\n connectionInfo: ConnectionContext\n appMetadataManager: AppMetadataManager\n interceptorCallback: (\n message: BeaconRequestOutputMessage,\n connectionInfo: ConnectionContext\n ) => void\n}\n\n// Chain identifiers whose wrapped payloads are normalized back to the flat\n// request shapes Tezos wallet apps have always consumed ('xtz' is the\n// pre-rename legacy identifier). Other chains (e.g. substrate) keep the\n// wrapped pass-through of the generic API.\nconst TEZOS_IDENTIFIERS: readonly string[] = ['tezos', 'xtz']\n\n// Wrapped Tezos blockchainData discriminators → the flat BeaconMessageType\n// the wallet app receives. Values reuse the pre-fork wire strings.\nconst TEZOS_PAYLOAD_TO_FLAT_TYPE: Record<string, BeaconMessageType> = {\n operation_request: BeaconMessageType.OperationRequest,\n sign_payload_request: BeaconMessageType.SignPayloadRequest,\n broadcast_request: BeaconMessageType.BroadcastRequest,\n proof_of_event_challenge_request: BeaconMessageType.ProofOfEventChallengeRequest,\n simulated_proof_of_event_challenge_request:\n BeaconMessageType.SimulatedProofOfEventChallengeRequest\n}\n\n/**\n * @internalapi\n *\n * The IncomingRequestInterceptor is used in the WalletClient to intercept an\n * incoming (wrapped) request, enrich it with app metadata, and — for Tezos\n * payloads — normalize it to the flat request shape wallet apps consume, so\n * apps never see envelopes or version strings.\n */\nexport class IncomingRequestInterceptor {\n /**\n * The method that is called during the interception\n *\n * @param config\n */\n public static async intercept(config: IncomingRequestInterceptorOptions): Promise<void> {\n logger.log('INTERCEPTING REQUEST', config.message)\n\n // Negotiated wire: flat '2' arrivals are the legacy dialect (a v4.8.x\n // dApp) and already carry the shape wallet apps consume — they only need\n // enrichment. Wrapped arrivals (v3+) are unwrapped and, for Tezos\n // payloads, normalized to the same flat shapes. Anything else (absent or\n // malformed version — untrusted input) is dropped, never dispatched.\n if (usesWrappedMessages(config.message.version)) {\n await IncomingRequestInterceptor.handleWrappedMessage(config)\n } else if (config.message.version === '2') {\n await IncomingRequestInterceptor.handleFlatMessage(config)\n } else {\n logger.warn(\n 'intercept',\n `Dropping message with unsupported version ${JSON.stringify(config.message.version)}`\n )\n }\n }\n\n // Legacy flat v2 dialect: enrich with app metadata and pass through — the\n // output shape is identical to the wrapped path's flat normalization, so\n // wallet apps cannot tell which dialect the dApp spoke.\n private static async handleFlatMessage(\n config: IncomingRequestInterceptorOptions\n ): Promise<void> {\n const { connectionInfo, appMetadataManager, interceptorCallback } = config\n const message = config.message as BeaconRequestMessage\n\n if (message.type === BeaconMessageType.PermissionRequest) {\n // TODO: Remove v1 compatibility in later version\n let dappMetadata = message.appMetadata\n const legacyBeaconId = (dappMetadata as { beaconId?: string }).beaconId\n if (legacyBeaconId && !dappMetadata.senderId) {\n dappMetadata = { ...dappMetadata, senderId: legacyBeaconId }\n delete (dappMetadata as { beaconId?: string }).beaconId\n }\n\n await appMetadataManager.addAppMetadata(dappMetadata)\n interceptorCallback({ ...message, appMetadata: dappMetadata }, connectionInfo)\n\n return\n }\n\n const appMetadata: AppMetadata = await IncomingRequestInterceptor.getAppMetadata(\n appMetadataManager,\n message.senderId\n )\n interceptorCallback(\n { appMetadata, ...message },\n connectionInfo\n )\n }\n\n private static async getAppMetadata(\n appMetadataManager: AppMetadataManager,\n senderId: string\n ): Promise<AppMetadata> {\n const appMetadata: AppMetadata | undefined = await appMetadataManager.getAppMetadata(senderId)\n if (!appMetadata) {\n throw new Error('AppMetadata not found')\n }\n\n return appMetadata\n }\n\n private static async handleWrappedMessage(\n config: IncomingRequestInterceptorOptions\n ): Promise<void> {\n const {\n message: msg,\n connectionInfo,\n appMetadataManager,\n interceptorCallback\n }: IncomingRequestInterceptorOptions = config\n\n const wrappedMessage = msg as unknown as\n | BeaconMessageWrapper<PermissionRequestV3>\n | BeaconMessageWrapper<BlockchainRequestV3>\n\n const v3Message: PermissionRequestV3 | BlockchainRequestV3 = wrappedMessage.message\n const isTezos = TEZOS_IDENTIFIERS.includes(v3Message.blockchainIdentifier)\n\n switch (v3Message.type) {\n case BeaconMessageType.PermissionRequest:\n {\n const appMetadata: AppMetadata = {\n ...v3Message.blockchainData.appMetadata,\n senderId: msg.senderId // Make sure we use the actual senderId, not what the dApp told us\n }\n await appMetadataManager.addAppMetadata(appMetadata)\n\n if (isTezos) {\n // Flat normalization: {type, id, senderId, version, appMetadata,\n // network, networks?, scopes} — exactly the pre-fork shape.\n const payload = { ...(v3Message.blockchainData as Record<string, unknown>) }\n delete payload.appMetadata\n const request = {\n type: BeaconMessageType.PermissionRequest,\n id: wrappedMessage.id,\n version: wrappedMessage.version,\n senderId: wrappedMessage.senderId,\n appMetadata,\n ...payload\n } as unknown as BeaconRequestOutputMessage\n interceptorCallback(request, connectionInfo)\n } else {\n interceptorCallback(\n wrappedMessage as unknown as BeaconRequestOutputMessage,\n connectionInfo\n )\n }\n }\n break\n case BeaconMessageType.BlockchainRequest:\n {\n const blockchainRequest = v3Message\n const payloadType = (blockchainRequest.blockchainData as { type?: string }).type\n const flatType = payloadType ? TEZOS_PAYLOAD_TO_FLAT_TYPE[payloadType] : undefined\n\n if (isTezos && flatType) {\n const appMetadata: AppMetadata = await IncomingRequestInterceptor.getAppMetadata(\n appMetadataManager,\n msg.senderId\n )\n const payload = { ...(blockchainRequest.blockchainData as Record<string, unknown>) }\n delete payload.type\n delete payload.scope\n const request = {\n type: flatType,\n id: wrappedMessage.id,\n version: wrappedMessage.version,\n senderId: wrappedMessage.senderId,\n appMetadata,\n ...payload\n } as unknown as BeaconRequestOutputMessage\n interceptorCallback(request, connectionInfo)\n } else {\n interceptorCallback(\n { ...wrappedMessage } as unknown as BeaconRequestOutputMessage,\n connectionInfo\n )\n }\n }\n break\n\n default:\n logger.log('intercept', 'Message not handled')\n assertNever(v3Message)\n }\n }\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AppMetadataManager, PermissionManager } from '@tezos-x/octez.connect-core';
|
|
2
|
-
import { BeaconMessage, BeaconResponseInputMessage, AppMetadata,
|
|
2
|
+
import { BeaconMessage, BeaconResponseInputMessage, AppMetadata, BeaconMessageWrapper, BeaconRequestMessage, BeaconBaseMessage, Blockchain } from '@tezos-x/octez.connect-types';
|
|
3
3
|
interface OutgoingResponseInterceptorOptions {
|
|
4
4
|
senderId: string;
|
|
5
5
|
request: BeaconRequestMessage | BeaconMessageWrapper<BeaconBaseMessage>;
|
|
@@ -7,17 +7,22 @@ interface OutgoingResponseInterceptorOptions {
|
|
|
7
7
|
ownAppMetadata: AppMetadata;
|
|
8
8
|
permissionManager: PermissionManager;
|
|
9
9
|
appMetadataManager: AppMetadataManager;
|
|
10
|
-
interceptorCallback(message: BeaconMessage)
|
|
10
|
+
interceptorCallback: (message: BeaconMessage) => void;
|
|
11
11
|
blockchains: Map<string, Blockchain>;
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
14
14
|
* @internalapi
|
|
15
15
|
*
|
|
16
|
-
* The OutgoingResponseInterceptor is used in the WalletClient to intercept an
|
|
16
|
+
* The OutgoingResponseInterceptor is used in the WalletClient to intercept an
|
|
17
|
+
* outgoing response, wrap it onto the (wrapped-only) wire, validate it via the
|
|
18
|
+
* blockchain registry, and persist granted permissions.
|
|
17
19
|
*/
|
|
18
20
|
export declare class OutgoingResponseInterceptor {
|
|
19
21
|
static intercept(config: OutgoingResponseInterceptorOptions): Promise<void>;
|
|
20
|
-
private static
|
|
21
|
-
private static
|
|
22
|
+
private static handleWrappedInput;
|
|
23
|
+
private static handleFlatInput;
|
|
24
|
+
private static requireBlockchain;
|
|
25
|
+
private static persistGrantedPermissions;
|
|
26
|
+
private static networkFromRequest;
|
|
22
27
|
}
|
|
23
28
|
export {};
|