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

feat: add NIM - CRC swap #502

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
34 changes: 30 additions & 4 deletions client/src/PublicRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,14 @@ export type SepaSettlementInstruction = {
},
};

export type SettlementInstruction = MockSettlementInstruction | SepaSettlementInstruction;
export type SinpeMovilSettlementInstruction = {
type: 'sinpemovil',
contractId: string,
phoneNumber: string,
};

export type SettlementInstruction =
MockSettlementInstruction | SepaSettlementInstruction | SinpeMovilSettlementInstruction;

export type SignSwapRequestLayout = 'standard' | 'slider';

Expand Down Expand Up @@ -299,6 +306,13 @@ export type SignSwapRequestCommon = SimpleRequest & {
// bankLogoUrl?: string,
// bankColor?: string,
}
) | (
{type: 'CRC'}
& {
amount: number,
fee: number,
recipientLabel?: string,
sisou marked this conversation as resolved.
Show resolved Hide resolved
}
),
redeem: (
{type: 'NIM'}
Expand Down Expand Up @@ -345,6 +359,17 @@ export type SignSwapRequestCommon = SimpleRequest & {
// bankLogoUrl?: string,
// bankColor?: string,
}
) | (
{ type: 'CRC' }
& {
keyPath: string,
// A SettlementInstruction contains a `type`, so cannot be in the
// root of the object (it conflicts with the 'CRC' type).
settlement: Omit<SettlementInstruction, 'contractId'>,
amount: number,
fee: number,
recipientLabel?: string,
}
),

// Data needed for display
Expand Down Expand Up @@ -394,7 +419,7 @@ export type SignSwapRequestSlider = SignSwapRequestCommon & {
export type SignSwapRequest = SignSwapRequestStandard | SignSwapRequestSlider;

export type SignSwapResult = SimpleResult & {
eurPubKey?: string,
fiatPubKey?: string,
tmpCookieEncryptionKey?: Uint8Array;
};

Expand All @@ -411,7 +436,7 @@ export type SignSwapTransactionsRequest = {
type: 'USDC_MATIC',
htlcData: string,
} | {
type: 'EUR',
type: 'EUR' | 'CRC',
hash: string,
timeout: number,
htlcId: string,
Expand All @@ -431,7 +456,7 @@ export type SignSwapTransactionsRequest = {
timeout: number,
htlcId: string,
} | {
type: 'EUR',
type: 'EUR' | 'CRC',
hash: string,
timeout: number,
htlcId: string,
Expand Down Expand Up @@ -531,6 +556,7 @@ export type SignSwapTransactionsResult = {
btc?: SignedBitcoinTransaction,
usdc?: SignedPolygonTransaction,
eur?: string, // When funding EUR: empty string, when redeeming EUR: JWS of the settlement instructions
crc?: string, // When funding CRC: empty string, when redeeming CRC: JWS of the settlement instructions
refundTx?: string,
};

Expand Down
4 changes: 4 additions & 0 deletions src/common.css
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,10 @@ body.loading .page:target .page-footer > .loading-spinner {
content: "EUR";
}

.crc-symbol::before {
content: "CRC";
}

.address {
font-family: "Fira Mono", "Andale Mono", monospace;
font-size: 1.625rem;
Expand Down
2 changes: 1 addition & 1 deletion src/components/BalanceDistributionBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
/* global CryptoUtils */

/** @typedef {{address: string, balance: number, active: boolean, newBalance: number}} Segment */
/** @typedef {'NIM' | 'BTC' | 'USDC_MATIC' | 'EUR'} Asset */
/** @typedef {'NIM' | 'BTC' | 'USDC_MATIC' | 'EUR' | 'CRC'} Asset */

class BalanceDistributionBar { // eslint-disable-line no-unused-vars
/**
Expand Down
17 changes: 10 additions & 7 deletions src/components/SwapFeesTooltip.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,22 +75,25 @@ class SwapFeesTooltip { // eslint-disable-line no-unused-vars
}

// Show OASIS fees next
if (fundTx.type === 'EUR' || redeemTx.type === 'EUR') {
const myFee = fundTx.type === 'EUR'
if (fundTx.type === 'EUR' || fundTx.type === 'CRC' || redeemTx.type === 'EUR' || redeemTx.type === 'CRC') {
const myFee = fundTx.type === 'EUR' || fundTx.type === 'CRC'
? fundTx.fee
: redeemTx.type === 'EUR'
: redeemTx.type === 'EUR' || redeemTx.type === 'CRC'
? redeemTx.fee
: 0;

const theirFee = fundTx.type === 'EUR' ? fundFees.processing : redeemFees.processing;
const theirFee = fundTx.type === 'EUR' || fundTx.type === 'CRC'
? fundFees.processing : redeemFees.processing;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
? fundFees.processing : redeemFees.processing;
? fundFees.processing
: redeemFees.processing;


const fiatRate = fundTx.type === 'EUR' ? fundingFiatRate : redeemingFiatRate;
const fiatFee = CryptoUtils.unitsToCoins('EUR', myFee + theirFee) * fiatRate;
const fiatRate = fundTx.type === 'EUR' || fundTx.type === 'CRC' ? fundingFiatRate : redeemingFiatRate;
const fiatSwapAsset = (fundTx.type === 'EUR' || fundTx.type === 'CRC' ? fundTx.type : redeemTx.type);
const fiatFee = CryptoUtils.unitsToCoins(fiatSwapAsset, myFee + theirFee) * fiatRate;

const rows = this._createOasisLine(
fiatFee,
fiatCurrency,
(myFee + theirFee) / (fundTx.type === 'EUR' ? exchangeFromAmount : exchangeToAmount),
(myFee + theirFee) / (fundTx.type === 'EUR' || fundTx.type === 'CRC'
? exchangeFromAmount : exchangeToAmount),
onmax marked this conversation as resolved.
Show resolved Hide resolved
);
this.$tooltip.appendChild(rows[0]);
this.$tooltip.appendChild(rows[1]);
Expand Down
1 change: 1 addition & 0 deletions src/lib/NumberFormatting.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ class NumberFormatting { // eslint-disable-line no-unused-vars
case 'eur':
case 'chf':
return 'de';
case 'crc':
case 'gbp':
case 'usd':
return 'en';
Expand Down
3 changes: 3 additions & 0 deletions src/lib/crc/CrcConstants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const CrcConstants = { // eslint-disable-line no-unused-vars
CENTS_PER_COIN: 100,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Historically, CRC did in fact have cents but those are not in circulation anymore. Are the amounts in request types in CRC cents or CRC? Until seeing this line, I assumed CRC, but in any case, a comment should be added in PublicRequest to clarify this.

Are fractional CRC amounts also displayed in the UI? In that case, I don't think we should do so, except for exchange rates.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When we added the wallet exchange logic, all Oasis fiat was in EUR. Now the wallet uses multiple / 100 conversions from cents to coins. See here for an example.

To keep things simple in the Wallet PR, I used 2 decimal places for the CRC, which Jeff confirmed is valid, though less common. This gives us more precision and is still a correct format while keeping the PR as simple as possible without breaking changes for EUR swaps.

Let me know your thoughts on this trade-off.

};
19 changes: 19 additions & 0 deletions src/lib/crc/CrcUtils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/* global CrcConstants */

class CrcUtils { // eslint-disable-line no-unused-vars
/**
* @param {number} coins CRC amount in decimal
* @returns {number} Number of CRC cents
*/
static coinsToCents(coins) {
return Math.round(coins * CrcConstants.CENTS_PER_COIN);
}

/**
* @param {number} cents Number of CRC cents
* @returns {number} CRC count in decimal
*/
static centsToCoins(cents) {
return cents / CrcConstants.CENTS_PER_COIN;
}
}
Comment on lines +1 to +19
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think, these should be combined with EuroUtils into FiatUtils, in a similar fashion as the CryptoUtils, which are also not individual utils for each crypto asset, or if they are, they provide more utilities specific to that crypto.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already have all the assets under CryptoUtils (both fiat and crypto). Maybe the CryptoUtils name is not the best, but renaming the class should be another PR?

13 changes: 9 additions & 4 deletions src/lib/swap/CryptoUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
/* global PolygonUtils */
/* global EuroConstants */
/* global EuroUtils */
/* global CrcConstants */
/* global CrcUtils */

class CryptoUtils { // eslint-disable-line no-unused-vars
/**
* @param {'NIM' | 'BTC' | 'USDC_MATIC' | 'EUR'} asset
* @param {'NIM' | 'BTC' | 'USDC_MATIC' | 'EUR' | 'CRC'} asset
* @param {number} units
* @returns {number}
*/
Expand All @@ -18,12 +20,13 @@ class CryptoUtils { // eslint-disable-line no-unused-vars
case 'BTC': return BitcoinUtils.satoshisToCoins(units);
case 'USDC_MATIC': return PolygonUtils.unitsToCoins(units);
case 'EUR': return EuroUtils.centsToCoins(units);
case 'CRC': return CrcUtils.centsToCoins(units);
default: throw new Error(`Invalid asset ${asset}`);
}
}

/**
* @param {'NIM' | 'BTC' | 'USDC_MATIC' | 'EUR'} asset
* @param {'NIM' | 'BTC' | 'USDC_MATIC' | 'EUR' | 'CRC'} asset
* @returns {number}
*/
static assetDecimals(asset) {
Expand All @@ -32,20 +35,22 @@ class CryptoUtils { // eslint-disable-line no-unused-vars
case 'BTC': return Math.log10(BitcoinConstants.SATOSHIS_PER_COIN);
case 'USDC_MATIC': return Math.log10(PolygonConstants.UNITS_PER_COIN);
case 'EUR': return Math.log10(EuroConstants.CENTS_PER_COIN);
case 'CRC': return Math.log10(CrcConstants.CENTS_PER_COIN);
default: throw new Error(`Invalid asset ${asset}`);
}
}

/**
* @param {'NIM' | 'BTC' | 'USDC_MATIC' | 'EUR'} asset
* @returns {'nim' | 'btc' | 'usdc' | 'eur'}
* @param {'NIM' | 'BTC' | 'USDC_MATIC' | 'EUR' | 'CRC'} asset
* @returns {'nim' | 'btc' | 'usdc' | 'eur' | 'crc'}
*/
static assetToCurrency(asset) {
switch (asset) {
case 'NIM': return 'nim';
case 'BTC': return 'btc';
case 'USDC_MATIC': return 'usdc';
case 'EUR': return 'eur';
case 'CRC': return 'crc';
default: throw new Error(`Invalid asset ${asset}`);
}
}
Expand Down
4 changes: 3 additions & 1 deletion src/request/sign-swap/SignSwap.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
.nim-symbol,
.btc-symbol,
.usdc-symbol,
.eur-symbol {
.eur-symbol,
.crc-symbol {
margin-left: 0.25em;
}

Expand Down Expand Up @@ -101,6 +102,7 @@
}

.layout-standard .account.eur .identicon,
.layout-standard .account.crc .identicon,
.layout-standard .account.btc .identicon {
padding: .25rem;
}
Expand Down
Loading
Loading