How to extend default Party interface in DAML? - daml

I am new to DAML. I am experimenting DAML for lifecycle management for financial instruments use case. One question comes to my mind is how do we extend the default Party interface? Currently I see that a Party can only have a name and id.
A lender/borrower can have its own properties like legal entity id, legal account number and corp id etc... How can we associate those details to a Party in this case lender or borrower?

The way to model workflows in Daml is through templates for smart contracts. In your case you want to create role template for borrower, lender etc. In addition to storing the details you mentioned, a role contract allows to implement rights and obligations that the role should have. E.g. a borrower has the right to apply for a loan, which can be implemented using a nonconsuming choice on a Borrower Daml template.
A role contract can be associated with a Daml Party by way of a contract key. Contract key ensures uniqueness of the contract for the key (in the example below for the combination of system operator and borrower parties) and allows to fetch the contract from the ledger by key. Here's a quick example
template Borrower
with
sysOperator : Party
borrower : Party
fullName : Text
lei : Text
accNum : Int
where
signatory sysOperator, borrower
key (sysOperator, borrower) : (Party, Party)
maintainer key._1
nonconsuming choice ApplyForLoan : ContractId LoanApplication
with
lender : Party
amount : Decimal
expiryDate : Date
controller borrower
do
create LoanApplication with ..

Related

DAML: Create a template in scenario requiring a ContractId as input and exercise a choice automatically after submit

I have 2 questions regarding DAML the possibility of automated choices and scenario.
I have this template that requires the input of a ContractId:
template Create_Creation
with
current_login : Party
artist : Party
title : Text
votingRight : Set Party
observers_list_id : ContractId Observers
where
signatory current_login
I need to create some of these templates in scenario, but am unable to specify a ContractId (like #0:0), giving me errors such as: Couldn't match expected type 'ContractId Observers' with actual type 'Text' Is it possible to specify a ContractId in scenario?
Next, in the above template I have a choice defined called Load_all_creation_observers that creates a template Creation and loads the observers specified in template Observers into it as observers:
choice Load_all_creation_observers : ContractId Creation
controller current_login
do
observers_list <- fetch observers_list_id
create Creation with created_by = current_login; artist = artist; title = title;
votingRight = votingRight; observers_list_id = observers_list_id; observers = observers_list.observers
template Observers
with
superuser : Party
observers : Set Party
where
signatory superuser
observer observers
As the code stands now, when a user creates a Create_Creation template he is required to perform the Load_all_creation_observers choice to create the Creation template with all the observers loaded into it. Is it possible to perform this choice automatically when a user submits the Create_Creation template? or maybe not make it a choice at all and define it as automated functionality like you would do in normal programming languages (if statements). You can only seem to define do functions in choices.
Given that the question about contract ids has already been answered, I’ll focus on your second question.
You cannot execute a choice automatically (you could have some off-ledger automation, e.g. a DAML trigger that does that but you don’t get any atomicity guarantees in that case). The way I would solve this problem is to define a new template with a single choice and then call that choice using CreateAndExercise on the ledger API. This is pretty much equivalent to defining a top-level function. For your example this would look something like the following
template CreateCreationTemplate
with
p : Party
where
signatory p
choice CreateCreation : ContractId Creation
with
observers_list_id : ContractId Observers
artist : Party
title : Text
votingRight : Set Party
do observers_list <- fetch observers_list_id
create Creation with
created_by = p
artist = artist
title = title
votingRight = votingRight
observers_list_id = observers_list_id
observers = observers_list.observers
You could have some of the fields of the choice as fields of a template but as a general guideline, I tend to only have the party as a field of the template when emulating top-level functions.
Depending on your usage, it is also possible to have a single “factory” template with a non-consuming CreateCreation choice.
In a scenario, the only contracts that exist on the ledger are those that have been created thus far in that scenario. So if there is an Observers contractId an Observers contract must have been created at some previous point in the scenario.
ContractIds are opaque and definitely not predictable, so it makes no sense to think of a contract-id literal. Instead, when the contract is created, bind the resulting id at that point. Ie.
test = scenario do
su <- getParty "Super User"
obsId <- su submit create Observers with ...
p1 <- getParty "Party 1"
ccId <- p1 submit create Create_Creation with ...; observers_list_id = obsId

Is it possible to restrict a template to be created only once per day

Is it possible to define a template Daily, which can only be created once per day in the sense that if Alice creates one, Bob no longer can, and if Bob creates one, Alice no longer can?
When asking about constraints like "one per day" in DAML, one has to think about the scope of that constraint and who guarantees it.
The simplest possible template in DAML is
template Daily
with
holder : Party
where
signatory holder
An instance of this template is only known to holder. There is no party, or set of parties that could ensure that there is only one such contract instance between Alice and Bob. In certain ledger topologies, Alice and Bob may not even know about each other, nor is there any party that knows about both.
A set of parties that guarantees the uniqueness is needed:
template Daily
with
holder : Party
uniquenessGuarantors : [Party]
...
The uniqueness guarantors need to be able to enable or block the creation of a Daily. In other words, they need to be signatories.
template Daily
with
holder : Party
uniquenessGuarantors : [Party]
where
signatory holder, uniquenessGuarantors
Now the easiest way to guarantee any sort of uniqueness in DAML is by using contract keys. Since we want one per day, we need a Date field.
template Daily
with
holder : Party
uniquenessGuarantors : [Party]
date : Date
where
signatory holder, uniquenessGuarantors
key (uniquenessGuarantors, date) : ([Party], Date)
maintainer key._1
What this says is that there is a unique copy of Daily for each key, and the guarantors in key._1 are responsible for making it so.
Finally you need a mechanism for actually creating these things, a sort of DailyFactory provided by the guarantors. That factory can also take care of making sure that date is always set to the current date on the ledger.
template DailyFactory
with
uniquenessGuarantors : [Party]
holder : Party
where
signatory uniquenessGuarantors
controller holder can
nonconsuming FabricateDaily
: ContractId Daily
do
now <- getTime
let date = toDateUTC now
create Daily with ..
A simple test shows how it works, with uniqueness being guaranteed by a single party Charlie:
test_daily = scenario do
[alice, bob, charlie] <- mapA getParty ["Alice", "Bob", "Charlie"]
fAlice <- submit charlie do
create DailyFactory with
holder = alice
uniquenessGuarantors = [charlie]
fBob <- submit charlie do
create DailyFactory with
holder = bob
uniquenessGuarantors = [charlie]
-- Alice can get hold of a `Daily`
submit alice do
exercise fAlice FabricateDaily
-- Neither can create a second
submitMustFail alice do
exercise fAlice FabricateDaily
submitMustFail bob do
exercise fBob FabricateDaily
-- The next day bob can create one
pass (days 1)
submit bob do
exercise fBob FabricateDaily
-- But neither can create a second
submitMustFail alice do
exercise fAlice FabricateDaily
submitMustFail bob do
exercise fBob FabricateDaily
Note that in terms of privacy, Alice and Bob don't know about each other or the other's Daily or DailyFactory, but the uniquenessGuarantors know all parties for which uniqueness is maintained, and know of all Daily instances for which they guarantee uniqueness. They have to!
To run the above snippets, you need to import DA.Time and DA.Date.
Beware that getTime returns UTC - and consequently the code would guarantee uniqueness, one per day, according to UTC, but not for example according to local calendar (which could be, say, Auckland NZ).

How to interpret Record Type in Socrata New York City Real Property Legals database?

Can you look at https://data.cityofnewyork.us/City-Government/ERROR-in-record-type/dq2e-3a6q
This shows a record type that appears to be incorrect.
It shows
P:10,item":"Bloomfield"},{"count":9,item":"New Britain"},{"count":8,item":"West Htfd"},{"count":7,item":"Torrington"},{"count":6,item":"Meriden"},{"count":5,item":"Whfd"},{"count":4,item":"Manchester
If you select count(*) and group by record_type you see:
curl 'https://data.cityofnewyork.us/resource/636b-3b5g.json?$select=count(*),record_type&$group=record_type'
[ {
"count" : "1",
"record_type" : "P:10,item\":\"Bloomfield\"},{\"count\":9,item\":\"New Britain\"},{\"count\":8,item\":\"West Htfd\"},{\"count\":7,item\":\"Torrington\"},{\"count\":6,item\":\"Meriden\"},{\"count\":5,item\":\"Whfd\"},{\"count\":4,item\":\"Manchester"
}
, {
"count" : "36631085",
"record_type" : "P"
}
This means there are 36M record type's having the value "P" and one very odd one.
One suggestion for New York City Open Data Law:
We must modify the Open Data Law (http://www1.nyc.gov/site/doitt/initiatives/open-data-law.page) to require New York City Government agencies to not only to open up data but to actually use the open data portal for government agency public sites.
If we allow agencies to simply dump data into a portal, then we have no quality testing. And agencies can trumpet how many datasets are open but no one is actually using the data.
This simple change "agency must use it's own data (aka, dogfood)" will encourage quality. If you read, http://www1.nyc.gov/site/doitt/initiatives/open-data-law.page it only mentions quality once and nothing about usage of the data. A portal is not a thing to brag about, it is an important way to join technology and government.
Thanks!

Retrieve item's price history on Steam market

Regarding items from Steam market I was wondering if there is a way to retrieve the price history of an item over a period of time.
I know that Steam provides a special api for developers who want to integrate market specific data into their own sites but I haven't been able to find anything about retrieving price history for an item in the form of a json.
Have any of you already done this ?
I've done some more research and found the way you can retrieve the price history for an item.
As an example for those who are curious, the price history for this random item "Specialized Killstreak Brass Beast" can be retrieved in this way:
http://steamcommunity.com/market/pricehistory/?country=DE&currency=3&appid=440&market_hash_name=Specialized%20Killstreak%20Brass%20Beast
If calling from code
url ="http://steamcommunity.com/market/pricehistory/"
and the query string payload is:
{
"country" = "US", # two letter ISO country code
"currency"= 1, # 1 is USD, 3 is EUR, not sure what others are
"appid" = 753, # this is the application id. 753 is for steam cards
"market_hash_name" ="322330-Shadows and Hexes" # this is the name of the item in the steam market.
}
country code is the ISO Country Code.
you can find the app id for a game from the URL of its store page. Example: The game "CS:GO" app id is 730. Store page
You can find the market hash name from the URL of its market page. Example: This CS:GO item hash name is "Glove Case Key".
Price history for the Glove Case Key is here.

hCard address with a 'care of' (c/o) element

Say I've got an address like this:
Foobar Widget Team
c/o ACME Widgets Inc.
123 The Drive
Someplace Town
BN1 1AB
I want to mark this up as an hCard but I am not sure what class names I should apply to the two organisation names. Foobar Widget Team might be a group of employees who get together and run a local football team, supported and sponsored by ACME but not officially an organisational unit of ACME - they're just using ACME as the mailing address.
So what is the best way of expressing this using hCard? I thought of using the AGENT property, but that seems to apply to a person rather than an organisation acting on behalf of another. Organization-unit isn't quite right either as, strictly speaking, Foobar Widget Team isn't a unit of ACME. How else might I mark this up?
I think that AGENT would be correct to use for an organization as well; the only requirement is that it is something that is separately addressable which can act on behalf of the the intended recipient.
The other option would just be to use the free-form LABEL field for the address of Foobar Widget Team, including everything from the "c/o" to the end. Given that there aren't likely to be a lot of consumers that will get any value out of specifying the relationship precisely, just putting it into a freeform text value will allow simple programs that just extract the address to produce an address label that contains the right information, without having to understand what the "c/o" line means.