Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Support for Off Chain Assets #1831

Closed
wants to merge 29 commits into from

Conversation

ademidun
Copy link

@ademidun ademidun commented Jul 18, 2022

This PR proposes an API for off-chain asset providers such as centralized exchanges and banks to allow users to transfer off-chain assets on-chain directly from their crypto wallet.

Why

  • Most of the interesting applications of crypto such as buying an NFT, verifying an account or using a DEX, require you to have a crypto wallet with crypto tokens.
  • This often requires you to load crypto in your wallet using an off-chain account such as a centralized exchange or a bank and bring it on-chain to your wallet
  • Current methods require you to go to a separate app, do authentication, buy crypto, copy the address to your clipboard, withdraw crypto, and do authentication again. This adds confusion and friction to using decentralized applications and using crypto wallets.
  • Integrating those steps directly into the crypto wallet, makes things easier.

Note: This PR is still in a draft state. Before merging, I will clean up the code, ( i.e. remove console.log, remove hardcoded variables etc.). Right now, I'm looking for feedback on the high-level idea, strategy, additional considerations, and so forth.

Video Demo

tally-demo.mp4

Provider Setup

An OffChainProvider represents a financial services provider that stores off-chain assets such as fiat currencies and crypto in their centralized databases. This can be a centralized exchange such as Wealthsimple, Coinbase, Binance or banks that allow users to convert their fiat assets into crypto.

Any exchange that allows users to buy cryptocurrencies and withdraw them to outside wallets can have their off-chain assets integrated into the wallet by implementing 3 endpoints.

  1. Login
  2. Get assets
  3. Request a transfer

Provider Implementation

The implementation details for each endpoint are determined and executed by each provider. The browser wallet simply sends requests to the provided URL based on a UI action (you may think of it like a webhook).

For example, on a login request: Given a username and password to /api/v1/login the provider might choose to respond immediately with the user credentials or request further authentication using a challengeMessage.

Similarly with api/v1/transfer, the provider determines how to execute the requested transfer. The wallet's is simply a messenger for for passing information between the client and the provider.

Login

The client (Tally) sends a GET request to the OffChainProvider.apiUrl/api/v1/login with a usernameandpassword` credential.

The server can then reply with a userId and tokenId.

The userId uniquely identifies the user that made the request and the tokenId is a JWT token that is added to the header in subsequent requests for authentication.

Response

{
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
"userId": "123abc"
}

Get Assets

The client (Tally) sends a GET request to OffChainProvider.apiUrl/api/v1/assets with a userId in the request and token in the header. The server responds with a list of assets that the user has with the provider. These assets may be fiat or cryptocurrencies.

{
    "assets": [
        {
            "accountId": "abc123",
            "currencySymbol": "CAD",
            "amount": 100,
            "label": "Alice's Chequing Account"
        },
        {
            "accountId": "abc123",
            "currencySymbol": "ETH",
            "amount": 0.033,
            "label": "Alice's Crypto Account"
        }
    ]
}

Request Transfer

The client (Tally) sends a POST request to OffChainProvider.apiUrl/api/v1/transfer that requests the provider to transfer a user's asset from their off-chain account to an on-chain asset and place it as an address in their Tally account. The implementation details of how this money will be moved, such as the market price and the transaction fee will be handled by the provider.

This API simply makes the request, displays the response to the client and queries the blockchain to get the status of the response.

Request:

{
  "accountId": "123456",
  "sourceCurrencySymbol": "CAD",
  "destinationCurrencySymbol": "ETH",
  "sourceAmount": 100,
  "destinationAddress": "0x123abc"
}

Response:

{
        "transactionHash": "",
        "chainId": "",
        "requestId": "",
}

Appendix

Multi-Factor Authenticated Requests

On each request made, the provider may request additional authentication.

{
  "requestId": "unique-id-generated-by-server",
  "challengeMessage": "Enter the code sent to your email",
  "challengeType": "6_digit_code",
}

The client responds with:

{
  "requestId": "unique-id-generated-by-server",
  "challengeResponse": "123456",
}

After which the client can return the desired response or request another challenge to be completed.

Future Endpoints

We recommend keeping the initial endpoint simple to start. However, there are many possibilities for this to be extended to add more features. We present them here since, if we know what we plan to build. It can influence our current design decisions.

Estimate Transfer

GET /api/v1/transfer/estimate

Request the provider to give an estimate for the results of a transaction.

In this example, the user requests 100 CAD to be converted to ETH and sent to address 0x123abc.

The response provides an estimate of how much ETH that address will receive.

Request

{
  "accountId": "123456",
  "sourceCurrencySymbol": "CAD",
  "destinationCurrencySymbol": "ETH",
  "sourceAmount": 100,
  "destinationAddress": "0x123abc"
}

Response

{
  "sourceAmount": 100,
  "destinationAmount": 0.050
}

The provider may also choose to include additional details such as the exchange rate used, the network fee (gas fees), the provider fee.

TODO: Should exchange rate be in terms of source or destination currency.

{
  "sourceAmount": 100,
  "destinationAmount": 0.050,
  "exchangeRate": 1778.5,
  "networkFee": 0.00000000050,
  "providerFee": 2,
  "providerFeeCurrency": "CAD"
}

@Shadowfiend
Copy link
Contributor

This feels like something we would treat similarly to a read-only account. Obviously it wouldn't have an explicit address which would require some rethinking, but that feels like the correct abstraction no?

@ademidun
Copy link
Author

This feels like something we would treat similarly to a read-only account. Obviously it wouldn't have an explicit address which would require some rethinking, but that feels like the correct abstraction no?

Yes, you are close. However, note that this PR is still in draft mode. We also plan to add an /authenticate and /transfer endpoint that will be write requests. However, because it is off-chain, the provider would be responsible for choosing how they want to implement the requests they receive from Tally.

@ademidun ademidun changed the title Add Support for Off Chain Balances Add Support for Off Chain Assets Jul 20, 2022
@ademidun ademidun marked this pull request as ready for review July 22, 2022 19:23
@ademidun ademidun marked this pull request as draft July 22, 2022 19:32
@Shadowfiend
Copy link
Contributor

Hey folks! It's not clear to me whether this work is under active dev now; regardless, we're still not set up on the community side to clearly prioritize new integrations like this one with respect to other aspects of the roadmap, particularly when they have deeper architectural and design implications. We've been focused elsewhere since this PR was opened, and we don't have a clear roadmap for returning to that aspect of prioritization before Q4 at the earliest.

As such, for clarity in the PR list, I'm going to close this PR. Note that this does not mean zero interest in the integration, but rather that we should keep things at the community level (chat.taho.xyz, gov.taho.xyz) until we land on a good way to coordinate the team's time and work with the community's preferences. Again, we don't expect a lot of movement on that front until Q4 at the earliest.

Hey folks, apologies for the long silence. The short version here is that we're still not set up on the community side to clearly prioritize new integrations like this one with respect to other aspects of the roadmap, particularly when they have deeper architectural and design implications. We've been focused elsewhere since this PR was opened, and we don't have a clear roadmap for returning to that aspect of prioritization before Q4 at the earliest.

As such, for clarity in the PR list, I'm going to close this PR. Note that this does not mean zero interest in the integration, but rather that we should keep things at the community level (chat.taho.xyz, gov.taho.xyz) until we land on a good way to coordinate the team's time and work with the community's preferences. Again, we don't expect a lot of movement on that front until Q4 at the earliest.

Thanks again for bearing with us here, and I hope we can turn our attention to getting the processes ironed out here before too too long.

@Shadowfiend Shadowfiend closed this May 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants