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

Commit

Permalink
feat: Add fees to wallet iface (#74)
Browse files Browse the repository at this point in the history
* feat: add get onchain fees to wallet queries
* feat: add tx fees to config for usage on withdraw
* fix: graphql multi wallet query to plural
Co-authored-by: Sebastien Verreault <[email protected]>
  • Loading branch information
sebastienverreault authored Feb 23, 2022
1 parent cc9b045 commit 713685b
Show file tree
Hide file tree
Showing 9 changed files with 133 additions and 11 deletions.
11 changes: 8 additions & 3 deletions default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ rebalancing:
minOnchain: 10000000 # 0.1

fees:
BASE_FEE: 0.0005
IMMEDIATE_CONVERSION_SPREAD: 0.0005
DELAYED_CONVERSION_SPREAD: 0.0010
BASE_FEE: 0.0003
IMMEDIATE_CONVERSION_SPREAD: 0.0001
DELAYED_CONVERSION_SPREAD: 0.0002

withdrawal:
MIN_ON_CHAIN_WITHDRAWAL_AMOUNT: 0.001
MIN_ON_CHAIN_WITHDRAWAL_FEE: 0.0002
MAX_ON_CHAIN_WITHDRAWAL_FEE: 0.0004
23 changes: 22 additions & 1 deletion src/DealerRemoteWallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const IN_MEMORY_CACHE_CONFIG = {

const WALLETS = gql`
query wallets {
wallet {
wallets {
id
balance
walletCurrency
Expand Down Expand Up @@ -146,6 +146,27 @@ export class DealerRemoteWallet implements GaloyWallet {
}
}

public async getWalletOnChainTransactionFee(
address: string,
btcAmountInSats: number,
): Promise<Result<number>> {
const logger = this.logger.child({ method: "getWalletOnChainTransactionFee()" })
try {
const fee = 0
logger.debug(
{ address, btcAmountInSats, result: fee },
"{GET_ONCHAIN_FEE} query to galoy graphql api successful with {result}",
)
return { ok: true, value: fee }
} catch (error) {
logger.error(
{ error },
"{GET_ONCHAIN_FEE} query to galoy graphql api failed with {error}",
)
return { ok: false, error }
}
}

public async payOnChain(
address: string,
btcAmountInSats: number,
Expand Down
35 changes: 34 additions & 1 deletion src/DealerRemoteWalletV2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,40 @@ export class DealerRemoteWalletV2 implements GaloyWallet {
}
}

public async getWalletOnChainTransactionFee(
address: string,
btcAmountInSats: number,
): Promise<Result<number>> {
const logger = this.logger.child({ method: "getWalletOnChainTransactionFee()" })
try {
const walletsResult = await this.getWalletsBalances()
if (!walletsResult.ok) {
return walletsResult
}
const variables = {
walletId: walletsResult.value.btcWalletId,
address: address,
amount: btcAmountInSats,
}
const result = await this.client.query({
query: QUERIES.onChainTxFee,
variables: variables,
})
logger.debug(
{ query: QUERIES.onChainTxFee, variables, result },
"{query} with {variables} to galoy graphql api successful with {result}",
)
const btcAddress = result.data?.onChainTxFee?.amount ?? undefined
return { ok: true, value: btcAddress }
} catch (error) {
logger.error(
{ query: QUERIES.onChainTxFee, address, btcAmountInSats, error },
"{query} to galoy graphql api failed with {error}",
)
return { ok: false, error }
}
}

public async payOnChain(
address: string,
btcAmountInSats: number,
Expand All @@ -161,7 +195,6 @@ export class DealerRemoteWalletV2 implements GaloyWallet {
address: address,
amount: btcAmountInSats,
memo: memo,
targetConfirmations: 1,
walletId: walletsResult.value.btcWalletId,
},
}
Expand Down
23 changes: 22 additions & 1 deletion src/DealerSimulatedWallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const IN_MEMORY_CACHE_CONFIG = {

const WALLETS = gql`
query wallets {
wallet @client {
wallets @client {
id
balance
walletCurrency
Expand Down Expand Up @@ -146,6 +146,27 @@ export class DealerSimulatedWallet implements GaloyWallet {
}
}

public async getWalletOnChainTransactionFee(
address: string,
btcAmountInSats: number,
): Promise<Result<number>> {
const logger = this.logger.child({ method: "getWalletOnChainTransactionFee()" })
try {
const fee = 0
logger.debug(
{ address, btcAmountInSats, result: fee },
"{GET_ONCHAIN_FEE} query to galoy graphql api successful with {result}",
)
return { ok: true, value: fee }
} catch (error) {
logger.error(
{ error },
"{GET_ONCHAIN_FEE} query to galoy graphql api failed with {error}",
)
return { ok: false, error }
}
}

public async payOnChain(
address: string,
btcAmountInSats: number,
Expand Down
4 changes: 4 additions & 0 deletions src/GaloyWalletTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ export interface GaloyWallet {
getBtcWalletBalance(): Promise<Result<number>>

getWalletOnChainDepositAddress(): Promise<Result<string>>
getWalletOnChainTransactionFee(
address: string,
btcAmountInSats: number,
): Promise<Result<number>>

payOnChain(
address: string,
Expand Down
25 changes: 25 additions & 0 deletions src/OkexExchange.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,31 @@ export class OkexExchange extends ExchangeBase {
try {
const config = this.exchangeConfig as OkexExchangeConfiguration

try {
const currencies = await this.exchange.privateGetAssetCurrencies()
const btcCurrency = currencies?.data?.find(
(currency) => currency?.chain === "BTC-Bitcoin",
)
if (btcCurrency) {
this.logger.debug(
{ config, response: btcCurrency },
"exchange.privateGetAssetCurrencies() returned: {response}",
)
if (btcCurrency?.minWd) config.minOnChainWithdrawalAmount = btcCurrency?.minWd
if (btcCurrency?.minFee) config.minOnChainWithdrawalFee = btcCurrency?.minFee
if (btcCurrency?.maxFee) config.maxOnChainWithdrawalFee = btcCurrency?.maxFee
this.logger.debug(
{ config, response: btcCurrency },
"ExchangeConfiguration after update: {config}",
)
}
} catch (error) {
this.logger.error(
{ error },
"exchange.privateGetAssetCurrencies() failed: {error}",
)
}

const args1 = { posMode: config.positionMode }
const positionResponse = await this.exchange.privatePostAccountSetPositionMode(
args1,
Expand Down
7 changes: 7 additions & 0 deletions src/OkexExchangeConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export enum DestinationAddressType {
}

const hedgingBounds = yamlConfig.hedging
const withdrawalFees = yamlConfig.withdrawal

export class OkexExchangeConfiguration implements ExchangeConfiguration {
exchangeId: SupportedExchange
Expand All @@ -53,6 +54,9 @@ export class OkexExchangeConfiguration implements ExchangeConfiguration {
positionMode: PositionMode
marginMode: MarginMode
leverage: number
minOnChainWithdrawalAmount: number
minOnChainWithdrawalFee: number
maxOnChainWithdrawalFee: number

constructor() {
this.exchangeId = SupportedExchange.OKEX5
Expand All @@ -61,6 +65,9 @@ export class OkexExchangeConfiguration implements ExchangeConfiguration {
this.positionMode = PositionMode.Net
this.marginMode = MarginMode.Cross
this.leverage = hedgingBounds.HIGH_BOUND_LEVERAGE
this.minOnChainWithdrawalAmount = withdrawalFees.MIN_ON_CHAIN_WITHDRAWAL_AMOUNT
this.minOnChainWithdrawalFee = withdrawalFees.MIN_ON_CHAIN_WITHDRAWAL_FEE
this.maxOnChainWithdrawalFee = withdrawalFees.MAX_ON_CHAIN_WITHDRAWAL_FEE

if (process.env["NETWORK"] === "testnet") {
this.headers["x-simulated-trading"] = 1
Expand Down
7 changes: 5 additions & 2 deletions src/OkexPerpetualSwapStrategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -432,13 +432,16 @@ export class OkexPerpetualSwapStrategy implements HedgingStrategy {
await database.internalTransfers.insert(intTransferRecord)

// then initiate the withdrawal which by default uses the funding account
const config = this.exchangeConfig as OkexExchangeConfiguration
const averageFee =
(config.minOnChainWithdrawalFee + config.maxOnChainWithdrawalFee) / 2
const withdrawArgs = {
currency: TradeCurrency.BTC,
quantity: transferSizeInBtc,
address: withdrawOnChainAddress,
params: {
fee: "0", // probably need to fetch from galoy wallet api
dest: DestinationAddressType.OKEx, // TODO: fix this to external or get from api also
fee: averageFee,
dest: DestinationAddressType.External,
pwd: this.exchange.fundingPassword,
},
}
Expand Down
9 changes: 6 additions & 3 deletions src/servers/graphql/WalletGraphqlServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,14 @@ export async function startApolloServer() {
BTC
}
# An amount (of a currency) that can be negative (i.g. in a transaction)
scalar SignedAmount
# ?: Account? Multiple wallets
type Wallet {
id: ID!
walletCurrency: Currency!
balance: Int!
balance: SignedAmount!
}
type LastOnChainAddress {
Expand All @@ -68,7 +71,7 @@ export async function startApolloServer() {
# clients can execute, along with the return type for each. In this
# case, the "books" query returns an array of zero or more Books (defined above).
type Query {
wallet: [Wallet]
wallets: [Wallet]
getLastOnChainAddress: LastOnChainAddress
}
Expand Down Expand Up @@ -103,7 +106,7 @@ export async function startApolloServer() {

const resolvers = {
Query: {
wallet: async (_, __, { logger }) => {
wallets: async (_, __, { logger }) => {
const result = await database.graphql.getWallet()
logger.debug({ result }, "wallet: database.getWallet() returned: {result}")
if (result.ok && result.value && result.value.jsonData) {
Expand Down

0 comments on commit 713685b

Please sign in to comment.