Skip to content
This repository has been archived by the owner on Dec 7, 2023. It is now read-only.

Commit

Permalink
feat: Integrate with galoy backend (#71)
Browse files Browse the repository at this point in the history
* feat: upgrade to galoy graphql v2 wallet format
* test: upgrade graphql tests to new v2 format
* fix: test assumes +balances, but -bals still in use
* refactor: rename methods to diff usd/btc wallets
* fix: add missing migration step for wallet
Co-authored-by: Sebastien Verreault <[email protected]>
  • Loading branch information
sebastienverreault authored Feb 23, 2022
1 parent 19b2886 commit 92d289d
Show file tree
Hide file tree
Showing 15 changed files with 935 additions and 140 deletions.
3 changes: 2 additions & 1 deletion migrations/20210929053822631_init-wallet.sql
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ VALUES
"id": "dealer",
"balance": {
"currency": "USD",
"amount": -100
"amount": -100,
"quantityInBtc": -0.00265463
}
}
]'::json
Expand Down
162 changes: 162 additions & 0 deletions migrations/20220222082935368_wallet-v2.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
-- Up Migration
DO $$
DECLARE btcBalance FLOAT := 0;
DECLARE usdBalance FLOAT := 0;
DECLARE lastId INTEGER := 0;
DECLARE result TEXT := '';
BEGIN
SELECT
(json_data -> 0 ->> 'balance')::json -> 'quantityInBtc' as btcBalance
FROM dealer.wallet
WHERE json_data::json -> 0 ->> 'id' = 'dealer'
INTO btcBalance;
raise notice 'btcBalance = %', btcBalance;

SELECT
(json_data -> 0 ->> 'balance')::json -> 'amount' as usdBalance
FROM dealer.wallet
WHERE json_data::json -> 0 ->> 'id' = 'dealer'
into usdBalance;
raise notice 'usdBalance = %', usdBalance;


INSERT INTO dealer.wallet
(json_data)
VALUES
('[
{
"id": "BTCWallet",
"balance": 0,
"walletCurrency": "BTC"
},
{
"id": "USDWallet",
"balance": 0,
"walletCurrency": "USD"
}
]'::json
)
RETURNING id
INTO lastId;

SELECT json_data::jsonb
from dealer.wallet
WHERE id = lastId
INTO result;
raise notice 'new row: %', result;

UPDATE dealer.wallet
SET json_data = jsonb_set(json_data::jsonb, '{0,balance}', btcBalance::text::jsonb, false)
WHERE id = lastId;

SELECT json_data
from dealer.wallet
WHERE id = lastId
INTO result;
raise notice 'new row: %', result;

UPDATE dealer.wallet
SET json_data = jsonb_set(json_data::jsonb, '{1,balance}', usdBalance::text::jsonb, false)
WHERE id = lastId;

SELECT json_data
from dealer.wallet
WHERE id = lastId
INTO result;
raise notice 'new row: %', result;

SELECT json_data
from dealer.wallet
INTO result;
raise notice 'before delete: %', result;

DELETE
FROM dealer.wallet
WHERE json_data::json -> 0 ->> 'id' = 'dealer';

SELECT json_data
from dealer.wallet
INTO result;
raise notice 'after delete: %', result;
END $$;

-- Down Migration
DO $$
DECLARE btcBalance FLOAT := 0;
DECLARE usdBalance FLOAT := 0;
DECLARE lastId INTEGER := 0;
DECLARE result TEXT := '';
BEGIN
SELECT
json_data -> 0 ->> 'balance' as btcBalance
FROM dealer.wallet
WHERE json_data::json -> 0 ->> 'id' = 'BTCWallet'
INTO btcBalance;
raise notice 'btcBalance = %', btcBalance;

SELECT
json_data -> 1 ->> 'balance' as usdBalance
FROM dealer.wallet
WHERE json_data::json -> 1 ->> 'id' = 'USDWallet'
into usdBalance;
raise notice 'usdBalance = %', usdBalance;


INSERT INTO dealer.wallet
(json_data)
VALUES
('[
{
"id": "dealer",
"balance": {
"currency": "USD",
"amount": 0,
"quantityInBtc": 0
}
}
]'::json
)
RETURNING id
INTO lastId;

SELECT json_data::jsonb
from dealer.wallet
WHERE id = lastId
INTO result;
raise notice 'new row: %', result;

UPDATE dealer.wallet
SET json_data = jsonb_set(json_data::jsonb, '{0,balance,quantityInBtc}', btcBalance::text::jsonb, false)
WHERE id = lastId;

SELECT json_data
from dealer.wallet
WHERE id = lastId
INTO result;
raise notice 'new row: %', result;

UPDATE dealer.wallet
SET json_data = jsonb_set(json_data::jsonb, '{0,balance,amount}', usdBalance::text::jsonb, false)
WHERE id = lastId;

SELECT json_data
from dealer.wallet
WHERE id = lastId
INTO result;
raise notice 'new row: %', result;

SELECT json_data
from dealer.wallet
INTO result;
raise notice 'before delete: %', result;

DELETE
FROM dealer.wallet
WHERE json_data::json -> 0 ->> 'id' = 'BTCWallet';

SELECT json_data
from dealer.wallet
INTO result;
raise notice 'after delete: %', result;
END $$;

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@
"migrate-ts": "node-pg-migrate --create-schema true --schema dealer --migration-filename-format utc --migration-file-language ts --tsconfig ./tsconfig.json "
},
"dependencies": {
"@apollo/client": "^3.3.21",
"@apollo/client": "^3.5.8",
"@galoymoney/client": "^0.1.3",
"@grpc/grpc-js": "^1.5.3",
"@opentelemetry/instrumentation-grpc": "^0.27.0",
"@profusion/apollo-validation-directives": "^2.1.5",
Expand Down
8 changes: 4 additions & 4 deletions src/Dealer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,10 @@ export class Dealer {
return { ok: false, error: priceResult.error }
}
const btcPriceInUsd = priceResult.value
const usdLiabilityResult = await this.wallet.getWalletUsdBalance()
const usdLiabilityResult = await this.wallet.getUsdWalletBalance()
logger.debug(
{ usdLiabilityResult },
"wallet.getWalletUsdBalance() returned: {usdLiabilityResult}",
"wallet.getUsdWalletBalance() returned: {usdLiabilityResult}",
)

// If liability is negative, treat as an asset and do not hedge
Expand Down Expand Up @@ -423,15 +423,15 @@ export class Dealer {
}

public async getLiabilityInUsd(): Promise<number> {
const result = await this.wallet.getWalletUsdBalance()
const result = await this.wallet.getUsdWalletBalance()
if (!result.ok) {
return NaN
}
return result.value
}

public async getLiabilityInBtc(): Promise<number> {
const result = await this.wallet.getWalletBtcBalance()
const result = await this.wallet.getBtcWalletBalance()
if (!result.ok) {
return NaN
}
Expand Down
84 changes: 50 additions & 34 deletions src/DealerRemoteWallet.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Result } from "./Result"
import { GaloyWallet } from "./GaloyWalletTypes"
import { GaloyWallet, WalletsBalances } from "./GaloyWalletTypes"
import {
ApolloClient,
NormalizedCacheObject,
Expand All @@ -14,12 +14,20 @@ const IN_MEMORY_CACHE_CONFIG = {
typePolicies: {
Query: {
fields: {
// wallet: {
// wallets: {
// read() {
// return {
// id: "dealer",
// balance: { currency: "USD", amount: -100 },
// }
// return [
// {
// id: "USDWallet",
// balance: 100,
// walletCurrency: "USD",
// },
// {
// id: "BTCWallet",
// balance: 1_000_000, // 100 USD @ 10k USD/BTC
// walletCurrency: "BTC",
// },
// ]
// },
// },
// getLastOnChainAddress: {
Expand All @@ -34,15 +42,12 @@ const IN_MEMORY_CACHE_CONFIG = {
},
}

const WALLET = gql`
query wallet {
const WALLETS = gql`
query wallets {
wallet {
id
balance {
currency
amount
quantityInBtc
}
balance
walletCurrency
}
}
`
Expand Down Expand Up @@ -76,40 +81,51 @@ export class DealerRemoteWallet implements GaloyWallet {
this.logger = logger.child({ class: DealerRemoteWallet.name })
}

public async getWalletUsdBalance(): Promise<Result<number>> {
const logger = this.logger.child({ method: "getWalletUsdBalance()" })
public async getWalletsBalances(): Promise<Result<WalletsBalances>> {
const logger = this.logger.child({ method: "getWalletsBalances()" })
try {
const result = await this.client.query({ query: WALLET })
const result = await this.client.query({ query: WALLETS })
logger.debug(
{ WALLET, result },
{ WALLET: WALLETS, result },
"{WALLET} query to galoy graphql api successful with {result}",
)
return { ok: true, value: result.data.wallet[0].balance.amount }

const btcWallet = result.data.wallets?.find((wallet) => wallet?.id === "BTCWallet")
const btcWalletId = btcWallet?.id
const btcWalletBalance = btcWallet?.balance ?? NaN

const usdWallet = result.data.wallets?.find((wallet) => wallet?.id === "USDWallet")
const usdWalletId = usdWallet?.id
// TODO: figure out if the balance will always be positive or not in that new implementation
const usdWalletBalance = -usdWallet?.balance ?? NaN

return {
ok: true,
value: { btcWalletId, btcWalletBalance, usdWalletId, usdWalletBalance },
}
} catch (error) {
logger.error(
{ WALLET, error },
{ WALLET: WALLETS, error },
"{WALLET} query to galoy graphql api failed with {error}",
)
return { ok: false, error }
}
}

public async getWalletBtcBalance(): Promise<Result<number>> {
const logger = this.logger.child({ method: "getWalletBtcBalance()" })
try {
const result = await this.client.query({ query: WALLET })
logger.debug(
{ WALLET, result },
"{WALLET} query to galoy graphql api successful with {result}",
)
return { ok: true, value: result.data.wallet[0].balance.quantityInBtc }
} catch (error) {
logger.error(
{ WALLET, error },
"{WALLET} query to galoy graphql api failed with {error}",
)
return { ok: false, error }
public async getUsdWalletBalance(): Promise<Result<number>> {
const result = await this.getWalletsBalances()
if (result.ok) {
return { ok: true, value: result.value.usdWalletBalance }
}
return result
}

public async getBtcWalletBalance(): Promise<Result<number>> {
const result = await this.getWalletsBalances()
if (result.ok) {
return { ok: true, value: result.value.btcWalletBalance }
}
return result
}

public async getWalletOnChainDepositAddress(): Promise<Result<string>> {
Expand Down
Loading

0 comments on commit 92d289d

Please sign in to comment.