Hello,
Currently I’m developing an integration in order to provide some additional API functionality to the ledger.
My current question is, in order for the integration to filter only ledger contracts (eg: @events.ledger.contract_created(LEDGER.ContractTemplate
))
I need to specify the package ID of the ledger like this: (@events.ledger.contract_created(f'{env.package_id}:{LEDGER.ContractTemplate}')
)
Is there any way around this? Or at least any way to get the ledger package_id “on the fly” without having to specify it every time a new hash is created?
Hi @Nuno_Carvalho,
Can you give us a bit more context? Perhaps the specific tools you’re currently using and the version number of the SDK, as a starting point?
Hi, currently I’m using the following versions:
daml-dit-api 0.4.5
daml-dit-ddit 0.6.5
daml-dit-if 0.6.12
dazl 7.10.3
daml-sdk 2.4.0
python3.9
Also running the integration with the following command:
ddit run --party=$(DAML_LEDGER_PARTY) integration.id
I think that’s all, let me know if I missed anything.
The way you’re currently doing it (passing in the package ID that you want) is probably the best long-term strategy.
You can omit the package ID altogether, and the Python client bindings will attempt to find a matching contract across all packages. This requires all packages on the ledger to be loaded and examined and this process can take a long time, particularly with ledgers that have accumulated lots of packages. And worse, this won’t work at all if anyone ever happens to upload a package with the same template because there won’t be a way to resolve the ambiguity.
You could automate the process of getting a package ID by using daml damlc inspect-dar
(see Simple CLI command to get the package id of a DAR) which might help take some of the drudgery out of keeping the package ID up-to-date locally in your client code.
Well if that’s the case then I will stick to it. I just wanted to make sure I was doing it the right way as I believe in the previous versions of daml this steps was not required and the integrations would automatically scan the ledger.
Thank you
@Nuno_Carvalho For integrations, there is a special case that might be useful to you.
Integrations are designed in a way that they are often packaged with a Daml model. The idea is that the Daml model for an integration provides the on-ledger representation for integration data, as well as the API for that integration. (See the existing Slack and CoinDesk integrations for examples of this.)
This notion of an integration bundled with a Daml model is built into ddit build
… The integration build process drives the Daml compiler, bundles the result model into the dit
file, extracts the package ID, and makes it available to the integration at runtime.
For a model built in this way, the integration framework can provide the package ID automatically. This makes it easy to use only the symbolic name for a contract template in an @events.ledger
annotation and avoid the problems @dtanabe mentions. (Because the integration framework is specifying the package ID for you.)
An example of an integration that uses this feature is the Slack integration, which is here:
The build process uses ddit build
, which detects the presence of a daml.yaml
file in the root for the build director when it builds the integration and ensures that the Daml model is built and packaged.
You can confirm the presence of a package ID in this DIT file using ddit inspect
. It will print either the Package ID or a message indicating there is no Daml model information present.
Assuming there Is Daml model information in a DIT file, the event decorators for ledger events will (by default) automatically use that model information to ensure a package ID.
Note that this can be explicitly disabled by setting package_defaulting
to False
. It will also avoid overriding a package ID that you specify explicitly and will not specify a package ID if you request events for all templates (*
).