- ISO20022: As defined in ISO20022 website:
ISO20022 is a single standardization approach (methodology, process, repository) to be used by all financial standards initiatives.
-
ISO20022 messaging system: A decentralized messenger connecting financial institutions, so they can pass their ISO20022 messages securely between each other, like SWIFT in traditional banks. This system consists of a smart contract deployed on the Coreum blockchain and a client application distributed between financial institutions to connect to the smart contract.
-
ISO20022 Client: The application running on financial institutions' infrastructure that abstracts away all the complexities related to blockchain and acts as an HTTP server, so other applications in the institution can send and receive ISO20022 messages to or from it.
-
ISO20022 Message: An XML file generated using financial applications (like accounting apps) using the ISO20022 standard describing a financial operation like transferring credits.
The process of sending an ISO20022 message consists of 4 steps:
- Reading and parsing the XML file of the message and extracting the Financial Institution Identity information of the recipient from each message
- Finding the wallet address and public key of the recipient from the address book
- Compressing the XML file and encrypting it with a symmetric key generated from the public key of the receiver and the private key of the sender using diffie-hellman key exchange method
- Minting a NFT from the encrypted data & sending it to the smart contract
The process of receiving an ISO20022 message consists of 7 steps:
- Querying new messages periodically
- Querying the NFT information of a received message
- Decrypting the NFT data using the symmetric key generated from the public key of the sender and the private key of the recipient using diffie-hellman key exchange method and decompressing it
- Parsing the XML file of the message and extracting the Financial Institution Identity information of the sender from the message
- Finding the wallet address of the sender from the address book
- Verifying if the sender of the message to the smart contract is the same with the sender in ISO20022 message
- Writing the XML message to a file
As a simple example, let's say one person (Debtor) has an account in one financial institution (Debtor Agent) wants to transfer some credits to another person (Creditor) that has an account in another financial institution (Creditor Agent).
The Debtor will send a PAIN.001
(CustomerCreditTransferInitiation under Payment Initiation)
message to the Debtor Agent which is outside of scope of this project.
Then the Debtor Agent should transfer the credits to Creditor Agent, so the Creditor can receive the credit.
Both financial institutions are connected to the ISO20022 messaging system using the ISO20022 client application.
In traditional banking,
the PACS.008
message should be sent to SWIFT application to be delivered to the other financial institution.
However, using this system,
it should be sent to the HTTP server that ISO20022 client is running either directly to the HTTP server,
or using the command line interface.
It then extracts the actual receiver of the message,
compresses and encrypts the message and delivers it to the smart contract.
The Creditor Agent is polling the smart contract periodically,
and it will receive the message that the Debtor Agent sent.
It will receive,
decrypt and decompress it and then the Creditor Agent can process the request and send a report to the Creditor using
CAMT.053
(BankToCustomerStatement under Cash Management) which is also outside of scope of this project.
In the example above, we only handle the messaging part of the settlement, but the actual transfer of the funds is on
the two parties to handle. We also provide an option to do the actual transfer of the funds using our chain.
If a party sends a PACS.008
(FIToFICustomerCreditTransfer under Payments Clearing and Settlement) with settlement
method set to CLRG
(Clearing system) and the clearing system proprietary set to COREUM
, the client application
will take care of the RTGS.
<SttlmInf>
<SttlmMtd>CLRG</SttlmMtd>
<ClrSys>
<Prtry>COREUM</Prtry>
</ClrSys>
</SttlmInf>
When Coreum in charge of the settlement, the client will send an additional message to the smart contract, to send the
funds to an escrow account and then continue normally and deliver the message to the other party.
If the other party sends a PACS.002
(FIToFIPaymentStatusReport under Payments Clearing and Settlement) message back to
the first party, accepting the message, the funds will be sent from the escrow account to the account of the send party.
And if instead the other party decides to reject the payment, it will send the PACS.002
message with rejected status
and the first party will be refunded.
ISO20022 is designed for traditional banking and as of now, it only supports ISO4217 currencies (like USD, EUR, ...). To provide RTGS support while being ISO20022-compliance, we define 3 rules:
- The amount (
IntrBkSttlmAmt
) should be set to0
- The currency (
Ccy
) should be set toUSD
- The actual amount and currency (actually cryptocurrency) should be provided as
SplmtryData
The supplementary data would be as simple as this:
<SplmtryData>
<PlcAndNm>CryptoCurrencyAndAmountInfo</PlcAndNm>
<Envlp>
<s:Document>
<s:CryptoCurrencyAndAmount Dti="6G5C9N3LG">0.001</s:CryptoCurrencyAndAmount>
</s:Document>
</Envlp>
</SplmtryData>
Supplementary Data XSD
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="urn:iso:std:iso:20022:tech:xsd:supl.xxx.001.01"
targetNamespace="urn:iso:std:iso:20022:tech:xsd:supl.xxx.001.01"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xs:element name="Document" type="Document"/>
<xs:complexType name="Document">
<xs:sequence>
<xs:element name="CryptoCurrencyAndAmount" type="CryptoCurrencyAndAmountType"/>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="CryptoCurrencyAndAmount_SimpleType">
<xs:restriction base="xs:decimal">
<xs:fractionDigits value="18"/>
<xs:totalDigits value="40"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="CryptoCurrencyAndAmountType">
<xs:simpleContent>
<xs:extension base="CryptoCurrencyAndAmount_SimpleType">
<xs:attribute name="Dti" type="DigitalTokenIdentifier"/>
<xs:attribute name="Cccy" type="CryptoCurrencyCode"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:simpleType name="DigitalTokenIdentifier">
<xs:restriction base="xs:string">
<xs:pattern value="[A-Z0-9]{9,9}"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="CryptoCurrencyCode">
<xs:restriction base="xs:string">
<xs:pattern
value="ucore|utestcore|udevcore|[a-zA-Z][a-zA-Z0-9/:._]{0,50}-[a-z02-9]+1[qpzry9x8gf2tvdw0s3jn54khce6mua7l]+|ibc/[A-Z0-9]{64,64}"/>
<xs:maxLength value="127"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
For the currency, we are using DTIF (Digital Token Identifiers Foundation) website as a reference.
The list of available tokens can be found in their registry.
You can send any token listed there which its Auxiliary Digital Token Distributed Ledger is S87NJRT7T
(Coreum).
For now, the only supported token is TESTCORE with token identifier 6G5C9N3LG
.
So, in the example above, 0.001 of 6G5C9N3LG token will be converted to 1000utestcore.
NOTE: We are in process of allocating DTIs to our tokens and the DTIs used above are temporary and should not be used
in production. This document will be updated as soon as we are done with the process. For now, please use the Cccy
.
The alternative way is providing the whole denom for the token. It will only support the native token of the chain
(ucore
for mainnet, utestcore
for testnet and udevcore
for the devnet), Smart FT tokens (like
SUBUNIT-testcore1adst6w4e79tddzhcgaru2l2gms8jjep6a4caa7
) and IBC coins (like
ibc/927661F31AA9C5801D58104292A35053097B393CFFA0D9B6CB450A3D66D747FA
).
<SplmtryData>
<PlcAndNm>CryptoCurrencyAndAmountInfo</PlcAndNm>
<Envlp>
<s:Document>
<s:CryptoCurrencyAndAmount Cccy="utestcore">1000</s:CryptoCurrencyAndAmount>
</s:Document>
</Envlp>
</SplmtryData>
Preferred method is the DTI and Cccy is only there as an alternative.
Example PACS.008 message with supplementary data
<?xml version="1.0" encoding="UTF-8"?>
<Document
xmlns="urn:iso:std:iso:20022:tech:xsd:pacs.008.001.12" xmlns:s="urn:iso:std:iso:20022:tech:xsd:supl.xxx.001.01">
<FIToFICstmrCdtTrf>
<GrpHdr>
<MsgId>EEEE-150929-EUR-057-12</MsgId>
<CreDtTm>2015-09-29T09:00:00</CreDtTm>
<NbOfTxs>1</NbOfTxs>
<SttlmInf>
<SttlmMtd>CLRG</SttlmMtd>
<ClrSys>
<Prtry>COREUM</Prtry>
</ClrSys>
</SttlmInf>
<InstgAgt>
<FinInstnId>
<BICFI>B61NZT4Y</BICFI>
</FinInstnId>
</InstgAgt>
<InstdAgt>
<FinInstnId>
<BICFI>6P9YGUDF</BICFI>
</FinInstnId>
</InstdAgt>
</GrpHdr>
<CdtTrfTxInf>
<PmtId>
<InstrId>EEEE-150929-EUR-057-12</InstrId>
<EndToEndId>AABC-ABC-13679-2015-09-132</EndToEndId>
<TxId>BBBB-150928-CCT-EUR-911-1</TxId>
</PmtId>
<PmtTpInf>
<InstrPrty>NORM</InstrPrty>
</PmtTpInf>
<IntrBkSttlmAmt Ccy="USD">0</IntrBkSttlmAmt>
<IntrBkSttlmDt>2015-09-29</IntrBkSttlmDt>
<InstdAmt Ccy="EUR">500000</InstdAmt>
<ChrgBr>CRED</ChrgBr>
<ChrgsInf>
<Amt Ccy="EUR">500</Amt>
<Agt>
<FinInstnId>
<BICFI>BBBBUS33</BICFI>
</FinInstnId>
</Agt>
</ChrgsInf>
<ChrgsInf>
<Amt Ccy="EUR">250</Amt>
<Agt>
<FinInstnId>
<BICFI>EEEEDEFF</BICFI>
</FinInstnId>
</Agt>
</ChrgsInf>
<Dbtr>
<Nm>ABC Corporation</Nm>
<PstlAdr>
<StrtNm>Times Square</StrtNm>
<BldgNb>7</BldgNb>
<PstCd>NY 10036</PstCd>
<TwnNm>New York</TwnNm>
<Ctry>US</Ctry>
</PstlAdr>
</Dbtr>
<DbtrAcct>
<Id>
<Othr>
<Id>00125574999</Id>
</Othr>
</Id>
</DbtrAcct>
<DbtrAgt>
<FinInstnId>
<BICFI>BBBBUS33</BICFI>
</FinInstnId>
</DbtrAgt>
<CdtrAgt>
<FinInstnId>
<BICFI>DDDDBEBB</BICFI>
</FinInstnId>
</CdtrAgt>
<Cdtr>
<Nm>GHI Semiconductors</Nm>
<PstlAdr>
<StrtNm>Avenue Brugmann</StrtNm>
<BldgNb>415</BldgNb>
<PstCd>1180</PstCd>
<TwnNm>Brussels</TwnNm>
<Ctry>BE</Ctry>
</PstlAdr>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>BE30001216371411</IBAN>
</Id>
</CdtrAcct>
<Purp>
<Cd>GDDS</Cd>
</Purp>
<RmtInf>
<Strd>
<RfrdDocInf>
<Tp>
<CdOrPrtry>
<Cd>CINV</Cd>
</CdOrPrtry>
</Tp>
<Nb>ABC-13679</Nb>
<RltdDt>
<Tp>
<Cd>INDA</Cd>
</Tp>
<Dt>2015-09-08</Dt>
</RltdDt>
</RfrdDocInf>
</Strd>
</RmtInf>
<SplmtryData>
<PlcAndNm>CryptoCurrencyAndAmountInfo</PlcAndNm>
<Envlp>
<s:Document>
<s:CryptoCurrencyAndAmount Dti="6G5C9N3LG">0.001</s:CryptoCurrencyAndAmount>
</s:Document>
</Envlp>
</SplmtryData>
</CdtTrfTxInf>
</FIToFICstmrCdtTrf>
</Document>
If you want to get started quickly and learn how to interact with the application first, you need to have the binary, initialize it, add your wallet key and register your institution. Then you can start the application and interact with it.
You can download the latest build from Releases page of the repo according to your operating system (OS) and CPU architecture.
Or you can clone the project and make it using:
make build
It's better to either copy the binary to one the paths listed in your PATH
environment variable
or add the binary directory to the PATH
environment variable.
To see the directories listed in your PATH
environment variable, you can run:
echo $PATH
When you want to work with the binary for the first time, you need to initialize it, so it can generate the right configuration for the application.
Usually it's as easy as running:
iso20022-client init
But you have the option to configure it otherwise. For example, if you want to connect to testnet instead of mainnet, you can run:
iso20022-client init --chain-id=coreum-testnet-1 --coreum-contract-address=testcore1sx8h66ehjcj999t5apz5993y9n6nxwdr5jcd06mzrquxdkful4tqpugwh8 --coreum-grpc-url=https://full-node.testnet-1.coreum.dev:9090
To be able to join the blockchain network, you need to have an account in Coreum blockchain. To have that, you need to use a wallet that is connected to Coreum mainnet and has enough funds to deliver messages.
Sending each message to the network costs some small tokens, the fund is necessary for this purpose.
Once you've created that, you can use the same mnemonics of the account in the ISO20022 Client, so it can use the same account:
iso20022-client keys add iso20022-client --recover
Alternatively, you can generate the account in the ISO20022 Client:
iso20022-client keys add iso20022-client
And import the mnemonics to your wallet and fund your account.
Each financial institution should be registered before being able to send or receive messages to the network.
To do so, you need to have the ISO20022 Financial Institution Identity information of your institute, the wallet address and your public key.
After adding your key to the application in the previous step, it will show you an output like this:
- address: core1tagmslrz9xqfyjdddt6nu3q97us3ejck6475n8
name: iso20022-client
pubkey: '{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"AqV7ob5PTCKOaiOp6iD6tQvjGorS6xLJiGQaVRBvQzM+"}'
type: local
- The address written after the
address:
in the output is your wallet address. - The
key
part of thepubkey
is your public key. - The ISO20022 Financial Institution Identity information is how you are identified in ISO20022 messages, which usually is using a Business Identification Code (BIC).
Now you need fill this form with the information about your institution. Once your request is processes, you can continue and start the application and interact with it.
Note: You are not obligated to use our Address Book. You can use our binary to send message between nodes in a community you want which uses another address book and change the address in the config file.
To start the application, you need to run:
iso20022-client start
It will start the HTTP server on port 2843
that receives ISO20022 messages in XML format
and delivers them to the smart contract deployed on blockchain.
If you open the same port of your local machine in your browser, you can see the Swagger documentation of this HTTP server:
Usually the simple start
command is enough to run the HTTP server,
but if you need to run it on another port, or use another key name, you can do so like this:
iso20022-client start --server-addr=':2844' --key-name=iso20022-client-2
The HTTP server should be running all the time, so you can interact with it.
Sending and receiving messages is done using HTTP requests like described in the Swagger API documentation,
but as an alternative, there are send
and receive
command line sub commands available in the binary.
Sending an ISO20022 message which is actually an XML file is done by:
iso20022-client message send /path/to/read/request.xml
Alternatively, if you have run your HTTP server using another port, you can do:
iso20022-client message send /path/to/read/request.xml --server-addr=':2843'
For receiving messages, you need to periodically run the receive
sub command (or poll the HTTP endpoint):
iso20022-client message receive /path/to/write/response.xml
For the first PoC version, the only supported Business Area (BA) is Payments Clearing and Settlement (PACS).
- Add new messages from ISO20022 message definitions.
- Add old messages from ISO20022 message archive.