From e454ffca58e018b3f0eb97f7a21ad5de2e231603 Mon Sep 17 00:00:00 2001 From: TosinJs Date: Sat, 15 Jun 2024 14:50:34 +0100 Subject: [PATCH 1/8] Update Readme.md --- README.md | 6 ++++++ examples/example.ts | 6 ++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 735d757..5a8bdf9 100644 --- a/README.md +++ b/README.md @@ -28,10 +28,13 @@ npm install @gandalf-network/connect --save ```typescript import Connect from "@gandalf-network/connect"; +import { Platform } from "@gandalf-network/connect/components"; const connect = new Connect({ publicKey: process.env.PUBLIC_KEY, redirectURL: "YOUR_REDIRECT_URL", + // The platform defaults to IOS but could be ANDROID or UNIVERSAL + platform: platform.android, services: { uber: { @@ -48,10 +51,13 @@ const connect = new Connect({ ```javascript // CommonJS const Connect = require("@gandalf-network/connect"); +const { Platform } = require("@gandalf-network/connect/components"); const connect = new Connect({ publicKey: process.env.PUBLIC_KEY, redirectURL: "YOUR_REDIRECT_URL", + // The platform defaults to IOS but could be ANDROID or UNIVERSAL + platform: platform.android, services: { uber: { diff --git a/examples/example.ts b/examples/example.ts index cb03a5e..8dd6331 100644 --- a/examples/example.ts +++ b/examples/example.ts @@ -1,8 +1,10 @@ import Connect from "../src/connect"; -import { ActivityType, InputData, TraitLabel } from "../src/types"; +import { ActivityType, InputData, TraitLabel, Platform } from "../src/types"; const publicKey = "0x0297bb4f88a65b82c08fd20afb1259b7027dc996c8941e0c5917a452d538cd0da9"; const redirectURL = "https://example.com" +const platform = Platform.android; + const services: InputData = { uber: { traits: [TraitLabel.Plan], @@ -14,7 +16,7 @@ const services: InputData = { } async function example() { - const connect = new Connect({publicKey, redirectURL, services}) + const connect = new Connect({ publicKey, redirectURL, services, platform }) // Generate the Connect URL const url = await connect.generateURL() From 397352d039a50f32e0dbca7d4865eb81a86a4e63 Mon Sep 17 00:00:00 2001 From: TosinJs Date: Sat, 15 Jun 2024 14:55:36 +0100 Subject: [PATCH 2/8] update Readme --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 5a8bdf9..be1f8f7 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,9 @@ npm install @gandalf-network/connect --save #### Initialization +Note: With the platform parameter you can generate either IOS, ANDROID or UNIVERSAL connect URLs. +More Information on the Platform parameter can be found [here](https://docs.gandalf.network/concepts/connect). + ```typescript import Connect from "@gandalf-network/connect"; import { Platform } from "@gandalf-network/connect/components"; From b68fbe483b5d854f4c672296a02d28dbc0b6a3aa Mon Sep 17 00:00:00 2001 From: TosinJs Date: Sat, 15 Jun 2024 16:05:46 +0100 Subject: [PATCH 3/8] Update Readme.md --- README.md | 33 ++++++++++----------------------- examples/example.ts | 2 +- src/connect.ts | 22 +++++++++++++++------- src/types/index.ts | 6 +++--- 4 files changed, 29 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index be1f8f7..f8395ae 100644 --- a/README.md +++ b/README.md @@ -24,43 +24,30 @@ npm install @gandalf-network/connect --save ### Usage -#### Initialization - -Note: With the platform parameter you can generate either IOS, ANDROID or UNIVERSAL connect URLs. -More Information on the Platform parameter can be found [here](https://docs.gandalf.network/concepts/connect). +#### Import the library ```typescript +// Typescript && ESModules + import Connect from "@gandalf-network/connect"; import { Platform } from "@gandalf-network/connect/components"; - -const connect = new Connect({ - publicKey: process.env.PUBLIC_KEY, - redirectURL: "YOUR_REDIRECT_URL", - // The platform defaults to IOS but could be ANDROID or UNIVERSAL - platform: platform.android, - services: - { - uber: { - traits: ["rating"], // At least one trait or activity is required - activities: ["trip"], - }, - gandalf: { - traits: ["email"] - } - } // Only one non "Gandalf" service (e.g "netflix", "instacart") is supported per Connect URL -}) ``` ```javascript // CommonJS + const Connect = require("@gandalf-network/connect"); const { Platform } = require("@gandalf-network/connect/components"); +``` + +#### Initialize Connect +```typescript const connect = new Connect({ publicKey: process.env.PUBLIC_KEY, redirectURL: "YOUR_REDIRECT_URL", // The platform defaults to IOS but could be ANDROID or UNIVERSAL - platform: platform.android, + platform: Platform.ANDROID, services: { uber: { @@ -70,7 +57,7 @@ const connect = new Connect({ gandalf: { traits: ["email"] } - } // Only one non "Gandalf" service (e.g "uber", "amazon") is supported per Connect URL + } // Only one non "Gandalf" service (e.g "netflix", "instacart") is supported per Connect URL }) ``` diff --git a/examples/example.ts b/examples/example.ts index 8dd6331..653415d 100644 --- a/examples/example.ts +++ b/examples/example.ts @@ -3,7 +3,7 @@ import { ActivityType, InputData, TraitLabel, Platform } from "../src/types"; const publicKey = "0x0297bb4f88a65b82c08fd20afb1259b7027dc996c8941e0c5917a452d538cd0da9"; const redirectURL = "https://example.com" -const platform = Platform.android; +const platform = Platform.ANDROID; const services: InputData = { uber: { diff --git a/src/connect.ts b/src/connect.ts index 29e75c3..e73f2e6 100644 --- a/src/connect.ts +++ b/src/connect.ts @@ -32,7 +32,7 @@ class Connect { publicKey: string; redirectURL: string; data: InputData; - platform: Platform = Platform.ios; + platform: Platform = Platform.IOS; verificationComplete: boolean = false; constructor(input: ConnectInput) { @@ -42,7 +42,7 @@ class Connect { this.publicKey = input.publicKey; this.redirectURL = input.redirectURL; this.data = input.services; - this.platform = input.platform ? input.platform : Platform.ios; + this.platform = input.platform ? input.platform : Platform.IOS; } async generateURL(): Promise { @@ -109,10 +109,10 @@ class Connect { ): string { let BASE_URL = IOS_APP_CLIP_BASE_URL; switch (this.platform) { - case Platform.android: + case Platform.ANDROID: BASE_URL = ANDROID_APP_CLIP_BASE_URL; break; - case Platform.universal: + case Platform.UNIVERSAL: BASE_URL = UNIVERSAL_APP_CLIP_BASE_URL; break; } @@ -163,9 +163,13 @@ class Connect { let unsupportedServices: string[] = []; - const keys = Object.keys(input).map((key) => key.toLowerCase()); + const keys = Object.keys(input); + const lkeys = keys.map((key) => key.toLowerCase()); - if (keys.length > 2 || (keys.length === 2 && !keys.includes('gandalf'))) { + if ( + lkeys.length > 2 || + (lkeys.length === 2 && !lkeys.includes('gandalf')) + ) { throw new GandalfError( `Only one non Gandalf service is supported per Connect URL`, GandalfErrorCode.InvalidService, @@ -173,7 +177,11 @@ class Connect { } for (const key of keys) { - if (!supportedServicesAndTraits.services.includes(key as Source)) { + if ( + !supportedServicesAndTraits.services.includes( + key.toLocaleLowerCase() as Source, + ) + ) { unsupportedServices = [...unsupportedServices, key]; continue; } diff --git a/src/types/index.ts b/src/types/index.ts index 2e095fe..0da3abc 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -12,9 +12,9 @@ export type Service = { }; export enum Platform { - universal = 'UNIVERSAL', - ios = 'IOS', - android = 'ANDROID', + UNIVERSAL = 'UNIVERSAL', + IOS = 'IOS', + ANDROID = 'ANDROID', } export type ConnectInput = { From 768667637c6cc06665a7cb2b1138b0634b9f3739 Mon Sep 17 00:00:00 2001 From: TosinJs Date: Sat, 15 Jun 2024 16:11:53 +0100 Subject: [PATCH 4/8] Update Tests --- tests/connect.spec.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/connect.spec.ts b/tests/connect.spec.ts index cae462d..0d04d80 100644 --- a/tests/connect.spec.ts +++ b/tests/connect.spec.ts @@ -54,7 +54,7 @@ describe("Connect SDK", () => { expect(connect.publicKey).toEqual(publicKey); expect(connect.redirectURL).toEqual(redirectURL); - expect(connect.platform).toEqual(Platform.ios); + expect(connect.platform).toEqual(Platform.IOS); }); it("should strip the redirect url of trailing slashes", async () => { @@ -66,9 +66,9 @@ describe("Connect SDK", () => { it("should set the platform", async () => { const redirectURL = "https://example.com/"; - const connect = new Connect({ publicKey, redirectURL, services, platform: Platform.universal }); + const connect = new Connect({ publicKey, redirectURL, services, platform: Platform.UNIVERSAL }); - expect(connect.platform).toEqual(Platform.universal); + expect(connect.platform).toEqual(Platform.UNIVERSAL); }); }); @@ -229,7 +229,7 @@ describe("Connect SDK", () => { }); it("should generate a universal connect URL", async () => { - const connect = new Connect({ publicKey, redirectURL, services, platform: Platform.universal }); + const connect = new Connect({ publicKey, redirectURL, services, platform: Platform.UNIVERSAL }); const generatedURL = await connect.generateURL(); expect(generatedURL).toEqual( `${UNIVERSAL_APP_CLIP_BASE_URL}/?publicKey=${encodedPublicKey}&redirectUrl=${encodedRedirectURL}&data=${encodedData}`, @@ -237,7 +237,7 @@ describe("Connect SDK", () => { }); it("should generate an android connect URL", async () => { - const connect = new Connect({ publicKey, redirectURL, services, platform: Platform.android }); + const connect = new Connect({ publicKey, redirectURL, services, platform: Platform.ANDROID }); const generatedURL = await connect.generateURL(); expect(generatedURL).toEqual( `${ANDROID_APP_CLIP_BASE_URL}/?publicKey=${encodedPublicKey}&redirectUrl=${encodedRedirectURL}&data=${encodedData}`, @@ -305,13 +305,13 @@ describe("Connect SDK", () => { }); it("should generate a universal connect URL", async () => { - const services = {"netflix": true}; - const stringData = JSON.stringify(services); + const services = {"NETFLIX": true}; + const stringData = JSON.stringify({"netflix": true}); const encodedData = encodeURIComponent(btoa(stringData)); const encodedRedirectURL = encodeURIComponent(redirectURL); const encodedPublicKey = encodeURIComponent(publicKey); - const connect = new Connect({ publicKey, redirectURL, services, platform: Platform.universal }); + const connect = new Connect({ publicKey, redirectURL, services, platform: Platform.UNIVERSAL }); const generatedURL = await connect.generateURL(); expect(generatedURL).toEqual( `${UNIVERSAL_APP_CLIP_BASE_URL}/?publicKey=${encodedPublicKey}&redirectUrl=${encodedRedirectURL}&data=${encodedData}`, From 5eaa057b98d8386655771b3740f12bb7a275c357 Mon Sep 17 00:00:00 2001 From: Tosin Samuel <68669102+TosinJs@users.noreply.github.com> Date: Sun, 16 Jun 2024 16:16:14 +0100 Subject: [PATCH 5/8] Update README.md --- README.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/README.md b/README.md index f8395ae..f57d173 100644 --- a/README.md +++ b/README.md @@ -54,10 +54,7 @@ const connect = new Connect({ traits: ["rating"], // At least one trait or activity is required activities: ["trip"], }, - gandalf: { - traits: ["email"] - } - } // Only one non "Gandalf" service (e.g "netflix", "instacart") is supported per Connect URL + } }) ``` From 44aec7bdb128cd6a78e7e779b3450fa8e89c6884 Mon Sep 17 00:00:00 2001 From: TosinJs Date: Sun, 16 Jun 2024 22:42:04 +0100 Subject: [PATCH 6/8] use Legacy Params Flag --- src/connect.ts | 70 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 60 insertions(+), 10 deletions(-) diff --git a/src/connect.ts b/src/connect.ts index e73f2e6..cf8ff12 100644 --- a/src/connect.ts +++ b/src/connect.ts @@ -34,8 +34,9 @@ class Connect { data: InputData; platform: Platform = Platform.IOS; verificationComplete: boolean = false; + useAlphaVersionParams: boolean = false; - constructor(input: ConnectInput) { + constructor(input: ConnectInput, useAlphaVersionParams: boolean = false) { if (input.redirectURL.endsWith('/')) { input.redirectURL = input.redirectURL.slice(0, -1); } @@ -43,16 +44,28 @@ class Connect { this.redirectURL = input.redirectURL; this.data = input.services; this.platform = input.platform ? input.platform : Platform.IOS; + this.useAlphaVersionParams = useAlphaVersionParams; } async generateURL(): Promise { await this.allValidations(this.publicKey, this.redirectURL, this.data); const data = JSON.stringify(this.data); - const appClipURL = this.encodeComponents( - data, - this.redirectURL, - this.publicKey, - ); + let appClipURL = ''; + + if (this.useAlphaVersionParams) { + appClipURL = this.encodeLegacyComponents( + data, + this.redirectURL, + this.publicKey, + ); + } else { + appClipURL = this.encodeComponents( + data, + this.redirectURL, + this.publicKey, + ); + } + return appClipURL; } @@ -132,6 +145,35 @@ class Connect { return url.toString(); } + private encodeLegacyComponents( + services: string, + redirectUrl: string, + publicKey: string, + ): string { + let BASE_URL = IOS_APP_CLIP_BASE_URL; + switch (this.platform) { + case Platform.ANDROID: + BASE_URL = ANDROID_APP_CLIP_BASE_URL; + break; + case Platform.UNIVERSAL: + BASE_URL = UNIVERSAL_APP_CLIP_BASE_URL; + break; + } + + const url = new URL(BASE_URL); + const params: Record = { + publicKey, + redirectUrl, + services, + }; + + Object.keys(params).forEach((key) => + url.searchParams.append(key, params[key]), + ); + + return url.toString(); + } + private async allValidations( publicKey: string, redirectURL: string, @@ -140,7 +182,10 @@ class Connect { if (!this.verificationComplete) { await Connect.validatePublicKey(publicKey); Connect.validateRedirectURL(redirectURL); - const cleanServices = await Connect.validateInputData(data); + const cleanServices = await Connect.validateInputData( + data, + this.useAlphaVersionParams, + ); this.data = cleanServices; } @@ -157,7 +202,10 @@ class Connect { } } - private static async validateInputData(input: InputData): Promise { + private static async validateInputData( + input: InputData, + useAlphaVersionParams: boolean = false, + ): Promise { const supportedServicesAndTraits = await getSupportedServicesAndTraits(); const cleanServices: InputData = {}; @@ -187,13 +235,15 @@ class Connect { } const service = input[key]; - if (typeof service === 'boolean') { + if (typeof service === 'boolean' || useAlphaVersionParams) { if (!service) throw new GandalfError( 'At least one service has to be required', GandalfErrorCode.InvalidService, ); - cleanServices[key.toLowerCase()] = input[key as Source]; + if (useAlphaVersionParams) { + cleanServices[key.toLowerCase()] = true; + } else cleanServices[key.toLowerCase()] = input[key as Source]; } else { this.validateInputService(service, supportedServicesAndTraits); cleanServices[key.toLowerCase()] = input[key as Source]; From 14151fae9b54f13efb246093952957c2eba18168 Mon Sep 17 00:00:00 2001 From: TosinJs Date: Sun, 16 Jun 2024 23:13:21 +0100 Subject: [PATCH 7/8] Update --- README.md | 20 ++++++++++++++++++++ src/connect.ts | 8 +++----- src/types/index.ts | 1 + 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index f57d173..a3da3a0 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,26 @@ const datakey = Connect.getDataKeyFromURL("REDIRECT_URL") console.log(datakey) ``` +### Additional + +You can generate legacy Connect URLs by setting `useAlphaVersionParams` to true + +```typescript +const connect = new Connect({ + publicKey: process.env.PUBLIC_KEY, + redirectURL: "YOUR_REDIRECT_URL", + platform: Platform.ANDROID, + services: { uber: true }, + + // Set useAlphaVersionParams to true + useAlphaVersionParams: true, +}) +``` + +```bash +npm install @gandalf-network/connect --save +``` + ## Contributing Contributions are welcome, whether they're feature requests, bug fixes, or documentation improvements. diff --git a/src/connect.ts b/src/connect.ts index cf8ff12..9741a29 100644 --- a/src/connect.ts +++ b/src/connect.ts @@ -36,7 +36,7 @@ class Connect { verificationComplete: boolean = false; useAlphaVersionParams: boolean = false; - constructor(input: ConnectInput, useAlphaVersionParams: boolean = false) { + constructor(input: ConnectInput) { if (input.redirectURL.endsWith('/')) { input.redirectURL = input.redirectURL.slice(0, -1); } @@ -44,7 +44,7 @@ class Connect { this.redirectURL = input.redirectURL; this.data = input.services; this.platform = input.platform ? input.platform : Platform.IOS; - this.useAlphaVersionParams = useAlphaVersionParams; + this.useAlphaVersionParams = !!input.useAlphaVersionParams; } async generateURL(): Promise { @@ -241,9 +241,7 @@ class Connect { 'At least one service has to be required', GandalfErrorCode.InvalidService, ); - if (useAlphaVersionParams) { - cleanServices[key.toLowerCase()] = true; - } else cleanServices[key.toLowerCase()] = input[key as Source]; + cleanServices[key.toLowerCase()] = true; } else { this.validateInputService(service, supportedServicesAndTraits); cleanServices[key.toLowerCase()] = input[key as Source]; diff --git a/src/types/index.ts b/src/types/index.ts index 0da3abc..e0641a9 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -22,6 +22,7 @@ export type ConnectInput = { redirectURL: string; services: InputData; platform?: Platform; + useAlphaVersionParams?: boolean; }; export enum GandalfErrorCode { From 774a8da71e9358688cbc3512835b86a00bf3bd2a Mon Sep 17 00:00:00 2001 From: Tosin Samuel <68669102+TosinJs@users.noreply.github.com> Date: Mon, 17 Jun 2024 00:21:12 +0100 Subject: [PATCH 8/8] Update README.md --- README.md | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/README.md b/README.md index a3da3a0..45b4333 100644 --- a/README.md +++ b/README.md @@ -81,22 +81,6 @@ const datakey = Connect.getDataKeyFromURL("REDIRECT_URL") console.log(datakey) ``` -### Additional - -You can generate legacy Connect URLs by setting `useAlphaVersionParams` to true - -```typescript -const connect = new Connect({ - publicKey: process.env.PUBLIC_KEY, - redirectURL: "YOUR_REDIRECT_URL", - platform: Platform.ANDROID, - services: { uber: true }, - - // Set useAlphaVersionParams to true - useAlphaVersionParams: true, -}) -``` - ```bash npm install @gandalf-network/connect --save ```