Skip to content

Commit 886f71e

Browse files
authored
feat: add deeplink compression logic to sdk-multichain (#1360)
* feat: add deeplink compression logic * build: fix package json devDependency vs dependency * minor fix
1 parent 7af4f97 commit 886f71e

File tree

4 files changed

+55
-5
lines changed

4 files changed

+55
-5
lines changed

packages/sdk-multichain/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
"@metamask/auto-changelog": "^3.4.3",
3434
"@react-native-async-storage/async-storage": "^1.23.1",
3535
"@types/jsdom": "^21.1.7",
36+
"@types/pako": "^2.0.4",
3637
"@types/ws": "^8.18.1",
3738
"@vitest/coverage-v8": "^3.2.4",
3839
"esbuild-plugin-umd-wrapper": "^3.0.0",
@@ -66,6 +67,7 @@
6667
"cross-fetch": "^4.1.0",
6768
"eciesjs": "^0.4.15",
6869
"eventemitter3": "^5.0.1",
70+
"pako": "^2.1.0",
6971
"uuid": "^11.1.0",
7072
"ws": "^8.18.3"
7173
}

packages/sdk-multichain/src/multichain/utils/index.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,38 @@
1+
import { deflate } from 'pako';
12
import { type CaipAccountId, type CaipChainId, parseCaipAccountId, parseCaipChainId } from '@metamask/utils';
23
import packageJson from '../../../package.json';
34
import { type DappSettings, getInfuraRpcUrls, getPlatformType, type MultichainOptions, PlatformType, type Scope, type SessionData } from '../../domain';
45

56
export type OptionalScopes = Record<Scope, SessionData['sessionScopes'][Scope]>;
67

8+
/**
9+
* Cross-platform base64 encoding
10+
* Works in browser, Node.js, and React Native environments
11+
*/
12+
function base64Encode(str: string): string {
13+
if (typeof btoa !== 'undefined') {
14+
// Browser and React Native with polyfills
15+
return btoa(str);
16+
} else if (typeof Buffer !== 'undefined') {
17+
// Node.js
18+
return Buffer.from(str).toString('base64');
19+
}
20+
throw new Error('No base64 encoding method available');
21+
}
22+
23+
/**
24+
* Compress a string using pako (deflateRaw)
25+
* Returns a base64-encoded compressed string
26+
*/
27+
export function compressString(str: string): string {
28+
const compressed = deflate(str);
29+
30+
// Convert Uint8Array to string for base64 encoding
31+
const binaryString = String.fromCharCode.apply(null, Array.from(compressed));
32+
return base64Encode(binaryString);
33+
}
34+
35+
736
export function getDappId(dapp?: DappSettings) {
837
if (typeof window === 'undefined' || typeof window.location === 'undefined') {
938
return dapp?.name ?? dapp?.url ?? 'N/A';

packages/sdk-multichain/src/ui/index.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import MetaMaskOnboarding from '@metamask/onboarding';
22
import { type ConnectionRequest, getPlatformType, getVersion, type Modal, type OTPCode, PlatformType } from '../domain';
33
import type { FactoryModals, ModalTypes } from './modals/types';
44
import type { AbstractOTPCodeModal } from './modals/base/AbstractOTPModal';
5+
import { compressString } from '../multichain/utils';
56
import { METAMASK_CONNECT_BASE_URL, METAMASK_DEEPLINK_BASE } from 'src/config';
67

78
// @ts-ignore
@@ -90,15 +91,17 @@ export class ModalFactory<T extends FactoryModals = FactoryModals> {
9091
}
9192

9293
createDeeplink(connectionRequest: ConnectionRequest) {
93-
const json = JSON.stringify(connectionRequest);
94-
const urlEncoded = encodeURIComponent(json);
95-
return `${METAMASK_DEEPLINK_BASE}/mwp?p=${urlEncoded}`;
94+
const json = JSON.stringify(connectionRequest);
95+
const compressed = compressString(json);
96+
const urlEncoded = encodeURIComponent(compressed);
97+
return `${METAMASK_DEEPLINK_BASE}/mwp?p=${urlEncoded}&c=1`;
9698
}
9799

98100
createUniversalLink(connectionRequest: ConnectionRequest) {
99101
const json = JSON.stringify(connectionRequest);
100-
const urlEncoded = encodeURIComponent(json);
101-
return `${METAMASK_CONNECT_BASE_URL}/mwp?p=${urlEncoded}`;
102+
const compressed = compressString(json);
103+
const urlEncoded = encodeURIComponent(compressed);
104+
return `${METAMASK_CONNECT_BASE_URL}/mwp?p=${urlEncoded}&c=1`;
102105
}
103106

104107
private async onCloseModal(shouldTerminate = true) {

yarn.lock

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11583,6 +11583,7 @@ __metadata:
1158311583
"@paulmillr/qr": ^0.2.1
1158411584
"@react-native-async-storage/async-storage": ^1.23.1
1158511585
"@types/jsdom": ^21.1.7
11586+
"@types/pako": ^2.0.4
1158611587
"@types/ws": ^8.18.1
1158711588
"@vitest/coverage-v8": ^3.2.4
1158811589
bowser: ^2.11.0
@@ -11593,6 +11594,7 @@ __metadata:
1159311594
fake-indexeddb: ^6.0.1
1159411595
jsdom: ^26.1.0
1159511596
nock: ^14.0.4
11597+
pako: ^2.1.0
1159611598
prettier: ^3.3.3
1159711599
tsup: ^8.5.0
1159811600
typescript: ^5.8.3
@@ -20236,6 +20238,13 @@ __metadata:
2023620238
languageName: node
2023720239
linkType: hard
2023820240

20241+
"@types/pako@npm:^2.0.4":
20242+
version: 2.0.4
20243+
resolution: "@types/pako@npm:2.0.4"
20244+
checksum: 7e7b090c27cdbed4a8c21f7dfa466ad1c6b5c29afbcaaa24b35e83803d2b6b6cd552060060d8832058cf3809787baaab47a6a974b69d75a2a2dc59d21b607ee8
20245+
languageName: node
20246+
linkType: hard
20247+
2023920248
"@types/parse-json@npm:^4.0.0":
2024020249
version: 4.0.0
2024120250
resolution: "@types/parse-json@npm:4.0.0"
@@ -44907,6 +44916,13 @@ __metadata:
4490744916
languageName: node
4490844917
linkType: hard
4490944918

44919+
"pako@npm:^2.1.0":
44920+
version: 2.1.0
44921+
resolution: "pako@npm:2.1.0"
44922+
checksum: 71666548644c9a4d056bcaba849ca6fd7242c6cf1af0646d3346f3079a1c7f4a66ffec6f7369ee0dc88f61926c10d6ab05da3e1fca44b83551839e89edd75a3e
44923+
languageName: node
44924+
linkType: hard
44925+
4491044926
"pako@npm:~0.2.0":
4491144927
version: 0.2.9
4491244928
resolution: "pako@npm:0.2.9"

0 commit comments

Comments
 (0)