Skip to content

Commit

Permalink
Doc components (#1811)
Browse files Browse the repository at this point in the history
* add create offerings page

* rename

* add creating quotes page

* add onboarding docs

* remove infinite loop

* add overview and process-orders page. Recreate LanguageSwitchLink

* support older dependency components
  • Loading branch information
dayhaysoos authored Oct 8, 2024
1 parent cfa6c37 commit d35656e
Show file tree
Hide file tree
Showing 13 changed files with 946 additions and 10 deletions.
184 changes: 184 additions & 0 deletions site-new/docs/tbdex-sdk/pfi/creating-offerings.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
---
title: Creating Offerings
hide_title: true
sidebar_position: 6
---

import Shnip from "@site/src/components/Shnip";

# Creating Offerings

Offerings describe a currency pair that can be exchanged and specify the requirements, conditions, and constraints needed to fulfill the described transaction.
In other words, an Offering is a way of describing a financial product you’re offering as a PFI on a tbDEX network.

Any Wallet that has your PFI's DID will be able to query your PFI for all available Offerings, as well as fetch specific Offerings. Wallets will then use that data to make an [Request for Quote (RFQ)](/docs/tbdex/wallet/send-rfq) to your PFI to begin a potential transaction process.

## Create an Offering

You can use the tbDEX SDK to create Offerings.
An Offering must adhere to the [Offering schema](https://github.com/TBD54566975/tbdex/tree/main/specs/protocol#offering).

<Shnip languages={["JavaScript", "Kotlin"]} snippetName="pfiCreateOffering" />

### Required Claims

In order to comply with certain financial regulations, you may require information about the customer you are transacting with.
You can obtain this information via [Verifiable Credentials](/docs/web5/verifiable-credentials/what-are-vcs).

To specify the exact credentials you need, you can do so in the `requiredClaims` section of your Offering by [creating a Presentation Definition](/docs/web5/verifiable-credentials/presentation-definition/).
You'll specify all required forms and details of proof, optional selection rules, and define flexibility where possible when different types of input may satisfy the requirements.

For a full breakdown of all the available fields and combinations, [see the DIF website](https://identity.foundation/presentation-exchange/#presentation-definition) for details.

Below is an example of how you could specify that a [KnownCustomerCredential](https://www.tbdex.io/guides/kcc) is required to order this Offering:

<Shnip
languages={["JavaScript", "Kotlin"]}
snippetName="kccPresentationDefinition"
/>

Once you've created your required claims, it's important to validate them to ensure there are no errors in the design.
This will throw an error if it's not valid.

<Shnip languages={["JavaScript", "Kotlin"]} snippetName="kccValidatePd" />

### Sign Offering

After creating your Offering, it's necessary to cryptographically sign it so that Wallet apps know that it's authentic.

<Shnip languages={["JavaScript", "Kotlin"]} snippetName="pfiSignOffering" />

### Validate Offering

After signing the Offering, you can validate that your Offering's structure is valid.
This will throw an error if it's not valid.

<Shnip languages={["JavaScript", "Kotlin"]} snippetName="pfiValidateOffering" />

Once the Offering has been generated, you can store it in your database using code as shown in the [Offerings API Provider section](/docs/tbdex/pfi/anatomy-of-a-pfi#offerings-api-provider).

## Sample Offering

When combining all the data above, you can end up with a full Offering object that looks something like the following:

```js
{
"metadata": {
"from": "did:dht:d4sgiggd3dwimo4ubki7spo45q5dazxphrizbxhcgapapcnzpouy",
"protocol": "1.0",
"kind": "offering",
"id": "offering_01htkr88ybffzbxfea01rq3ht9",
"createdAt": "2024-04-04T05:10:38.796Z"
},
"data": {
"description": "Selling BTC for USD",
"payin": {
"currencyCode": "USD",
"methods": [
{
"kind": "DEBIT_CARD",
"requiredPaymentDetails": {
"$schema": "http://json-schema.org/draft-07/schema",
"type": "object",
"properties": {
"cardNumber": {
"type": "string",
"description": "The 16-digit debit card number",
"minLength": 16,
"maxLength": 16
},
"expiryDate": {
"type": "string",
"description": "The expiry date of the card in MM/YY format",
"pattern": "^(0[1-9]|1[0-2])\\/([0-9]{2})$"
},
"cardHolderName": {
"type": "string",
"description": "Name of the cardholder as it appears on the card"
},
"cvv": {
"type": "string",
"description": "The 3-digit CVV code",
"minLength": 3,
"maxLength": 3
}
}
}
}
]
},
"payout": {
"currencyCode": "BTC",
"methods": [
{
"kind": "BITCOIN_ADDRESS",
"estimatedSettlementTime": 60,
"fee": "0.25"
}
]
},
"payoutUnitsPerPayinUnit": "0.00003826",
"requiredClaims": {
"id": "presentation-definition-kcc",
"name": "Customer Verification",
"purpose": "We need to verify your customer status and conduct necessary checks.",
"format": {
"jwt_vc": {
"alg": [
"ES256K",
"EdDSA"
]
}
},
"input_descriptors": [
{
"id": "known-customer-credential",
"name": "Known Customer Credential",
"purpose": "Please present your Known Customer Credential for verification.",
"constraints": {
"fields": [
{
"path": [
"$.credentialSchema[*].id"
],
"filter": {
"type": "string",
"const": "https://vc.schemas.host/kcc.schema.json"
}
},
{
"path": [
"$.evidence[*].kind"
],
"filter": {
"type": "string",
"pattern": "sanction_screening"
}
},
{
"path": [
"$.credentialSubject.countryOfResidence"
],
"filter": {
"type": "string",
"const": "US"
}
},
{
"path": [
"$.issuer"
],
"filter": {
"type": "string",
"const": "did:dht:d4sgiggd3dwimo4ubki7spo45q5dazxphrizbxhcgapapcnzpouy"
}
}
]
}
}
]
}
},
"signature": "eyJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpkaHQ6ZDRzZ2lnZ2QzZHdpbW80dWJraTdzcG80NXE1ZGF6eHBocml6YnhoY2dhcGFwY256cG91eSMwIn0..CcC0pWCpZXzqvPF-2z-axvJQyHhT6-Of4lavPIrrIrJ4WM5eyKRaR7YgEORh7xMwR_pXZ_KUHnPksmSQZsm2Ag"
}
```
54 changes: 54 additions & 0 deletions site-new/docs/tbdex-sdk/pfi/creating-quotes.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
title: Creating Quotes
hide_title: true
sidebar_position: 7
---

import Shnip from "@site/src/components/Shnip";

# Creating Quotes

When you receive an `RFQ` message, you’ll want to do the following:

1. Store the `RFQ` message in your database
2. Get the `Offering` specified by `offeringId` in the `RFQ`
3. Create a `Quote` and store it in your database

## Store RFQ message

An `RFQ` is the first message of an exchange.
When a Wallet application sends your PFI an `RFQ` message, your server's `onCreateExchange()` callback parameter will be invoked.
This is where you should implement your business logic for determining the customer's exact Quote.

As a best practice, store the `RFQ` message in your [Exchanges database](/docs/tbdex/pfi/anatomy-of-a-pfi#main-server-entrypoint) so that both you and the Wallet app can access it.

## Get the Offering

After inserting the `RFQ` into your database, you can search your database for the `Offering` the `RFQ` is requesting.

RFQs contain a required `offeringId` field that you pass to your Offerings API provider’s `getOffering()` method to obtain the exact Offering.

Building on the example from the [Exchange API Provider section](/docs/tbdex/pfi/anatomy-of-a-pfi#exchange-api-provider), your code might look like this:

<Shnip languages={["JavaScript", "Kotlin"]} snippetName="pfiWriteOffering" />

## Verify Credentials

Upon receiving an `RFQ`, the tbDEX SDK will automatically [verify the submitted credentials](/docs/web5/verifiable-credentials/verify-vc#verify-verifiable-credentials) to guarantee their integrity and authenticity as well as ensure that they meet the `requiredClaims` specified in the `Offering`.

## Create a Quote

Before creating a `Quote` in response to the received `RFQ`, you can review the [protocol definition for Quotes](https://github.com/TBD54566975/tbdex/tree/main/specs/protocol#quote).
With that in mind, you can then create your quote using the `Quote.create()` method as shown below:

<Shnip languages={["JavaScript", "Kotlin"]} snippetName="pfiCreateQuote" />

With the `Quote` created, you’ll then sign it for authorization purposes and write it to your own database:

<Shnip languages={["JavaScript", "Kotlin"]} snippetName="pfiSignQuote" />

:::tip Note
If the Wallet Application supplied a `replyTo` address with their RFQ, the tbDEX SDK will send the Quote to that address.

If not, the Wallet Application will poll your PFI awaiting the Quote message to appear within the exchange.
:::
38 changes: 38 additions & 0 deletions site-new/docs/tbdex-sdk/pfi/onboarding.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
sidebar_position: 3
title: Onboarding
hide_title: true
---

import Shnip from "@site/src/components/Shnip";

# Onboarding

Before beginning development of your PFI’s code, you’ll need to create an identity to use on the network. A tbDEX network is built to be decentralized, which is why you’ll need to create your own [Decentralized Identifier](/docs/web5/decentralized-identifiers/what-are-dids) (DID) to assign to the PFI. That DID will represent the PFI, as well as serve as the signer for tbDEX messages and resources that are sent to other parties.

DIDs are associated with [DID Documents](/docs/web5/decentralized-identifiers/did_documents) which describe how to engage with your PFI.

To create a DID and identify yourself as a PFI, use the `web5/dids` package:

### Import Classes

<Shnip
languages={["JavaScript", "Kotlin"]}
snippetName="pfiOnboardingImports"
/>

### Create DID with Service Endpoint

For a DID to be recognized as a PFI, it is important to include a service endpoint in the DID document. The value for `serviceEndpoint` should be the URL to your PFI's service entry.

If you also have an existing key management system to secure your secrets, e.g., [AWS KMS](https://aws.amazon.com/kms/), [Google Cloud KMS](https://cloud.google.com/security/products/security-key-management), etc., creating a DID provides a `keyManager` interface that you can pass it through.

<Shnip
languages={["JavaScript", "Kotlin"]}
snippetName="pfiOnboardingCreateDid"
/>

:::note Notes

- `LocalKeyManager` or `InMemoryKeyManager` should only be used in non-production environments. See [Key Management Service](/docs/web5/decentralized-identifiers/key-management) for more details.
:::
24 changes: 24 additions & 0 deletions site-new/docs/tbdex-sdk/pfi/overview.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
sidebar_position: 1
---

# PFI Overview

PFIs are **Participating Financial Institutions** that offer liquidity on a tbDEX network.

PFIs make themselves known to [Wallet applications](/docs/tbdex/wallet/overview) and engage in verifying necessary information for transaction completion with [Verifiable Credential](/docs/web5/verifiable-credentials/what-are-vcs) Issuers.

For more on how PFIs fit into the overall structure of tbDEX, please [refer to the tbDEX overview](/docs/tbdex/#example-scenario).

The PFI guides are intended to provide you with what you need to begin participating on a tbDEX network.

## Recommended Path

1. [tbDEX Overview](/docs/tbdex/)
2. [Review Message Types](/docs/tbdex/message-types)
3. [Install Required SDKs](/docs/tbdex/pfi/required-sdks)
4. [Onboard as a PFI](/docs/tbdex/pfi/onboarding)
5. [Review Anatomy of a PFI](/docs/tbdex/pfi/anatomy-of-a-pfi)
6. [Create Offerings](/docs/tbdex/pfi/creating-offerings)
7. [Create Quotes](/docs/tbdex/pfi/creating-quotes)
8. [Process Orders](/docs/tbdex/pfi/processing-orders)
57 changes: 57 additions & 0 deletions site-new/docs/tbdex-sdk/pfi/processing-orders.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
title: Processing Orders
sidebar_position: 9
hide_title: true
---

import Shnip from "@site/src/components/Shnip";
import LanguageSwitchLink from "@site/src/components/LanguageSwitchLink";

# Processing Orders

After the Wallet app receives a [Quote](/docs/tbdex/pfi/creating-quotes) from your PFI, they are able to submit an Order.
This guide covers how to use tbDEX to communicate progress on Orders you receive.

## Receiving an Order

When a Wallet application places an order, your server's `onSubmitOrder()` callback parameter will be invoked.
This is where you should implement your business logic for handling these incoming orders.

As a best practice, store the `Order` message in your [Exchanges database](/docs/tbdex/pfi/anatomy-of-a-pfi#main-server-entrypoint).

## Accessing Hashed Data

The payment details for the Order were specified in the <LanguageSwitchLink text="RFQ message" links='{"JavaScript": "https://tbd54566975.github.io/tbdex-js/classes/_tbdex_protocol.Rfq.html",
"Kotlin": "https://tbd54566975.github.io/tbdex-kt/docs/tb-d-e-x%20-s-d-k%20-documentation/tbdex.sdk.protocol.models/-rfq/index.html"}'/> that was sent by the Wallet application.

Sensitive information such as payment details and claims are hashed and are accessible from the [privateData](https://github.com/TBD54566975/tbdex/tree/main/specs/protocol#privatedata-1) section of the RFQ:

<Shnip
languages={["JavaScript", "Kotlin"]}
snippetName="pfiAccessPrivateData"
/>

Using this information, you are free to use the logic of choice to fulfill the Order.

:::note
tbDEX is a messaging protocol that facilitates communication to enable transactions but does not actually provide the APIs to fulfill them.
That responsibility lies with the transacting parties.
:::

## Provide Order Status

As you deem appropriate for your customers, you can provide them with <LanguageSwitchLink text="OrderStatus messages" links='{"JavaScript": "https://tbd54566975.github.io/tbdex-js/classes/_tbdex_http_client.OrderStatus.html", "Kotlin": "https://tbd54566975.github.io/tbdex-kt/docs/tb-d-e-x%20-s-d-k%20-documentation/tbdex.sdk.protocol.models/-order-status/index.html"}'/> to keep them updated on the status of their `Order`:

<Shnip languages={["JavaScript", "Kotlin"]} snippetName="pfiOrderStatus" />

If the Wallet application supplied a `replyTo` address, the tbDEX SDK will send the `OrderStatus` message there.

You should also write the `OrderStatus` to your database and the Wallet will poll for these updates.

## Close the Order

When the `Order` has reached a terminal state (e.g. order fulfilled, order rejected, etc), you can create a `Close` message, which will be the final message of the thread:

<Shnip languages={["JavaScript", "Kotlin"]} snippetName="pfiCloseOrder" />

After writing the `Close` message to your database, the Wallet will be able to know that their transaction has closed via polling or callback.
Loading

0 comments on commit d35656e

Please sign in to comment.