Should we fetch this public party on the front end, and then pass it in as a choice param while creating a contract so they can be made observer on the new contract?
Youâre exactly right. The public party can be fetched from an applicationâs frontend by querying GET [ledgerId].projectdabl.com/.well-known/dabl.json (remember to substitute your real ledgerId on the subdomain).
This will return the party identifiers in JSON format for two special parties, Public and UserAdmin (the latter of which can be used as an operator party for your application). You can then supply the public identifier as a parameter when creating a contract that has a public : Party field (as an example).
The public party is also available through the project:DABL ledger UI - every party selector dropdown will have the Public party as an option when filling in contracts.
There are three ways of adding in the public party token.
Directly, you can make a request to POST api.projectdabl.com/api/ledger/[:ledgerId]/public/token (documented here)
If youâre creating a React-based UI, you can use this Daml Hub UI helper library @daml/hub-react - npm to create a <PublicLedger/> ledger context. Then you can use React binding equivalents to stream publicly viewable contracts.
The token can also be copy/pasted from the Users tab in Daml Hub, though this is of somewhat limited use due to 24 hour expiry of tokens. But, for completeness, I figured Iâd throw it out there.
If youâre using React, you can make use of some contexts from the aforementioned helper library. Install it in your project by running npm install @daml/hub-react
This example is for illustrative purposes, and I doubt will be directly copy-pastable, as it depends on how youâve structured the rest of your app. But hopefully it will demonstrate the general pattern that you can integrate into your app.
In your app, you will likely have an App component that wraps the application in a
<DamlLedger>
...
</DamlLedger>
context, which provides the Daml bindings as hooks to the children components.
If so, youâll want to wrap your application in some additional contexts. An App.tsx might look something along the lines of
// App.tsx
import React from 'react'
import DamlLedger from '@daml/react'
import { PublicLedger, WellKnownPartiesProvider, useWellKnownParties } from '@daml/hub-react'
import { ledgerId, httpBaseUrl } from '../config'
import MainScreen from './MainScreen'
/**
* React component for the entry point into the application.
*/
// APP_BEGIN
const App: React.FC = () => {
return (
<div className='app'>
<DamlLedger
token={/* user's auth token */}
party={/* user's party id */}
httpBaseUrl={httpBaseUrl}
>
<WellKnownPartiesProvider>
<PublicProvider>
<MainScreen/>
</PublicProvider>
</WellKnownPartiesProvider>
</DamlLedger>
</div>
)
}
// APP_END
const PublicProvider: React.FC = ({ children }) => {
// This component fetches the public party ID and uses it to instantiate a PublicLedger context
const { parties, loading } = useWellKnownParties();
if (loading || !parties) {
return <div>Loading...</div>
}
return (
<PublicLedger
ledgerId={ledgerId}
publicParty={parties.publicParty}
>
{ children }
</PublicLedger>
)
}
export default App;
Inside the MainScreen component, youâll be able to use public streaming hooks, like so.
// MainScreen.tsx
import React from 'react'
import { useStreamQueriesAsPublic } from '@daml/hub-react'
// import your template from @daml.js/.../
const MainScreen: React.FC = () => {
const allPublicContracts = useStreamQueriesAsPublic(MyPublicTemplate);
return (
<div className='main-screen'>
{ /* display public contracts */}
{ allPublicContracts.map(c => <p>{c.contractId}</p>) }
</div>
)
}
export default MainScreen;
Thanks for your reply.
we had tried @daml/hub-react but we are facing an issue while using useStreamQueriesAsPublic.
useStreamQueries works fine and I upgraded to version 1.11.1
(alias) namespace ClientProject
(alias) const ClientProject: damlTypes.Template<ClientProject, ClientProject.Key, "a632bd8c1ac26369271261732332aa9681d4b048233820d021df67c099072c6b:Main:ClientProject"> & {
...;
}
import ClientProject
Argument of type 'Template<ClientProject, Key, "a632bd8c1ac26369271261732332aa9681d4b048233820d021df67c099072c6b:Main:ClientProject"> & { Archive: Choice<ClientProject, Archive, {}, Key>; ... 7 more ...; ProposeSubmission: Choice<...>; }' is not assignable to parameter of type 'Template<object, unknown, string>'.
Type 'Template<ClientProject, Key, "a632bd8c1ac26369271261732332aa9681d4b048233820d021df67c099072c6b:Main:ClientProject"> & { Archive: Choice<ClientProject, Archive, {}, Key>; ... 7 more ...; ProposeSubmission: Choice<...>; }' is missing the following properties from type 'Template<object, unknown, string>': sdkVersion, keyEncode, encodets(2345)
...Main:ClientProjectâ> & { ...; }' is missing the following properties from type âTemplate<object, unknown, string>â: sdkVersion, keyEncode, encode
without public: useStreamQueries(ClientProject) works fine, using the old lib: { useStreamQueries } from â@daml/reactâ;
Have you tried clearing your node_modules and reinstalling the dependencies? The old package might still be cached somewhere. Try the following within your projectâs UI directory.