Foundry React Mobile App ODSK

Hi All,

I am currently developing a mobile React Native app using Expo. I’ve successfully created the project using the Expo CLI and have connected it to an iOS simulator via Xcode. The base application runs fine without any issues.

However, I encountered problems when attempting to integrate Foundry using the OSDK. I followed the standard setup steps:

  1. Exported my Foundry token (FOUNDRY_TOKEN).
  2. Added the .npmrc configuration for the registry.
  3. Installed the required packages:
  4. Initialized the createClient and attempted to fetch objects as per the provided example in the documentation.

When running the application (npx expo start → Press i for the iOS simulator), I keep encountering the error:

Unable to resolve "@osdk/client" from “FoundryClient.tsx”`

I’ve spent significant time debugging this and believe the issue is related to Metro Bundler’s inability to resolve the package properly. The error suggests the @osdk/client package may not be properly exported under the "exports" field in its package.json file, causing Metro Bundler to fail to locate the module during the build process.

Steps to Reproduce:

To reproduce the issue:

  1. Create a blank Expo TypeScript project:

lua

Copy code

npx create-expo-app FitnessApp --template with-typescript
  1. Install Foundry OSDK packages using the provided instructions.
  2. Initialize the createClient and attempt to fetch data using the basic client-server setup.
  3. Run the project:

sql

Copy code

npx expo start  
  1. Open the iOS simulator using i.

Current Behavior:

The Metro Bundler fails with the error:
Unable to resolve "@osdk/client" from “FoundryClient.tsx”`


I would greatly appreciate any insights or solutions on how to properly configure Metro Bundler or the package.json exports to resolve this issue.

Thank you in advance for your help!

Best Regards,
Sam

There are few changes to the expo project that need to happen to support expo + OSDK.
If you run the createOSDK CLI like this:

npm create @osdk/app@2.1.0-beta.20 -- \
    --application ri.third-party-applications.main.application.7ebc94b7-bad3-45a9-a063-d7fc0ccd2873 \
    --foundryUrl https://REDACTED \
    --applicationUrl https://osdk20.REDACTED.com \
    --clientId 1564cead075af0exxxx1799ac0f6381f \
    --osdkPackage @osdk-sample-app-20/sdk \
    --osdkRegistryUrl https://REDACTED.com/artifacts/api/repositories/ri.artifacts.main.repository.b6d14786-c820-457a-9055-82a11dc7fdc1/contents/release/npm \
    --corsProxy false \
    --sdkVersion 2.x

You will be presented with the option to choose a framework where Expo is one,

Select a framework:
○ React
● Expo
○ Vue
○ Next (static export)
○ Tutorial: To do App
○ Tutorial: To do AIP App

Checkout the configuration (mainly metro config) and see the changes you need to make, or just start from the template we provide.

Hi,

Thank you for your response and guidance. As you suggested, I’m attempting to create a new project and then adjust my configuration to match the new setup.

Here is the command I used:

bash

Copy code

npx create @osdk/app@2.1.0-beta.20 -- \
    --application ri.third-party-applications.main.application.18a42506-c1da-4d07-8c93-abdc7bee94d2 \
    --foundryUrl https://REDACTED \
    --applicationUrl https://REDACTED \
    --clientId b496c08c12cd998e8104d9f70902c228 \
    --osdkPackage @fitness-application/sdk@0.2.0 \
    --osdkRegistryUrl https://REDACTED/artifacts/api/repositories/ri.artifacts.main.repository.34c4b8ab-017d-49dd-be84-96956080ed2b/contents/release/npm \
    --corsProxy false \
    --sdkVersion 2.x

However, when I ran this, I encountered the following error:

lua

Copy code

Could not load create-@osdk/app@2.1.0-beta.20: npx-import failed for create-/app@2.1.0-beta.20 with message:
    Command failed with exit code 1: npx --prefer-online -y -p create-@osdk printenv PATH
npm error code E404
npm error 404 Not Found - GET https://registry.npmjs.org/create- - Not found
npm error 404
npm error 404  'create-@osdk' is not in this registry.
npm error 404
npm error 404 Note that you can also install from a
npm error 404 tarball, folder, http url, or git url.
npm error A complete log of this run can be found in: /Users/samrajsahota/.npm/_logs/2025-01-13T15_02_35_078Z-debug-0.log

You should install create- locally: 
    npm install --save-dev create-@osdk

To troubleshoot, I also removed the @2.1.0-beta.20 version suffix in case the issue was version-related, but I encountered the same error.

It seems the package create-@osdk/app or its specific version is not available in the registry I’m accessing. I’ve already verified that my .npmrc file is correctly configured to point to my private registry.

It may also be an issue with my arguments. The one I am not confident in is the ‘applicationURL’, the rest I’m fairly sure are accurate.

Any advice on why this issue might be occurring or how I can resolve it would be greatly appreciated.

Kind regards,
Sam

Did you just copied my command or did you get your command from your developer console?
I suggest you opt-out of beta features in the setting under SDK version and then get the proper CLI command from your dev console application under Bootstrap in local development environment

Hi,

I initially copied your code and change the parameters to match mine.

I’m already opted out of the beta features (See below)

However I am confused, as I do not have a ‘Bootstrap in local dev environment’

When I click ‘Start Developing’ I only have 2 options below.

The 1st one is what I already use which doesn’t work. The generate package does give me a CIL Command, but it seems different to yours, I tried it and I confident it’s not the right one.

npx @osdk/foundry-sdk-generator@latest generatePackage  \
    --authToken $FOUNDRY_TOKEN \
    --foundryHostname samrajsahota.euw-3.palantirfoundry.co.uk \
    --ontology ri.ontology.main.ontology.65d48866-78c3-42d9-9d9d-a44b383da23b \
    --packageName @fitness-application/sdk \
    --packageVersion 0.0.1 \
    --outputDir ./generated \
    --objectTypes FitnessAppTest

So I am confused. Please could you clarify when you get a chance!

Kind Regards
Sam

My guess is that you created a confidential client and not a public client. Expo application must be a public client application.

Hi,

I have 2 things to address:

1 - I am hoping for this Mobile App, to make it so I have one Foundry Confidential Client. And User Authentication isn’t done via Foundry (I will have my own). This is due to the limited foundry users allowed. Will this be possible if I choose a public client. If not, do you have a workaround?

2 - I made a new public client, and I copied the code in the local bootstrap which is below:

npm create @osdk/app@2.0.9 -- \
    --application ri.third-party-applications.main.application.7206bb9a-5046-4316-9b04-21eece149ca9 \
    --foundryUrl https://samrajsahota.euw-3.palantirfoundry.co.uk \
    --clientId 05f22404ba06661dfbfae9a910404e5c \
    --osdkPackage @reactfitness/sdk \
    --osdkRegistryUrl https://samrajsahota.euw-3.palantirfoundry.co.uk/artifacts/api/repositories/ri.artifacts.main.repository.b6d4c5bd-3725-4e39-b522-cb8377d5de21/contents/release/npm \
    --corsProxy false \
    --sdkVersion 2.x

When I ran this I didn’t get an option for Expo. So this is another issue.

Thank you for your help so far. If possible, are you able to address both issues please

Kind Regards
Sam

I am sorry about that.
The template we have is for a public client but you should be able to take the metro.config.js and use it in your confidential client.
I think it should be something like this:

// @ts-check
const { mergeConfig } = require("metro-config");
const { getDefaultConfig } = require("expo/metro-config");
const dotenv = require("dotenv");

// Load environment variables from .env.development
dotenv.config({ path: ".env.development" });

const defaultConfig = getDefaultConfig(__dirname);

module.exports = mergeConfig(defaultConfig, {
  transformer: {
    ...defaultConfig.transformer,
    babelTransformerPath: require.resolve("react-native-svg-transformer"),
  },
  resolver: {
    unstable_enablePackageExports: true,
    assetExts: (defaultConfig.resolver?.assetExts ?? []).filter(ext =>
      ext !== "svg"
    ),
    sourceExts: [...(defaultConfig.resolver?.sourceExts ?? []), "svg"],

    resolveRequest: function(context, moduleName, platform) {
      if (moduleName.includes("@osdk")) {
        context = {
          ...context,
          unstable_conditionNames: ["browser", "require", "import"],
        };
      }
      return context.resolveRequest(context, moduleName, platform);
    },
  },
});

For your 2nd issue, I do think you need a later version of the create app maybe try: https://www.npmjs.com/package/@osdk/create-app/v/2.0.11

Hi,

Thank you for your help so far! I have got the correct metro config so it’s exporting the ODSK packages correctly. However I got another issue.

I am running the confidential client using the code below

import { Client, createClient, Osdk } from "@osdk/client";
;
import { createConfidentialOauthClient } from "@osdk/oauth";
import { FitnessAppTest } from "@fitness-application/sdk";


const client_id: string = "REDACTED";
const url: string = "REDACTED";
const ontologyRid: string = "REDACTED";
const client_secret: string = "REDACTED Manually;

const auth = createConfidentialOauthClient(client_id, client_secret, url);
const client: Client = createClient(url, ontologyRid, auth);

export async function fetchObjects(): Promise<Osdk.Instance<FitnessAppTest>[]> {
    const objects = (await client(FitnessAppTest).fetchPage({ $pageSize: 10 }));
    return objects.data;
}

fetchObjects()
    .then((objects: Osdk.Instance<FitnessAppTest>[]) => {
        console.log(objects);
    })
    .catch(error => {
        console.error("FC Error fetching FitnessAppTest:", error);
    });


However I am receiving the following errors

 (NOBRIDGE) ERROR  FC Error fetching FitnessAppTest: [Error: Captured stack trace for error: Failed to get token: invalid_request]

However I am confident the Client_ID,Secret,URL & Ontology RID is all okay. So I believe the issue is the COORS Policy. This is my existing allowed IPS.

These worked before when I was running ODSKs before.
When I start my Expo Server I get the following:

Opening exp+fitnessapp://expo-development-client/?url=http%3A%2F%2F111.111.0.111%3A8082 on iPhone 16 Pro

So I am fairly certain the IP is http://111.111.0.111:8081

(IP Has been editied, and this is not the true IP).

This should fall under the http://localhost:8081 I believe. And I can add this IP manually to it, as it errors, and says invalid config.

Do you have any ideas how I can go about fixing or even debugging it. \

Kind Regards
Sam

Does anyone have any advice on the above?

I am not sure, you should see a loadObject call and a fre-flight call which is the CORS one.
Why do you think this is a CORS issue?
Do you see an error on the loadObject call? or do you see a valid response on that?
if so, what is the error instance id?

Hi,

Let me explain my thinking.

In my App I call the fetch object so it fetches the object.

However when I start up my App it fails, and the error is related to the get the token. I think this related to the creation of the Confidential Auth Client. See Pic Below.

Screenshot 2025-01-20 at 11.40.57

Thus I believe the issue is not do with the fetch. it’s to do with the Auth Dance to set up my Client. And I believe the issue is that Foundry isn’t allowing my call from my server to foundry. Causing it not to return the correct authentication, and erroring.

And I am not sure how to get the error_id

Kind Regards
Sam

@ewitkon
@LukaszF

Hi,

Just Tagging if you have any information on the above

I am sorry but I am not sure how to help you without more concrete information like which errors are you seeing and why are you using service user in a mobile client app like you have in the begging of the thread.

Hi,

Let me explain again, as I may not have explained it well. Thank you for helping me.

I am using a confidential Client, as If I use a public client, you have to be a user on my Foundry stack and authentication is done via connecting to Foundry. I don’t want to do this as I only have a max limit of 5 users, and expect more users. So I have decided instead to manage the Login on my App myself using Firebase. And just have one Foundry connection which pulls the specific data for whatever user is logged in.

So to do this, I believe I need to use a confidential client, and use a client secret to get the token, rather than the foundry Authentication. I hope this answers your initial question.

And then the error message is when I try to fetch any data from my Foundry. The code and error I recieve is.


  useEffect(() => {
    const testConfidentialOauthClient = async () => {
      const auth = createConfidentialOauthClient(client_id, client_secret, url);
      try {
        // Create the OAuth client
        const client: Client = createClient(url, ontologyRid, auth);
        const objects = (await client(FitnessAppTest).fetchPage({ $pageSize: 10 }));


      
        console.log("Token Retrieved:", auth.getTokenOrUndefined); // Log the token to verify it works
        console.log("Client Retrieved:", client); // Log the token to verify it works
        console.log("objects: ",objects.data)
      } catch (error) {
        console.error("Error in Confidential OAuth Client:", error);
      }
    };

    // Run the test on app startup
    testConfidentialOauthClient();
  }, []);

 (NOBRIDGE) ERROR  Error in Confidential OAuth Client: [Error: Captured stack trace for error: Failed to get token: invalid_request]

I have double checked my client_id,client_secret,url and ontology rid is all correct. I have generated a new SDK version as well and still got the same issue. I’m not sure what to do or how I can debug.

How do you want to secure the foundry client_id and client_secret if you are shipping an app to end users? Can you live with endusers extracting your credentials?
I would advice to use a public client or keep your credentials in a dedicated backend.

Are you able to perform the client credentials flow manually, with tools like curl or Postman?

Hi,

Thanks for your response. This app is not for live production, it is for a University Dissertation equivalent. However I have explored this issue already, and I would have it stored in the backend.

For your second question, I am unsure how to do this manually. I can’t find the Curl commands I would need to use, even after trying to explore the Foundry Packages.

Kind Regards
Sam

curl -k -X POST https://<<foundry_url>>/multipass/api/oauth2/token \
-H 'content-type: application/x-www-form-urlencoded' \
-d "client_id=<<client_id>>" \
-d "client_secret=<<client_secret>>" \
-d "grant_type=client_credentials"

Thanks for this.

After doing the CURL i got the following response.

{"error":"unauthorized_client","error_description":"The client is not authorized to use the provided grant type: client_credentials"}%   

Which I believe means, maybe my configuration of my ODSK is incorrect. So I went to have a look at creating a new one from fresh.

I selected The application type below, which is correct for what I want

However the issue I believe is to be in the Permissions section. even though I have selected a Confidential Backend Client, It still only lets me use User permissions, which is not what I want, I believe I need an application permissions. And I believe this is what is causing the initial error above.

The Reason I cannot select Application permissions is because it is not set up on my stack
Screenshot 2025-01-28 at 09.36.42

So to conclude I have a few questions:

  1. Do you agree that the Initial error is caused by the fact I am not using Application permissions and User permissions is being used in my ODSK?
  2. How can I go about getting access to Application permissions on my stack
  3. Once I have Application Permissions, it should allow me to create a Confidential Client.

Thank you for your help in this

Kind Regards
Sam

I think the AIPNow stacks don‘t not allow creation of TPAs with client credentials.