Merge pull request #38 from exstake/remove-currency-model

remove currency model and all references
This commit is contained in:
João Geonizeli
2021-08-28 01:31:23 -03:00
committed by GitHub
74 changed files with 665 additions and 1561 deletions

View File

@@ -1,8 +0,0 @@
# frozen_string_literal: true
module Admin
class CurrenciesController < Admin::ApplicationController
def valid_action?(name, resource = resource_class)
["new", "edit", "destroy"].exclude?(name.to_s) && super
end
end
end

View File

@@ -10,7 +10,6 @@ class BalanceDashboard < Administrate::BaseDashboard
# on pages throughout the dashboard. # on pages throughout the dashboard.
ATTRIBUTE_TYPES = { ATTRIBUTE_TYPES = {
user: Field::BelongsTo, user: Field::BelongsTo,
currency: Field::BelongsTo,
id: Field::Number, id: Field::Number,
amount: Field::String.with_options(searchable: false), amount: Field::String.with_options(searchable: false),
created_at: Field::DateTime, created_at: Field::DateTime,
@@ -22,16 +21,16 @@ class BalanceDashboard < Administrate::BaseDashboard
# #
# By default, it's limited to four items to reduce clutter on index pages. # By default, it's limited to four items to reduce clutter on index pages.
# Feel free to add, remove, or rearrange items. # Feel free to add, remove, or rearrange items.
COLLECTION_ATTRIBUTES = [:user, :currency, :id, :amount].freeze COLLECTION_ATTRIBUTES = [:user, :id, :amount].freeze
# SHOW_PAGE_ATTRIBUTES # SHOW_PAGE_ATTRIBUTES
# an array of attributes that will be displayed on the model's show page. # an array of attributes that will be displayed on the model's show page.
SHOW_PAGE_ATTRIBUTES = [:user, :currency, :id, :amount, :created_at, :updated_at].freeze SHOW_PAGE_ATTRIBUTES = [:user, :id, :amount, :created_at, :updated_at].freeze
# FORM_ATTRIBUTES # FORM_ATTRIBUTES
# an array of attributes that will be displayed # an array of attributes that will be displayed
# on the model's form (`new` and `edit`) pages. # on the model's form (`new` and `edit`) pages.
FORM_ATTRIBUTES = [:user, :currency, :amount].freeze FORM_ATTRIBUTES = [:user, :amount].freeze
# COLLECTION_FILTERS # COLLECTION_FILTERS
# a hash that defines filters that can be used while searching via the search # a hash that defines filters that can be used while searching via the search

View File

@@ -10,7 +10,6 @@ class BuyCryptoOrderDashboard < Administrate::BaseDashboard
# on pages throughout the dashboard. # on pages throughout the dashboard.
ATTRIBUTE_TYPES = { ATTRIBUTE_TYPES = {
user: Field::BelongsTo, user: Field::BelongsTo,
currency: Field::BelongsTo,
id: Field::Number, id: Field::Number,
status: Field::Enumerize, status: Field::Enumerize,
paid_amount_cents: Field::Number, paid_amount_cents: Field::Number,
@@ -24,17 +23,16 @@ class BuyCryptoOrderDashboard < Administrate::BaseDashboard
# #
# By default, it's limited to four items to reduce clutter on index pages. # By default, it's limited to four items to reduce clutter on index pages.
# Feel free to add, remove, or rearrange items. # Feel free to add, remove, or rearrange items.
COLLECTION_ATTRIBUTES = [:user, :currency, :id, :status].freeze COLLECTION_ATTRIBUTES = [:user, :id, :status].freeze
# SHOW_PAGE_ATTRIBUTES # SHOW_PAGE_ATTRIBUTES
# an array of attributes that will be displayed on the model's show page. # an array of attributes that will be displayed on the model's show page.
SHOW_PAGE_ATTRIBUTES = [:user, :currency, :id, :status, :paid_amount_cents, :received_amount, :created_at, SHOW_PAGE_ATTRIBUTES = [:user, :id, :status, :paid_amount_cents, :received_amount, :created_at, :updated_at].freeze
:updated_at,].freeze
# FORM_ATTRIBUTES # FORM_ATTRIBUTES
# an array of attributes that will be displayed # an array of attributes that will be displayed
# on the model's form (`new` and `edit`) pages. # on the model's form (`new` and `edit`) pages.
FORM_ATTRIBUTES = [:user, :currency, :status, :paid_amount_cents, :received_amount].freeze FORM_ATTRIBUTES = [:user, :status, :paid_amount_cents, :received_amount].freeze
# COLLECTION_FILTERS # COLLECTION_FILTERS
# a hash that defines filters that can be used while searching via the search # a hash that defines filters that can be used while searching via the search

View File

@@ -1,52 +0,0 @@
# frozen_string_literal: true
require "administrate/base_dashboard"
class CurrencyDashboard < Administrate::BaseDashboard
# ATTRIBUTE_TYPES
# a hash that describes the type of each of the model's fields.
#
# Each different type represents an Administrate::Field object,
# which determines how the attribute is displayed
# on pages throughout the dashboard.
ATTRIBUTE_TYPES = {
id: Field::Number,
name: Field::String,
created_at: Field::DateTime,
updated_at: Field::DateTime,
}.freeze
# COLLECTION_ATTRIBUTES
# an array of attributes that will be displayed on the model's index page.
#
# By default, it's limited to four items to reduce clutter on index pages.
# Feel free to add, remove, or rearrange items.
COLLECTION_ATTRIBUTES = [:id, :name, :created_at, :updated_at].freeze
# SHOW_PAGE_ATTRIBUTES
# an array of attributes that will be displayed on the model's show page.
SHOW_PAGE_ATTRIBUTES = [:id, :name, :created_at, :updated_at].freeze
# FORM_ATTRIBUTES
# an array of attributes that will be displayed
# on the model's form (`new` and `edit`) pages.
FORM_ATTRIBUTES = [:name].freeze
# COLLECTION_FILTERS
# a hash that defines filters that can be used while searching via the search
# field of the dashboard.
#
# For example to add an option to search for open resources by typing "open:"
# in the search field:
#
# COLLECTION_FILTERS = {
# open: ->(resources) { resources.where(open: true) }
# }.freeze
COLLECTION_FILTERS = {}.freeze
# Overwrite this method to customize how currencies are displayed
# across all pages of the admin dashboard.
#
def display_resource(currency)
currency.name
end
end

View File

@@ -10,7 +10,6 @@ class SellCryptoOrderDashboard < Administrate::BaseDashboard
# on pages throughout the dashboard. # on pages throughout the dashboard.
ATTRIBUTE_TYPES = { ATTRIBUTE_TYPES = {
user: Field::BelongsTo, user: Field::BelongsTo,
currency: Field::BelongsTo,
id: Field::Number, id: Field::Number,
status: Field::Enumerize, status: Field::Enumerize,
paid_amount: Field::String.with_options(searchable: false), paid_amount: Field::String.with_options(searchable: false),
@@ -24,17 +23,17 @@ class SellCryptoOrderDashboard < Administrate::BaseDashboard
# #
# By default, it's limited to four items to reduce clutter on index pages. # By default, it's limited to four items to reduce clutter on index pages.
# Feel free to add, remove, or rearrange items. # Feel free to add, remove, or rearrange items.
COLLECTION_ATTRIBUTES = [:user, :currency, :id, :status].freeze COLLECTION_ATTRIBUTES = [:user, :id, :status].freeze
# SHOW_PAGE_ATTRIBUTES # SHOW_PAGE_ATTRIBUTES
# an array of attributes that will be displayed on the model's show page. # an array of attributes that will be displayed on the model's show page.
SHOW_PAGE_ATTRIBUTES = [:user, :currency, :id, :status, :paid_amount, :received_amount_cents, :created_at, SHOW_PAGE_ATTRIBUTES = [:user, :id, :status, :paid_amount, :received_amount_cents, :created_at,
:updated_at,].freeze :updated_at,].freeze
# FORM_ATTRIBUTES # FORM_ATTRIBUTES
# an array of attributes that will be displayed # an array of attributes that will be displayed
# on the model's form (`new` and `edit`) pages. # on the model's form (`new` and `edit`) pages.
FORM_ATTRIBUTES = [:user, :currency, :status, :paid_amount, :received_amount_cents].freeze FORM_ATTRIBUTES = [:user, :status, :paid_amount, :received_amount_cents].freeze
# COLLECTION_FILTERS # COLLECTION_FILTERS
# a hash that defines filters that can be used while searching via the search # a hash that defines filters that can be used while searching via the search

View File

@@ -10,7 +10,6 @@ class StakeOrderDashboard < Administrate::BaseDashboard
# on pages throughout the dashboard. # on pages throughout the dashboard.
ATTRIBUTE_TYPES = { ATTRIBUTE_TYPES = {
user: Field::BelongsTo, user: Field::BelongsTo,
currency: Field::BelongsTo,
id: Field::Number, id: Field::Number,
pool_name: Field::String, pool_name: Field::String,
status: Field::Enumerize, status: Field::Enumerize,
@@ -24,16 +23,16 @@ class StakeOrderDashboard < Administrate::BaseDashboard
# #
# By default, it's limited to four items to reduce clutter on index pages. # By default, it's limited to four items to reduce clutter on index pages.
# Feel free to add, remove, or rearrange items. # Feel free to add, remove, or rearrange items.
COLLECTION_ATTRIBUTES = [:user, :currency, :id, :pool_name].freeze COLLECTION_ATTRIBUTES = [:user, :id, :pool_name].freeze
# SHOW_PAGE_ATTRIBUTES # SHOW_PAGE_ATTRIBUTES
# an array of attributes that will be displayed on the model's show page. # an array of attributes that will be displayed on the model's show page.
SHOW_PAGE_ATTRIBUTES = [:user, :currency, :id, :pool_name, :status, :amount, :created_at, :updated_at].freeze SHOW_PAGE_ATTRIBUTES = [:user, :id, :pool_name, :status, :amount, :created_at, :updated_at].freeze
# FORM_ATTRIBUTES # FORM_ATTRIBUTES
# an array of attributes that will be displayed # an array of attributes that will be displayed
# on the model's form (`new` and `edit`) pages. # on the model's form (`new` and `edit`) pages.
FORM_ATTRIBUTES = [:user, :currency, :pool_name, :status, :amount].freeze FORM_ATTRIBUTES = [:user, :pool_name, :status, :amount].freeze
# COLLECTION_FILTERS # COLLECTION_FILTERS
# a hash that defines filters that can be used while searching via the search # a hash that defines filters that can be used while searching via the search

View File

@@ -1,7 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
module Inputs module Inputs
class CreateBuyCryptoOrderAttributesInput < Types::BaseInputObject class CreateBuyCryptoOrderAttributesInput < Types::BaseInputObject
argument :currency_id, ID, required: true
argument :amount_cents, Integer, "Amount to be paid", required: true argument :amount_cents, Integer, "Amount to be paid", required: true
end end
end end

View File

@@ -1,7 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
module Inputs module Inputs
class CreateSellCryptoOrderAttributesInput < Types::BaseInputObject class CreateSellCryptoOrderAttributesInput < Types::BaseInputObject
argument :currency_id, ID, required: true
argument :amount, String, "Amount to be paid", required: true argument :amount, String, "Amount to be paid", required: true
end end
end end

View File

@@ -6,8 +6,6 @@ module Mutations
argument :order, Inputs::CreateBuyCryptoOrderAttributesInput, required: true argument :order, Inputs::CreateBuyCryptoOrderAttributesInput, required: true
def resolve(order:) def resolve(order:)
currency_id = decode_id(order[:currency_id])
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
current_user current_user
.fiat_balance .fiat_balance
@@ -15,7 +13,6 @@ module Mutations
record = BuyCryptoOrder.create!( record = BuyCryptoOrder.create!(
paid_amount_cents: order[:amount_cents], paid_amount_cents: order[:amount_cents],
currency_id: currency_id,
user_id: current_user.id, user_id: current_user.id,
) )

View File

@@ -6,18 +6,15 @@ module Mutations
argument :order, Inputs::CreateSellCryptoOrderAttributesInput, required: true argument :order, Inputs::CreateSellCryptoOrderAttributesInput, required: true
def resolve(order:) def resolve(order:)
currency_id = decode_id(order[:currency_id])
amount = BigDecimal(order[:amount]) amount = BigDecimal(order[:amount])
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
current_user current_user
.balances .balance
.find_by!(currency_id: currency_id)
.withdrawal!(amount) .withdrawal!(amount)
record = SellCryptoOrder.create!( record = SellCryptoOrder.create!(
paid_amount: amount, paid_amount: amount,
currency_id: currency_id,
user_id: current_user.id, user_id: current_user.id,
) )

View File

@@ -6,18 +6,15 @@ module Mutations
argument :order, Inputs::CreateStakeOrderAttributesInput, required: true argument :order, Inputs::CreateStakeOrderAttributesInput, required: true
def resolve(order:) def resolve(order:)
currency_id = Currency.find_by!(name: "CAKE").id
amount = BigDecimal(order[:amount]) amount = BigDecimal(order[:amount])
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
current_user current_user
.balances .balance
.find_by!(currency_id: currency_id)
.withdrawal!(amount) .withdrawal!(amount)
record = StakeOrder.create!( record = StakeOrder.create!(
amount: amount, amount: amount,
currency_id: currency_id,
pool_name: order[:pool_name], pool_name: order[:pool_name],
user_id: current_user.id, user_id: current_user.id,
) )

View File

@@ -6,14 +6,12 @@ module Mutations
argument :order, Inputs::CreateStakeOrderAttributesInput, required: true argument :order, Inputs::CreateStakeOrderAttributesInput, required: true
def resolve(order:) def resolve(order:)
currency_id = Currency.find_by!(name: "CAKE").id
amount = -BigDecimal(order[:amount]) amount = -BigDecimal(order[:amount])
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
record = StakeOrder.find_or_initialize_by( record = StakeOrder.find_or_initialize_by(
pool_name: order[:pool_name], pool_name: order[:pool_name],
user_id: current_user.id, user_id: current_user.id,
currency_id: currency_id,
status: :processing status: :processing
) )

View File

@@ -8,10 +8,5 @@ module Types
field :id, ID, null: false field :id, ID, null: false
field :amount, String, null: false field :amount, String, null: false
field :currency, CurrencyType, null: false
def currency
dataloader.with(Dataloader::Source, Currency).load(object.currency_id)
end
end end
end end

View File

@@ -7,12 +7,6 @@ module Types
graphql_name "BuyCryptoOrder" graphql_name "BuyCryptoOrder"
field :id, ID, null: false field :id, ID, null: false
field :currency, CurrencyType, null: false
def currency
dataloader.with(Dataloader::Source, Currency).load(object.currency_id)
end
field :status, ProcessStatusEnum, null: false field :status, ProcessStatusEnum, null: false
field :paid_amount_cents, Integer, null: false field :paid_amount_cents, Integer, null: false
field :received_amount, String, null: true field :received_amount, String, null: true

View File

@@ -1,12 +0,0 @@
# frozen_string_literal: true
module Types
class CurrencyType < Types::BaseObject
implements GraphQL::Types::Relay::Node
global_id_field :id
graphql_name "Currency"
field :id, ID, null: false
field :name, String, null: false
end
end

View File

@@ -10,16 +10,6 @@ module Types
context[:current_user] context[:current_user]
end end
field :balances, BalanceType.connection_type, null: false
def balances
Pundit.policy_scope(current_user, Balance)
end
field :fiat_balances, FiatBalanceType.connection_type, null: false
def fiat_balances
Pundit.policy_scope(current_user, FiatBalance)
end
field :sell_crypto_orders, SellCryptoOrderType.connection_type, null: false field :sell_crypto_orders, SellCryptoOrderType.connection_type, null: false
def sell_crypto_orders def sell_crypto_orders
Pundit.policy_scope(current_user, SellCryptoOrder) Pundit.policy_scope(current_user, SellCryptoOrder)

View File

@@ -7,12 +7,6 @@ module Types
graphql_name "SellCryptoOrder" graphql_name "SellCryptoOrder"
field :id, ID, null: false field :id, ID, null: false
field :currency, CurrencyType, null: false
def currency
dataloader.with(Dataloader::Source, Currency).load(object.currency_id)
end
field :status, ProcessStatusEnum, null: false field :status, ProcessStatusEnum, null: false
field :paid_amount, String, null: false field :paid_amount, String, null: false
field :received_amount_cents, Integer, null: true field :received_amount_cents, Integer, null: true

View File

@@ -11,5 +11,8 @@ module Types
field :first_name, String, null: false field :first_name, String, null: false
field :last_name, String, null: false field :last_name, String, null: false
field :wallet_address, String, null: true field :wallet_address, String, null: true
field :balance, BalanceType, null: false
field :fiat_balance, FiatBalanceType, null: false
end end
end end

View File

@@ -6,8 +6,6 @@ class XStakeSchema < GraphQL::Schema
def self.resolve_type(abstract_type, obj, ctx) def self.resolve_type(abstract_type, obj, ctx)
case obj case obj
when Currency
Types::CurrencyType
when Balance when Balance
Types::BalanceType Types::BalanceType
when FiatBalance when FiatBalance

View File

@@ -1,42 +1,10 @@
type Balance implements Node { type Balance implements Node {
amount: String! amount: String!
currency: Currency!
id: ID! id: ID!
} }
"""
The connection type for Balance.
"""
type BalanceConnection {
"""
A list of edges.
"""
edges: [BalanceEdge!]!
"""
Information to aid in pagination.
"""
pageInfo: PageInfo!
}
"""
An edge in a connection.
"""
type BalanceEdge {
"""
A cursor for use in pagination.
"""
cursor: String!
"""
The item at the end of the edge.
"""
node: Balance!
}
type BuyCryptoOrder implements Node { type BuyCryptoOrder implements Node {
createdAt: ISO8601DateTime! createdAt: ISO8601DateTime!
currency: Currency!
id: ID! id: ID!
paidAmountCents: Int! paidAmountCents: Int!
receivedAmount: String receivedAmount: String
@@ -79,7 +47,6 @@ input CreateBuyCryptoOrderAttributesInput {
Amount to be paid Amount to be paid
""" """
amountCents: Int! amountCents: Int!
currencyId: ID!
} }
""" """
@@ -114,7 +81,6 @@ input CreateSellCryptoOrderAttributesInput {
Amount to be paid Amount to be paid
""" """
amount: String! amount: String!
currencyId: ID!
} }
""" """
@@ -206,47 +172,12 @@ type CreateStakeRemoveOrderPayload {
order: StakeOrder order: StakeOrder
} }
type Currency implements Node {
id: ID!
name: String!
}
type FiatBalance implements Node { type FiatBalance implements Node {
amountCents: Int! amountCents: Int!
amountCurrency: String! amountCurrency: String!
id: ID! id: ID!
} }
"""
The connection type for FiatBalance.
"""
type FiatBalanceConnection {
"""
A list of edges.
"""
edges: [FiatBalanceEdge!]!
"""
Information to aid in pagination.
"""
pageInfo: PageInfo!
}
"""
An edge in a connection.
"""
type FiatBalanceEdge {
"""
A cursor for use in pagination.
"""
cursor: String!
"""
The item at the end of the edge.
"""
node: FiatBalance!
}
""" """
An ISO 8601-encoded datetime An ISO 8601-encoded datetime
""" """
@@ -333,27 +264,6 @@ enum ProcessStatus {
} }
type Query { type Query {
balances(
"""
Returns the elements in the list that come after the specified cursor.
"""
after: String
"""
Returns the elements in the list that come before the specified cursor.
"""
before: String
"""
Returns the first _n_ elements from the list.
"""
first: Int
"""
Returns the last _n_ elements from the list.
"""
last: Int
): BalanceConnection!
buyCryptoOrders( buyCryptoOrders(
""" """
Returns the elements in the list that come after the specified cursor. Returns the elements in the list that come after the specified cursor.
@@ -376,27 +286,6 @@ type Query {
last: Int last: Int
): BuyCryptoOrderConnection! ): BuyCryptoOrderConnection!
currentUser: User currentUser: User
fiatBalances(
"""
Returns the elements in the list that come after the specified cursor.
"""
after: String
"""
Returns the elements in the list that come before the specified cursor.
"""
before: String
"""
Returns the first _n_ elements from the list.
"""
first: Int
"""
Returns the last _n_ elements from the list.
"""
last: Int
): FiatBalanceConnection!
""" """
Fetches an object given its ID. Fetches an object given its ID.
@@ -471,7 +360,6 @@ type RecordInvalid {
type SellCryptoOrder implements Node { type SellCryptoOrder implements Node {
createdAt: ISO8601DateTime! createdAt: ISO8601DateTime!
currency: Currency!
id: ID! id: ID!
paidAmount: String! paidAmount: String!
receivedAmountCents: Int receivedAmountCents: Int
@@ -555,7 +443,9 @@ input StakeOrderFilterInput {
} }
type User { type User {
balance: Balance!
email: String! email: String!
fiatBalance: FiatBalance!
firstName: String! firstName: String!
id: ID! id: ID!
lastName: String! lastName: String!

View File

@@ -7,17 +7,12 @@ import { Pool } from "./Pool";
import type { PoolListingQuery } from "./__generated__/PoolListingQuery.graphql"; import type { PoolListingQuery } from "./__generated__/PoolListingQuery.graphql";
export const PoolListing = () => { export const PoolListing = () => {
const { balances } = useLazyLoadQuery<PoolListingQuery>( const { currentUser } = useLazyLoadQuery<PoolListingQuery>(
graphql` graphql`
query PoolListingQuery { query PoolListingQuery {
balances { currentUser {
edges { balance {
node { amount
currency {
name
}
amount
}
} }
} }
} }
@@ -25,11 +20,7 @@ export const PoolListing = () => {
{} {}
); );
const cakeBalance = balances.edges.find( const balance = currentUser?.balance.amount ?? "0";
(edge) => edge.node.currency.name === "CAKE"
)?.node;
const balance = cakeBalance?.amount ?? "0";
return ( return (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 place-items-center w-full gap-8 py-4 -mt-16 overflow-x-hidden"> <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 place-items-center w-full gap-8 py-4 -mt-16 overflow-x-hidden">

View File

@@ -5,16 +5,11 @@
import { ConcreteRequest } from "relay-runtime"; import { ConcreteRequest } from "relay-runtime";
export type PoolListingQueryVariables = {}; export type PoolListingQueryVariables = {};
export type PoolListingQueryResponse = { export type PoolListingQueryResponse = {
readonly balances: { readonly currentUser: {
readonly edges: ReadonlyArray<{ readonly balance: {
readonly node: { readonly amount: string;
readonly currency: { };
readonly name: string; } | null;
};
readonly amount: string;
};
}>;
};
}; };
export type PoolListingQuery = { export type PoolListingQuery = {
readonly response: PoolListingQueryResponse; readonly response: PoolListingQueryResponse;
@@ -25,37 +20,25 @@ export type PoolListingQuery = {
/* /*
query PoolListingQuery { query PoolListingQuery {
balances { currentUser {
edges { balance {
node { amount
currency { id
name
id
}
amount
id
}
} }
id
} }
} }
*/ */
const node: ConcreteRequest = (function(){ const node: ConcreteRequest = (function(){
var v0 = { var v0 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "name",
"storageKey": null
},
v1 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "amount", "name": "amount",
"storageKey": null "storageKey": null
}, },
v2 = { v1 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
@@ -72,43 +55,20 @@ return {
{ {
"alias": null, "alias": null,
"args": null, "args": null,
"concreteType": "BalanceConnection", "concreteType": "User",
"kind": "LinkedField", "kind": "LinkedField",
"name": "balances", "name": "currentUser",
"plural": false, "plural": false,
"selections": [ "selections": [
{ {
"alias": null, "alias": null,
"args": null, "args": null,
"concreteType": "BalanceEdge", "concreteType": "Balance",
"kind": "LinkedField", "kind": "LinkedField",
"name": "edges", "name": "balance",
"plural": true, "plural": false,
"selections": [ "selections": [
{ (v0/*: any*/)
"alias": null,
"args": null,
"concreteType": "Balance",
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "Currency",
"kind": "LinkedField",
"name": "currency",
"plural": false,
"selections": [
(v0/*: any*/)
],
"storageKey": null
},
(v1/*: any*/)
],
"storageKey": null
}
], ],
"storageKey": null "storageKey": null
} }
@@ -128,62 +88,39 @@ return {
{ {
"alias": null, "alias": null,
"args": null, "args": null,
"concreteType": "BalanceConnection", "concreteType": "User",
"kind": "LinkedField", "kind": "LinkedField",
"name": "balances", "name": "currentUser",
"plural": false, "plural": false,
"selections": [ "selections": [
{ {
"alias": null, "alias": null,
"args": null, "args": null,
"concreteType": "BalanceEdge", "concreteType": "Balance",
"kind": "LinkedField", "kind": "LinkedField",
"name": "edges", "name": "balance",
"plural": true, "plural": false,
"selections": [ "selections": [
{ (v0/*: any*/),
"alias": null, (v1/*: any*/)
"args": null,
"concreteType": "Balance",
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "Currency",
"kind": "LinkedField",
"name": "currency",
"plural": false,
"selections": [
(v0/*: any*/),
(v2/*: any*/)
],
"storageKey": null
},
(v1/*: any*/),
(v2/*: any*/)
],
"storageKey": null
}
], ],
"storageKey": null "storageKey": null
} },
(v1/*: any*/)
], ],
"storageKey": null "storageKey": null
} }
] ]
}, },
"params": { "params": {
"cacheID": "6abf5e963429e49993af50df156f8e1c", "cacheID": "6af4091073903ead7eb057e9f245a32c",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "PoolListingQuery", "name": "PoolListingQuery",
"operationKind": "query", "operationKind": "query",
"text": "query PoolListingQuery {\n balances {\n edges {\n node {\n currency {\n name\n id\n }\n amount\n id\n }\n }\n }\n}\n" "text": "query PoolListingQuery {\n currentUser {\n balance {\n amount\n id\n }\n id\n }\n}\n"
} }
}; };
})(); })();
(node as any).hash = '4fefb238e24b79198799686599255e6c'; (node as any).hash = 'e296b5abac1f659b33d8c77522fbfc55';
export default node; export default node;

View File

@@ -11,11 +11,13 @@ export const Exchange = () => {
const data = useLazyLoadQuery<ExchangeQuery>( const data = useLazyLoadQuery<ExchangeQuery>(
graphql` graphql`
query ExchangeQuery { query ExchangeQuery {
fiatBalances { currentUser {
...ExchangePanel_fiatBalances fiatBalance {
} ...ExchangePanel_fiatBalances
balances { }
...ExchangePanel_balances balance {
...ExchangePanel_balances
}
} }
buyCryptoOrders { buyCryptoOrders {
...ExchangeHistory_buyCryptoOrders ...ExchangeHistory_buyCryptoOrders
@@ -30,10 +32,12 @@ export const Exchange = () => {
return ( return (
<div className="w-full"> <div className="w-full">
<ExchangePanel {data.currentUser && (
balancesRefs={data.balances} <ExchangePanel
fiatBalancesRefs={data.fiatBalances} balancesRefs={data.currentUser.balance}
/> fiatBalancesRefs={data.currentUser.fiatBalance}
/>
)}
<ExchangeHistory <ExchangeHistory
sellCryptoOrdersRefs={data.sellCryptoOrders} sellCryptoOrdersRefs={data.sellCryptoOrders}

View File

@@ -3,6 +3,7 @@ import type { FC } from "react";
import React from "react"; import React from "react";
import { useFragment } from "react-relay"; import { useFragment } from "react-relay";
import { Messages } from "../../../../messages";
import { centsToUnit } from "../../../../utils/fiatMoney"; import { centsToUnit } from "../../../../utils/fiatMoney";
import type { CryptoExchangeOrderProps } from "./components/CryptoExchangeOrder"; import type { CryptoExchangeOrderProps } from "./components/CryptoExchangeOrder";
import { CryptoExchangeOrder } from "./components/CryptoExchangeOrder"; import { CryptoExchangeOrder } from "./components/CryptoExchangeOrder";
@@ -47,9 +48,6 @@ export const ExchangeHistory: FC<Props> = ({
createdAt createdAt
paidAmountCents paidAmountCents
receivedAmount receivedAmount
currency {
name
}
__typename __typename
} }
} }
@@ -68,9 +66,6 @@ export const ExchangeHistory: FC<Props> = ({
paidAmount paidAmount
receivedAmountCents receivedAmountCents
createdAt createdAt
currency {
name
}
__typename __typename
} }
} }
@@ -95,7 +90,7 @@ export const ExchangeHistory: FC<Props> = ({
if (node?.__typename === "SellCryptoOrder") { if (node?.__typename === "SellCryptoOrder") {
return { return {
id: node.id, id: node.id,
payed: `${node.paidAmount} ${node.currency.name}`, payed: `${node.paidAmount} CAKE`,
received: `${centsToUnit(node.receivedAmountCents)} BRL`, received: `${centsToUnit(node.receivedAmountCents)} BRL`,
createdAt: new Date(node.createdAt as string).toLocaleString(), createdAt: new Date(node.createdAt as string).toLocaleString(),
kind: node.__typename, kind: node.__typename,
@@ -107,7 +102,7 @@ export const ExchangeHistory: FC<Props> = ({
return { return {
id: node.id, id: node.id,
payed: `${centsToUnit(node.paidAmountCents)} BRL`, payed: `${centsToUnit(node.paidAmountCents)} BRL`,
received: `${node.receivedAmount} ${node.currency.name}`, received: `${node.receivedAmount} CAKE`,
createdAt: new Date(node.createdAt as string).toLocaleString(), createdAt: new Date(node.createdAt as string).toLocaleString(),
kind: node.__typename, kind: node.__typename,
status: node.status, status: node.status,
@@ -117,7 +112,7 @@ export const ExchangeHistory: FC<Props> = ({
return null; return null;
}); });
if (!orderRows.length) return null; if (!orderRows.length) return <Messages.NoHistory historyName="troca" />;
return ( return (
<div className="container mx-auto px-4 sm:px-8"> <div className="container mx-auto px-4 sm:px-8">

View File

@@ -13,9 +13,6 @@ export type ExchangeHistory_buyCryptoOrders = {
readonly createdAt: unknown; readonly createdAt: unknown;
readonly paidAmountCents: number; readonly paidAmountCents: number;
readonly receivedAmount: string | null; readonly receivedAmount: string | null;
readonly currency: {
readonly name: string;
};
readonly __typename: string; readonly __typename: string;
}; };
}>; }>;
@@ -86,24 +83,6 @@ const node: ReaderFragment = {
"name": "receivedAmount", "name": "receivedAmount",
"storageKey": null "storageKey": null
}, },
{
"alias": null,
"args": null,
"concreteType": "Currency",
"kind": "LinkedField",
"name": "currency",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "name",
"storageKey": null
}
],
"storageKey": null
},
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -121,5 +100,5 @@ const node: ReaderFragment = {
"type": "BuyCryptoOrderConnection", "type": "BuyCryptoOrderConnection",
"abstractKey": null "abstractKey": null
}; };
(node as any).hash = 'da0e93160594d0e07defe123a9bd755b'; (node as any).hash = 'cf603cb2594ebe32eb4c562df9b03585';
export default node; export default node;

View File

@@ -13,9 +13,6 @@ export type ExchangeHistory_sellCryptoOrders = {
readonly paidAmount: string; readonly paidAmount: string;
readonly receivedAmountCents: number | null; readonly receivedAmountCents: number | null;
readonly createdAt: unknown; readonly createdAt: unknown;
readonly currency: {
readonly name: string;
};
readonly __typename: string; readonly __typename: string;
}; };
}>; }>;
@@ -86,24 +83,6 @@ const node: ReaderFragment = {
"name": "createdAt", "name": "createdAt",
"storageKey": null "storageKey": null
}, },
{
"alias": null,
"args": null,
"concreteType": "Currency",
"kind": "LinkedField",
"name": "currency",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "name",
"storageKey": null
}
],
"storageKey": null
},
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -121,5 +100,5 @@ const node: ReaderFragment = {
"type": "SellCryptoOrderConnection", "type": "SellCryptoOrderConnection",
"abstractKey": null "abstractKey": null
}; };
(node as any).hash = '384d1326525240c150d450555796a621'; (node as any).hash = '0a6fbd33935e0dcd241ffa3270f1ea30';
export default node; export default node;

View File

@@ -36,30 +36,19 @@ export const ExchangePanel: FC<Props> = ({
const [cryptoDock, setCryptoDock] = useState<string>("0"); const [cryptoDock, setCryptoDock] = useState<string>("0");
const [fiatDock, setFiatDock] = useState<string>("0.00"); const [fiatDock, setFiatDock] = useState<string>("0.00");
const fiatBalances = useFragment<ExchangePanel_fiatBalances$key>( const fiatBalance = useFragment<ExchangePanel_fiatBalances$key>(
graphql` graphql`
fragment ExchangePanel_fiatBalances on FiatBalanceConnection { fragment ExchangePanel_fiatBalances on FiatBalance {
edges { amountCents
node {
amountCents
}
}
} }
`, `,
fiatBalancesRefs fiatBalancesRefs
); );
const balances = useFragment<ExchangePanel_balances$key>( const balance = useFragment<ExchangePanel_balances$key>(
graphql` graphql`
fragment ExchangePanel_balances on BalanceConnection { fragment ExchangePanel_balances on Balance {
edges { amount
node {
amount
currency {
id
}
}
}
} }
`, `,
balancesRefs balancesRefs
@@ -67,12 +56,9 @@ export const ExchangePanel: FC<Props> = ({
if (!isAuthenticated) return <Unauthenticated />; if (!isAuthenticated) return <Unauthenticated />;
const [crypto] = balances.edges; const avaliableCrypto = new BigNumber(balance.amount);
const [fiat] = fiatBalances.edges;
const avaliableCrypto = new BigNumber(crypto.node.amount);
const avaliableFiat = ( const avaliableFiat = (
fiat.node.amountCents ? fiat.node.amountCents / 100 : 0 fiatBalance.amountCents ? fiatBalance.amountCents / 100 : 0
).toFixed(2); ).toFixed(2);
const handleSellTabClick = () => { const handleSellTabClick = () => {
@@ -123,14 +109,12 @@ export const ExchangePanel: FC<Props> = ({
if (exchangeOption === "SELL") { if (exchangeOption === "SELL") {
commitCreateSellCryptoOrderMutation(environment, { commitCreateSellCryptoOrderMutation(environment, {
amount: cryptoDock, amount: cryptoDock,
currencyId: crypto.node.currency.id,
}); });
} }
if (exchangeOption === "BUY") { if (exchangeOption === "BUY") {
commitCreateBuyCryptoOrderMutation(environment, { commitCreateBuyCryptoOrderMutation(environment, {
amountCents: parseFloat(fiatDock) * 100, amountCents: parseFloat(fiatDock) * 100,
currencyId: crypto.node.currency.id,
}); });
} }
}; };
@@ -172,7 +156,7 @@ export const ExchangePanel: FC<Props> = ({
> >
<span className="mb-2"> <span className="mb-2">
{exchangeOption === "SELL" ? "CAKE" : "BRL"} disponível:{" "} {exchangeOption === "SELL" ? "CAKE" : "BRL"} disponível:{" "}
{exchangeOption === "SELL" ? crypto.node.amount : avaliableFiat} {exchangeOption === "SELL" ? balance.amount : avaliableFiat}
</span> </span>
<div className="flex flex-row"> <div className="flex flex-row">
{exchangeOption === "BUY" ? ( {exchangeOption === "BUY" ? (

View File

@@ -5,14 +5,7 @@
import { ReaderFragment } from "relay-runtime"; import { ReaderFragment } from "relay-runtime";
import { FragmentRefs } from "relay-runtime"; import { FragmentRefs } from "relay-runtime";
export type ExchangePanel_balances = { export type ExchangePanel_balances = {
readonly edges: ReadonlyArray<{ readonly amount: string;
readonly node: {
readonly amount: string;
readonly currency: {
readonly id: string;
};
};
}>;
readonly " $refType": "ExchangePanel_balances"; readonly " $refType": "ExchangePanel_balances";
}; };
export type ExchangePanel_balances$data = ExchangePanel_balances; export type ExchangePanel_balances$data = ExchangePanel_balances;
@@ -32,53 +25,13 @@ const node: ReaderFragment = {
{ {
"alias": null, "alias": null,
"args": null, "args": null,
"concreteType": "BalanceEdge", "kind": "ScalarField",
"kind": "LinkedField", "name": "amount",
"name": "edges",
"plural": true,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "Balance",
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "amount",
"storageKey": null
},
{
"alias": null,
"args": null,
"concreteType": "Currency",
"kind": "LinkedField",
"name": "currency",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "id",
"storageKey": null
}
],
"storageKey": null
}
],
"storageKey": null
}
],
"storageKey": null "storageKey": null
} }
], ],
"type": "BalanceConnection", "type": "Balance",
"abstractKey": null "abstractKey": null
}; };
(node as any).hash = '3be851ad99a353609459a7edc960f272'; (node as any).hash = '99736114264996104eaa4907673d9849';
export default node; export default node;

View File

@@ -5,11 +5,7 @@
import { ReaderFragment } from "relay-runtime"; import { ReaderFragment } from "relay-runtime";
import { FragmentRefs } from "relay-runtime"; import { FragmentRefs } from "relay-runtime";
export type ExchangePanel_fiatBalances = { export type ExchangePanel_fiatBalances = {
readonly edges: ReadonlyArray<{ readonly amountCents: number;
readonly node: {
readonly amountCents: number;
};
}>;
readonly " $refType": "ExchangePanel_fiatBalances"; readonly " $refType": "ExchangePanel_fiatBalances";
}; };
export type ExchangePanel_fiatBalances$data = ExchangePanel_fiatBalances; export type ExchangePanel_fiatBalances$data = ExchangePanel_fiatBalances;
@@ -29,35 +25,13 @@ const node: ReaderFragment = {
{ {
"alias": null, "alias": null,
"args": null, "args": null,
"concreteType": "FiatBalanceEdge", "kind": "ScalarField",
"kind": "LinkedField", "name": "amountCents",
"name": "edges",
"plural": true,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "FiatBalance",
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "amountCents",
"storageKey": null
}
],
"storageKey": null
}
],
"storageKey": null "storageKey": null
} }
], ],
"type": "FiatBalanceConnection", "type": "FiatBalance",
"abstractKey": null "abstractKey": null
}; };
(node as any).hash = '14b79d15c8353d856f3e74bb7c181cf7'; (node as any).hash = '9f9bd030f967a665c247facbf641b760';
export default node; export default node;

View File

@@ -4,7 +4,6 @@
import { ConcreteRequest } from "relay-runtime"; import { ConcreteRequest } from "relay-runtime";
export type createBuyCryptoOrderMutationVariables = { export type createBuyCryptoOrderMutationVariables = {
currencyId: string;
amountCents: number; amountCents: number;
}; };
export type createBuyCryptoOrderMutationResponse = { export type createBuyCryptoOrderMutationResponse = {
@@ -26,10 +25,9 @@ export type createBuyCryptoOrderMutation = {
/* /*
mutation createBuyCryptoOrderMutation( mutation createBuyCryptoOrderMutation(
$currencyId: ID!
$amountCents: Int! $amountCents: Int!
) { ) {
createBuyCryptoOrder(input: {order: {currencyId: $currencyId, amountCents: $amountCents}}) { createBuyCryptoOrder(input: {order: {amountCents: $amountCents}}) {
errors { errors {
messages messages
} }
@@ -41,17 +39,14 @@ mutation createBuyCryptoOrderMutation(
*/ */
const node: ConcreteRequest = (function(){ const node: ConcreteRequest = (function(){
var v0 = { var v0 = [
"defaultValue": null, {
"kind": "LocalArgument", "defaultValue": null,
"name": "amountCents" "kind": "LocalArgument",
}, "name": "amountCents"
v1 = { }
"defaultValue": null, ],
"kind": "LocalArgument", v1 = [
"name": "currencyId"
},
v2 = [
{ {
"alias": null, "alias": null,
"args": [ "args": [
@@ -63,11 +58,6 @@ v2 = [
"kind": "Variable", "kind": "Variable",
"name": "amountCents", "name": "amountCents",
"variableName": "amountCents" "variableName": "amountCents"
},
{
"kind": "Variable",
"name": "currencyId",
"variableName": "currencyId"
} }
], ],
"kind": "ObjectValue", "kind": "ObjectValue",
@@ -125,36 +115,30 @@ v2 = [
]; ];
return { return {
"fragment": { "fragment": {
"argumentDefinitions": [ "argumentDefinitions": (v0/*: any*/),
(v0/*: any*/),
(v1/*: any*/)
],
"kind": "Fragment", "kind": "Fragment",
"metadata": null, "metadata": null,
"name": "createBuyCryptoOrderMutation", "name": "createBuyCryptoOrderMutation",
"selections": (v2/*: any*/), "selections": (v1/*: any*/),
"type": "Mutation", "type": "Mutation",
"abstractKey": null "abstractKey": null
}, },
"kind": "Request", "kind": "Request",
"operation": { "operation": {
"argumentDefinitions": [ "argumentDefinitions": (v0/*: any*/),
(v1/*: any*/),
(v0/*: any*/)
],
"kind": "Operation", "kind": "Operation",
"name": "createBuyCryptoOrderMutation", "name": "createBuyCryptoOrderMutation",
"selections": (v2/*: any*/) "selections": (v1/*: any*/)
}, },
"params": { "params": {
"cacheID": "d7cc0c483d893b14f46781408d9d3f2f", "cacheID": "aad8a1ea13e8a77031c98f59b0c5e0db",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "createBuyCryptoOrderMutation", "name": "createBuyCryptoOrderMutation",
"operationKind": "mutation", "operationKind": "mutation",
"text": "mutation createBuyCryptoOrderMutation(\n $currencyId: ID!\n $amountCents: Int!\n) {\n createBuyCryptoOrder(input: {order: {currencyId: $currencyId, amountCents: $amountCents}}) {\n errors {\n messages\n }\n order {\n id\n }\n }\n}\n" "text": "mutation createBuyCryptoOrderMutation(\n $amountCents: Int!\n) {\n createBuyCryptoOrder(input: {order: {amountCents: $amountCents}}) {\n errors {\n messages\n }\n order {\n id\n }\n }\n}\n"
} }
}; };
})(); })();
(node as any).hash = 'a272ce6d5ae676a9cdc4e38eb7cc3cbe'; (node as any).hash = '1eceec2d8340693381f746a9e75476b8';
export default node; export default node;

View File

@@ -4,7 +4,6 @@
import { ConcreteRequest } from "relay-runtime"; import { ConcreteRequest } from "relay-runtime";
export type createSellCryptoOrderMutationVariables = { export type createSellCryptoOrderMutationVariables = {
currencyId: string;
amount: string; amount: string;
}; };
export type createSellCryptoOrderMutationResponse = { export type createSellCryptoOrderMutationResponse = {
@@ -26,10 +25,9 @@ export type createSellCryptoOrderMutation = {
/* /*
mutation createSellCryptoOrderMutation( mutation createSellCryptoOrderMutation(
$currencyId: ID!
$amount: String! $amount: String!
) { ) {
createSellCryptoOrder(input: {order: {currencyId: $currencyId, amount: $amount}}) { createSellCryptoOrder(input: {order: {amount: $amount}}) {
errors { errors {
messages messages
} }
@@ -41,17 +39,14 @@ mutation createSellCryptoOrderMutation(
*/ */
const node: ConcreteRequest = (function(){ const node: ConcreteRequest = (function(){
var v0 = { var v0 = [
"defaultValue": null, {
"kind": "LocalArgument", "defaultValue": null,
"name": "amount" "kind": "LocalArgument",
}, "name": "amount"
v1 = { }
"defaultValue": null, ],
"kind": "LocalArgument", v1 = [
"name": "currencyId"
},
v2 = [
{ {
"alias": null, "alias": null,
"args": [ "args": [
@@ -63,11 +58,6 @@ v2 = [
"kind": "Variable", "kind": "Variable",
"name": "amount", "name": "amount",
"variableName": "amount" "variableName": "amount"
},
{
"kind": "Variable",
"name": "currencyId",
"variableName": "currencyId"
} }
], ],
"kind": "ObjectValue", "kind": "ObjectValue",
@@ -125,36 +115,30 @@ v2 = [
]; ];
return { return {
"fragment": { "fragment": {
"argumentDefinitions": [ "argumentDefinitions": (v0/*: any*/),
(v0/*: any*/),
(v1/*: any*/)
],
"kind": "Fragment", "kind": "Fragment",
"metadata": null, "metadata": null,
"name": "createSellCryptoOrderMutation", "name": "createSellCryptoOrderMutation",
"selections": (v2/*: any*/), "selections": (v1/*: any*/),
"type": "Mutation", "type": "Mutation",
"abstractKey": null "abstractKey": null
}, },
"kind": "Request", "kind": "Request",
"operation": { "operation": {
"argumentDefinitions": [ "argumentDefinitions": (v0/*: any*/),
(v1/*: any*/),
(v0/*: any*/)
],
"kind": "Operation", "kind": "Operation",
"name": "createSellCryptoOrderMutation", "name": "createSellCryptoOrderMutation",
"selections": (v2/*: any*/) "selections": (v1/*: any*/)
}, },
"params": { "params": {
"cacheID": "2c81ae5adf76b4fa157bc5453df40fcc", "cacheID": "d4cb659efe0d2b63262cce510327ae11",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "createSellCryptoOrderMutation", "name": "createSellCryptoOrderMutation",
"operationKind": "mutation", "operationKind": "mutation",
"text": "mutation createSellCryptoOrderMutation(\n $currencyId: ID!\n $amount: String!\n) {\n createSellCryptoOrder(input: {order: {currencyId: $currencyId, amount: $amount}}) {\n errors {\n messages\n }\n order {\n id\n }\n }\n}\n" "text": "mutation createSellCryptoOrderMutation(\n $amount: String!\n) {\n createSellCryptoOrder(input: {order: {amount: $amount}}) {\n errors {\n messages\n }\n order {\n id\n }\n }\n}\n"
} }
}; };
})(); })();
(node as any).hash = '073e3f84d5921279ded3149dd9ec7db9'; (node as any).hash = '5ce66da95c141385c607a3be499805f7';
export default node; export default node;

View File

@@ -10,15 +10,8 @@ export const commitCreateBuyCryptoOrderMutation = (
) => { ) => {
return commitMutation(environment, { return commitMutation(environment, {
mutation: graphql` mutation: graphql`
mutation createBuyCryptoOrderMutation( mutation createBuyCryptoOrderMutation($amountCents: Int!) {
$currencyId: ID! createBuyCryptoOrder(input: { order: { amountCents: $amountCents } }) {
$amountCents: Int!
) {
createBuyCryptoOrder(
input: {
order: { currencyId: $currencyId, amountCents: $amountCents }
}
) {
errors { errors {
messages messages
} }
@@ -28,7 +21,7 @@ export const commitCreateBuyCryptoOrderMutation = (
} }
} }
`, `,
variables: { ...variables }, variables,
onCompleted: (_response) => { onCompleted: (_response) => {
window.location.reload(); window.location.reload();
}, },

View File

@@ -10,13 +10,8 @@ export const commitCreateSellCryptoOrderMutation = (
) => { ) => {
return commitMutation(environment, { return commitMutation(environment, {
mutation: graphql` mutation: graphql`
mutation createSellCryptoOrderMutation( mutation createSellCryptoOrderMutation($amount: String!) {
$currencyId: ID! createSellCryptoOrder(input: { order: { amount: $amount } }) {
$amount: String!
) {
createSellCryptoOrder(
input: { order: { currencyId: $currencyId, amount: $amount } }
) {
errors { errors {
messages messages
} }
@@ -26,7 +21,7 @@ export const commitCreateSellCryptoOrderMutation = (
} }
} }
`, `,
variables: { ...variables }, variables,
onCompleted: (_response) => { onCompleted: (_response) => {
window.location.reload(); window.location.reload();
}, },

View File

@@ -6,12 +6,14 @@ import { ConcreteRequest } from "relay-runtime";
import { FragmentRefs } from "relay-runtime"; import { FragmentRefs } from "relay-runtime";
export type ExchangeQueryVariables = {}; export type ExchangeQueryVariables = {};
export type ExchangeQueryResponse = { export type ExchangeQueryResponse = {
readonly fiatBalances: { readonly currentUser: {
readonly " $fragmentRefs": FragmentRefs<"ExchangePanel_fiatBalances">; readonly fiatBalance: {
}; readonly " $fragmentRefs": FragmentRefs<"ExchangePanel_fiatBalances">;
readonly balances: { };
readonly " $fragmentRefs": FragmentRefs<"ExchangePanel_balances">; readonly balance: {
}; readonly " $fragmentRefs": FragmentRefs<"ExchangePanel_balances">;
};
} | null;
readonly buyCryptoOrders: { readonly buyCryptoOrders: {
readonly " $fragmentRefs": FragmentRefs<"ExchangeHistory_buyCryptoOrders">; readonly " $fragmentRefs": FragmentRefs<"ExchangeHistory_buyCryptoOrders">;
}; };
@@ -28,11 +30,16 @@ export type ExchangeQuery = {
/* /*
query ExchangeQuery { query ExchangeQuery {
fiatBalances { currentUser {
...ExchangePanel_fiatBalances fiatBalance {
} ...ExchangePanel_fiatBalances
balances { id
...ExchangePanel_balances }
balance {
...ExchangePanel_balances
id
}
id
} }
buyCryptoOrders { buyCryptoOrders {
...ExchangeHistory_buyCryptoOrders ...ExchangeHistory_buyCryptoOrders
@@ -50,10 +57,6 @@ fragment ExchangeHistory_buyCryptoOrders on BuyCryptoOrderConnection {
createdAt createdAt
paidAmountCents paidAmountCents
receivedAmount receivedAmount
currency {
name
id
}
__typename __typename
} }
} }
@@ -67,34 +70,17 @@ fragment ExchangeHistory_sellCryptoOrders on SellCryptoOrderConnection {
paidAmount paidAmount
receivedAmountCents receivedAmountCents
createdAt createdAt
currency {
name
id
}
__typename __typename
} }
} }
} }
fragment ExchangePanel_balances on BalanceConnection { fragment ExchangePanel_balances on Balance {
edges { amount
node {
amount
currency {
id
}
id
}
}
} }
fragment ExchangePanel_fiatBalances on FiatBalanceConnection { fragment ExchangePanel_fiatBalances on FiatBalance {
edges { amountCents
node {
amountCents
id
}
}
} }
*/ */
@@ -121,25 +107,6 @@ v2 = {
"storageKey": null "storageKey": null
}, },
v3 = { v3 = {
"alias": null,
"args": null,
"concreteType": "Currency",
"kind": "LinkedField",
"name": "currency",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "name",
"storageKey": null
},
(v0/*: any*/)
],
"storageKey": null
},
v4 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
@@ -156,31 +123,42 @@ return {
{ {
"alias": null, "alias": null,
"args": null, "args": null,
"concreteType": "FiatBalanceConnection", "concreteType": "User",
"kind": "LinkedField", "kind": "LinkedField",
"name": "fiatBalances", "name": "currentUser",
"plural": false, "plural": false,
"selections": [ "selections": [
{ {
"alias": null,
"args": null, "args": null,
"kind": "FragmentSpread", "concreteType": "FiatBalance",
"name": "ExchangePanel_fiatBalances" "kind": "LinkedField",
} "name": "fiatBalance",
], "plural": false,
"storageKey": null "selections": [
}, {
{ "args": null,
"alias": null, "kind": "FragmentSpread",
"args": null, "name": "ExchangePanel_fiatBalances"
"concreteType": "BalanceConnection", }
"kind": "LinkedField", ],
"name": "balances", "storageKey": null
"plural": false, },
"selections": [
{ {
"alias": null,
"args": null, "args": null,
"kind": "FragmentSpread", "concreteType": "Balance",
"name": "ExchangePanel_balances" "kind": "LinkedField",
"name": "balance",
"plural": false,
"selections": [
{
"args": null,
"kind": "FragmentSpread",
"name": "ExchangePanel_balances"
}
],
"storageKey": null
} }
], ],
"storageKey": null "storageKey": null
@@ -230,94 +208,50 @@ return {
{ {
"alias": null, "alias": null,
"args": null, "args": null,
"concreteType": "FiatBalanceConnection", "concreteType": "User",
"kind": "LinkedField", "kind": "LinkedField",
"name": "fiatBalances", "name": "currentUser",
"plural": false, "plural": false,
"selections": [ "selections": [
{ {
"alias": null, "alias": null,
"args": null, "args": null,
"concreteType": "FiatBalanceEdge", "concreteType": "FiatBalance",
"kind": "LinkedField", "kind": "LinkedField",
"name": "edges", "name": "fiatBalance",
"plural": true, "plural": false,
"selections": [ "selections": [
{ {
"alias": null, "alias": null,
"args": null, "args": null,
"concreteType": "FiatBalance", "kind": "ScalarField",
"kind": "LinkedField", "name": "amountCents",
"name": "node",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "amountCents",
"storageKey": null
},
(v0/*: any*/)
],
"storageKey": null "storageKey": null
} },
(v0/*: any*/)
], ],
"storageKey": null "storageKey": null
} },
],
"storageKey": null
},
{
"alias": null,
"args": null,
"concreteType": "BalanceConnection",
"kind": "LinkedField",
"name": "balances",
"plural": false,
"selections": [
{ {
"alias": null, "alias": null,
"args": null, "args": null,
"concreteType": "BalanceEdge", "concreteType": "Balance",
"kind": "LinkedField", "kind": "LinkedField",
"name": "edges", "name": "balance",
"plural": true, "plural": false,
"selections": [ "selections": [
{ {
"alias": null, "alias": null,
"args": null, "args": null,
"concreteType": "Balance", "kind": "ScalarField",
"kind": "LinkedField", "name": "amount",
"name": "node",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "amount",
"storageKey": null
},
{
"alias": null,
"args": null,
"concreteType": "Currency",
"kind": "LinkedField",
"name": "currency",
"plural": false,
"selections": [
(v0/*: any*/)
],
"storageKey": null
},
(v0/*: any*/)
],
"storageKey": null "storageKey": null
} },
(v0/*: any*/)
], ],
"storageKey": null "storageKey": null
} },
(v0/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
@@ -362,8 +296,7 @@ return {
"name": "receivedAmount", "name": "receivedAmount",
"storageKey": null "storageKey": null
}, },
(v3/*: any*/), (v3/*: any*/)
(v4/*: any*/)
], ],
"storageKey": null "storageKey": null
} }
@@ -414,8 +347,7 @@ return {
"storageKey": null "storageKey": null
}, },
(v2/*: any*/), (v2/*: any*/),
(v3/*: any*/), (v3/*: any*/)
(v4/*: any*/)
], ],
"storageKey": null "storageKey": null
} }
@@ -428,14 +360,14 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "424352bbffec52284c44f109ce54a441", "cacheID": "3312f3d7aa6ac4b7051376b61f10c957",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "ExchangeQuery", "name": "ExchangeQuery",
"operationKind": "query", "operationKind": "query",
"text": "query ExchangeQuery {\n fiatBalances {\n ...ExchangePanel_fiatBalances\n }\n balances {\n ...ExchangePanel_balances\n }\n buyCryptoOrders {\n ...ExchangeHistory_buyCryptoOrders\n }\n sellCryptoOrders {\n ...ExchangeHistory_sellCryptoOrders\n }\n}\n\nfragment ExchangeHistory_buyCryptoOrders on BuyCryptoOrderConnection {\n edges {\n node {\n id\n status\n createdAt\n paidAmountCents\n receivedAmount\n currency {\n name\n id\n }\n __typename\n }\n }\n}\n\nfragment ExchangeHistory_sellCryptoOrders on SellCryptoOrderConnection {\n edges {\n node {\n id\n status\n paidAmount\n receivedAmountCents\n createdAt\n currency {\n name\n id\n }\n __typename\n }\n }\n}\n\nfragment ExchangePanel_balances on BalanceConnection {\n edges {\n node {\n amount\n currency {\n id\n }\n id\n }\n }\n}\n\nfragment ExchangePanel_fiatBalances on FiatBalanceConnection {\n edges {\n node {\n amountCents\n id\n }\n }\n}\n" "text": "query ExchangeQuery {\n currentUser {\n fiatBalance {\n ...ExchangePanel_fiatBalances\n id\n }\n balance {\n ...ExchangePanel_balances\n id\n }\n id\n }\n buyCryptoOrders {\n ...ExchangeHistory_buyCryptoOrders\n }\n sellCryptoOrders {\n ...ExchangeHistory_sellCryptoOrders\n }\n}\n\nfragment ExchangeHistory_buyCryptoOrders on BuyCryptoOrderConnection {\n edges {\n node {\n id\n status\n createdAt\n paidAmountCents\n receivedAmount\n __typename\n }\n }\n}\n\nfragment ExchangeHistory_sellCryptoOrders on SellCryptoOrderConnection {\n edges {\n node {\n id\n status\n paidAmount\n receivedAmountCents\n createdAt\n __typename\n }\n }\n}\n\nfragment ExchangePanel_balances on Balance {\n amount\n}\n\nfragment ExchangePanel_fiatBalances on FiatBalance {\n amountCents\n}\n"
} }
}; };
})(); })();
(node as any).hash = '3d09bb5b003cac17750666dc76088801'; (node as any).hash = '85296680bd82d278a1f5d485b8b101f3';
export default node; export default node;

View File

@@ -0,0 +1,71 @@
import { graphql } from "babel-plugin-relay/macro";
import type { FC } from "react";
import React from "react";
import { useFragment } from "react-relay";
import { getCurrencyLogo } from "../../utils/getCurrencyLogo";
import type { Balance_balance$key } from "./__generated__/Balance_balance.graphql";
type Props = {
balancesRef: Balance_balance$key;
};
export const Balance: FC<Props> = ({ balancesRef }) => {
const node = useFragment<Balance_balance$key>(
graphql`
fragment Balance_balance on Balance {
amount
}
`,
balancesRef
);
if (!node) return null;
return (
<div className="-mx-4 sm:-mx-8 px-4 sm:px-8 py-4 overflow-x-auto">
<div className="inline-block min-w-full shadow rounded-lg overflow-hidden">
<table className="min-w-full leading-normal">
<thead>
<tr>
<th
scope="col"
className="px-5 py-3 bg-white border-b border-gray-200 text-gray-800 text-left text-sm uppercase font-normal"
>
Moeda
</th>
<th
scope="col"
className="px-5 py-3 bg-white border-b border-gray-200 text-gray-800 text-left text-sm uppercase font-normal"
>
Saldo
</th>
</tr>
</thead>
<tbody>
<tr>
<td className="px-5 py-5 border-b border-gray-200 bg-white text-sm">
<div className="flex items-center">
<div className="flex-shrink-0">
<img
alt="CAKE icon"
src={getCurrencyLogo("CAKE")}
className="mx-auto object-cover rounded-full h-10 w-10 "
/>
</div>
<div className="ml-3">
<p className="text-gray-900 whitespace-no-wrap">CAKE</p>
</div>
</div>
</td>
<td className="px-5 py-5 border-b border-gray-200 bg-white text-sm">
<p className="text-gray-900 whitespace-no-wrap">
{node.amount}
</p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
);
};

View File

@@ -1,85 +0,0 @@
import { graphql } from "babel-plugin-relay/macro";
import type { FC } from "react";
import React from "react";
import { useFragment } from "react-relay";
import { getCurrencyLogo } from "../../utils/getCurrencyLogo";
import type { Balances_balances$key } from "./__generated__/Balances_balances.graphql";
type Props = {
balancesRef: Balances_balances$key;
};
export const Balances: FC<Props> = ({ balancesRef }) => {
const { edges } = useFragment<Balances_balances$key>(
graphql`
fragment Balances_balances on BalanceConnection {
edges {
node {
id
amount
currency {
name
}
}
}
}
`,
balancesRef
);
if (!edges.length) return null;
return (
<div className="-mx-4 sm:-mx-8 px-4 sm:px-8 py-4 overflow-x-auto">
<div className="inline-block min-w-full shadow rounded-lg overflow-hidden">
<table className="min-w-full leading-normal">
<thead>
<tr>
<th
scope="col"
className="px-5 py-3 bg-white border-b border-gray-200 text-gray-800 text-left text-sm uppercase font-normal"
>
Moeda
</th>
<th
scope="col"
className="px-5 py-3 bg-white border-b border-gray-200 text-gray-800 text-left text-sm uppercase font-normal"
>
Saldo
</th>
</tr>
</thead>
<tbody>
{edges.map(({ node }) => {
return (
<tr key={node.id}>
<td className="px-5 py-5 border-b border-gray-200 bg-white text-sm">
<div className="flex items-center">
<div className="flex-shrink-0">
<img
alt={`${node.currency.name} icon`}
src={getCurrencyLogo(node.currency.name)}
className="mx-auto object-cover rounded-full h-10 w-10 "
/>
</div>
<div className="ml-3">
<p className="text-gray-900 whitespace-no-wrap">
{node.currency.name}
</p>
</div>
</div>
</td>
<td className="px-5 py-5 border-b border-gray-200 bg-white text-sm">
<p className="text-gray-900 whitespace-no-wrap">
{node.amount}
</p>
</td>
</tr>
);
})}
</tbody>
</table>
</div>
</div>
);
};

View File

@@ -3,31 +3,25 @@ import type { FC } from "react";
import React from "react"; import React from "react";
import { useFragment } from "react-relay"; import { useFragment } from "react-relay";
import type { FiatBalances_fiatBalances$key } from "./__generated__/FiatBalances_fiatBalances.graphql"; import type { FiatBalance_fiatBalance$key } from "./__generated__/FiatBalance_fiatBalance.graphql";
type Props = { type Props = {
fiatBalancesRef: FiatBalances_fiatBalances$key; fiatBalancesRef: FiatBalance_fiatBalance$key;
}; };
export const FiatBalances: FC<Props> = ({ fiatBalancesRef }) => { export const FiatBalance: FC<Props> = ({ fiatBalancesRef }) => {
const { edges } = useFragment<FiatBalances_fiatBalances$key>( const userFiatBalance = useFragment<FiatBalance_fiatBalance$key>(
graphql` graphql`
fragment FiatBalances_fiatBalances on FiatBalanceConnection { fragment FiatBalance_fiatBalance on FiatBalance {
edges { amountCents
node { amountCurrency
amountCents
amountCurrency
}
}
} }
`, `,
fiatBalancesRef fiatBalancesRef
); );
if (!edges.length) return null; if (!userFiatBalance) return null;
const [firstResult] = edges; const { amountCents, amountCurrency } = userFiatBalance;
const { amountCents, amountCurrency } = firstResult.node;
const amount = (amountCents ? amountCents / 100 : 0).toFixed(2); const amount = (amountCents ? amountCents / 100 : 0).toFixed(2);

View File

@@ -5,34 +5,36 @@ import { useLazyLoadQuery } from "react-relay";
import { useCurrentUser } from "../../contexts/UserProvider"; import { useCurrentUser } from "../../contexts/UserProvider";
import { Messages } from "../../messages"; import { Messages } from "../../messages";
import { Balances } from "./Balances"; import { Balance } from "./Balance";
import { FiatBalances } from "./FiatBalances"; import { FiatBalance } from "./FiatBalance";
import type { WalletQuery } from "./__generated__/WalletQuery.graphql"; import type { WalletQuery } from "./__generated__/WalletQuery.graphql";
export const Wallet: FC = () => { export const Wallet: FC = () => {
const { isAuthenticated } = useCurrentUser(); const { isAuthenticated } = useCurrentUser();
const { fiatBalances, balances } = useLazyLoadQuery<WalletQuery>( const { currentUser } = useLazyLoadQuery<WalletQuery>(
graphql` graphql`
query WalletQuery { query WalletQuery {
fiatBalances { currentUser {
...FiatBalances_fiatBalances fiatBalance {
} ...FiatBalance_fiatBalance
balances { }
...Balances_balances balance {
...Balance_balance
}
} }
} }
`, `,
{} {}
); );
if (!isAuthenticated) return <Messages.Unauthenticated />; if (!isAuthenticated || !currentUser) return <Messages.Unauthenticated />;
return ( return (
<div className="flex flex-col h-full w-full overflow-x-hidden"> <div className="flex flex-col h-full w-full overflow-x-hidden">
<div className="container mx-auto px-4 sm:px-8 max-w-3xl"> <div className="container mx-auto px-4 sm:px-8 max-w-3xl">
<div className="py-8"> <div className="py-8">
<FiatBalances fiatBalancesRef={fiatBalances} /> <FiatBalance fiatBalancesRef={currentUser.fiatBalance} />
<Balances balancesRef={balances} /> <Balance balancesRef={currentUser.balance} />
</div> </div>
</div> </div>
</div> </div>

View File

@@ -0,0 +1,37 @@
/* tslint:disable */
/* eslint-disable */
// @ts-nocheck
import { ReaderFragment } from "relay-runtime";
import { FragmentRefs } from "relay-runtime";
export type Balance_balance = {
readonly amount: string;
readonly " $refType": "Balance_balance";
};
export type Balance_balance$data = Balance_balance;
export type Balance_balance$key = {
readonly " $data"?: Balance_balance$data;
readonly " $fragmentRefs": FragmentRefs<"Balance_balance">;
};
const node: ReaderFragment = {
"argumentDefinitions": [],
"kind": "Fragment",
"metadata": null,
"name": "Balance_balance",
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "amount",
"storageKey": null
}
],
"type": "Balance",
"abstractKey": null
};
(node as any).hash = '3f420063f1e6ebfcd91bd05b7bbb492a';
export default node;

View File

@@ -1,92 +0,0 @@
/* tslint:disable */
/* eslint-disable */
// @ts-nocheck
import { ReaderFragment } from "relay-runtime";
import { FragmentRefs } from "relay-runtime";
export type Balances_balances = {
readonly edges: ReadonlyArray<{
readonly node: {
readonly id: string;
readonly amount: string;
readonly currency: {
readonly name: string;
};
};
}>;
readonly " $refType": "Balances_balances";
};
export type Balances_balances$data = Balances_balances;
export type Balances_balances$key = {
readonly " $data"?: Balances_balances$data;
readonly " $fragmentRefs": FragmentRefs<"Balances_balances">;
};
const node: ReaderFragment = {
"argumentDefinitions": [],
"kind": "Fragment",
"metadata": null,
"name": "Balances_balances",
"selections": [
{
"alias": null,
"args": null,
"concreteType": "BalanceEdge",
"kind": "LinkedField",
"name": "edges",
"plural": true,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "Balance",
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "id",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "amount",
"storageKey": null
},
{
"alias": null,
"args": null,
"concreteType": "Currency",
"kind": "LinkedField",
"name": "currency",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "name",
"storageKey": null
}
],
"storageKey": null
}
],
"storageKey": null
}
],
"storageKey": null
}
],
"type": "BalanceConnection",
"abstractKey": null
};
(node as any).hash = 'f42e01739ec72a194e05843169435d96';
export default node;

View File

@@ -0,0 +1,45 @@
/* tslint:disable */
/* eslint-disable */
// @ts-nocheck
import { ReaderFragment } from "relay-runtime";
import { FragmentRefs } from "relay-runtime";
export type FiatBalance_fiatBalance = {
readonly amountCents: number;
readonly amountCurrency: string;
readonly " $refType": "FiatBalance_fiatBalance";
};
export type FiatBalance_fiatBalance$data = FiatBalance_fiatBalance;
export type FiatBalance_fiatBalance$key = {
readonly " $data"?: FiatBalance_fiatBalance$data;
readonly " $fragmentRefs": FragmentRefs<"FiatBalance_fiatBalance">;
};
const node: ReaderFragment = {
"argumentDefinitions": [],
"kind": "Fragment",
"metadata": null,
"name": "FiatBalance_fiatBalance",
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "amountCents",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "amountCurrency",
"storageKey": null
}
],
"type": "FiatBalance",
"abstractKey": null
};
(node as any).hash = 'dc28e4dca104c7d25465a30412661af2';
export default node;

View File

@@ -1,71 +0,0 @@
/* tslint:disable */
/* eslint-disable */
// @ts-nocheck
import { ReaderFragment } from "relay-runtime";
import { FragmentRefs } from "relay-runtime";
export type FiatBalances_fiatBalances = {
readonly edges: ReadonlyArray<{
readonly node: {
readonly amountCents: number;
readonly amountCurrency: string;
};
}>;
readonly " $refType": "FiatBalances_fiatBalances";
};
export type FiatBalances_fiatBalances$data = FiatBalances_fiatBalances;
export type FiatBalances_fiatBalances$key = {
readonly " $data"?: FiatBalances_fiatBalances$data;
readonly " $fragmentRefs": FragmentRefs<"FiatBalances_fiatBalances">;
};
const node: ReaderFragment = {
"argumentDefinitions": [],
"kind": "Fragment",
"metadata": null,
"name": "FiatBalances_fiatBalances",
"selections": [
{
"alias": null,
"args": null,
"concreteType": "FiatBalanceEdge",
"kind": "LinkedField",
"name": "edges",
"plural": true,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "FiatBalance",
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "amountCents",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "amountCurrency",
"storageKey": null
}
],
"storageKey": null
}
],
"storageKey": null
}
],
"type": "FiatBalanceConnection",
"abstractKey": null
};
(node as any).hash = 'a1454d1a8afc3cffb17cbfbe9e3555f7';
export default node;

View File

@@ -6,12 +6,14 @@ import { ConcreteRequest } from "relay-runtime";
import { FragmentRefs } from "relay-runtime"; import { FragmentRefs } from "relay-runtime";
export type WalletQueryVariables = {}; export type WalletQueryVariables = {};
export type WalletQueryResponse = { export type WalletQueryResponse = {
readonly fiatBalances: { readonly currentUser: {
readonly " $fragmentRefs": FragmentRefs<"FiatBalances_fiatBalances">; readonly fiatBalance: {
}; readonly " $fragmentRefs": FragmentRefs<"FiatBalance_fiatBalance">;
readonly balances: { };
readonly " $fragmentRefs": FragmentRefs<"Balances_balances">; readonly balance: {
}; readonly " $fragmentRefs": FragmentRefs<"Balance_balance">;
};
} | null;
}; };
export type WalletQuery = { export type WalletQuery = {
readonly response: WalletQueryResponse; readonly response: WalletQueryResponse;
@@ -22,35 +24,26 @@ export type WalletQuery = {
/* /*
query WalletQuery { query WalletQuery {
fiatBalances { currentUser {
...FiatBalances_fiatBalances fiatBalance {
} ...FiatBalance_fiatBalance
balances { id
...Balances_balances }
balance {
...Balance_balance
id
}
id
} }
} }
fragment Balances_balances on BalanceConnection { fragment Balance_balance on Balance {
edges { amount
node {
id
amount
currency {
name
id
}
}
}
} }
fragment FiatBalances_fiatBalances on FiatBalanceConnection { fragment FiatBalance_fiatBalance on FiatBalance {
edges { amountCents
node { amountCurrency
amountCents
amountCurrency
id
}
}
} }
*/ */
@@ -72,31 +65,42 @@ return {
{ {
"alias": null, "alias": null,
"args": null, "args": null,
"concreteType": "FiatBalanceConnection", "concreteType": "User",
"kind": "LinkedField", "kind": "LinkedField",
"name": "fiatBalances", "name": "currentUser",
"plural": false, "plural": false,
"selections": [ "selections": [
{ {
"alias": null,
"args": null, "args": null,
"kind": "FragmentSpread", "concreteType": "FiatBalance",
"name": "FiatBalances_fiatBalances" "kind": "LinkedField",
} "name": "fiatBalance",
], "plural": false,
"storageKey": null "selections": [
}, {
{ "args": null,
"alias": null, "kind": "FragmentSpread",
"args": null, "name": "FiatBalance_fiatBalance"
"concreteType": "BalanceConnection", }
"kind": "LinkedField", ],
"name": "balances", "storageKey": null
"plural": false, },
"selections": [
{ {
"alias": null,
"args": null, "args": null,
"kind": "FragmentSpread", "concreteType": "Balance",
"name": "Balances_balances" "kind": "LinkedField",
"name": "balance",
"plural": false,
"selections": [
{
"args": null,
"kind": "FragmentSpread",
"name": "Balance_balance"
}
],
"storageKey": null
} }
], ],
"storageKey": null "storageKey": null
@@ -114,122 +118,71 @@ return {
{ {
"alias": null, "alias": null,
"args": null, "args": null,
"concreteType": "FiatBalanceConnection", "concreteType": "User",
"kind": "LinkedField", "kind": "LinkedField",
"name": "fiatBalances", "name": "currentUser",
"plural": false, "plural": false,
"selections": [ "selections": [
{ {
"alias": null, "alias": null,
"args": null, "args": null,
"concreteType": "FiatBalanceEdge", "concreteType": "FiatBalance",
"kind": "LinkedField", "kind": "LinkedField",
"name": "edges", "name": "fiatBalance",
"plural": true, "plural": false,
"selections": [ "selections": [
{ {
"alias": null, "alias": null,
"args": null, "args": null,
"concreteType": "FiatBalance", "kind": "ScalarField",
"kind": "LinkedField", "name": "amountCents",
"name": "node",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "amountCents",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "amountCurrency",
"storageKey": null
},
(v0/*: any*/)
],
"storageKey": null "storageKey": null
} },
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "amountCurrency",
"storageKey": null
},
(v0/*: any*/)
], ],
"storageKey": null "storageKey": null
} },
],
"storageKey": null
},
{
"alias": null,
"args": null,
"concreteType": "BalanceConnection",
"kind": "LinkedField",
"name": "balances",
"plural": false,
"selections": [
{ {
"alias": null, "alias": null,
"args": null, "args": null,
"concreteType": "BalanceEdge", "concreteType": "Balance",
"kind": "LinkedField", "kind": "LinkedField",
"name": "edges", "name": "balance",
"plural": true, "plural": false,
"selections": [ "selections": [
{ {
"alias": null, "alias": null,
"args": null, "args": null,
"concreteType": "Balance", "kind": "ScalarField",
"kind": "LinkedField", "name": "amount",
"name": "node",
"plural": false,
"selections": [
(v0/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "amount",
"storageKey": null
},
{
"alias": null,
"args": null,
"concreteType": "Currency",
"kind": "LinkedField",
"name": "currency",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "name",
"storageKey": null
},
(v0/*: any*/)
],
"storageKey": null
}
],
"storageKey": null "storageKey": null
} },
(v0/*: any*/)
], ],
"storageKey": null "storageKey": null
} },
(v0/*: any*/)
], ],
"storageKey": null "storageKey": null
} }
] ]
}, },
"params": { "params": {
"cacheID": "6acfc80d1e8d7c882a03e25cc7902d72", "cacheID": "d0537f2712255befa46df80db6c7246b",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "WalletQuery", "name": "WalletQuery",
"operationKind": "query", "operationKind": "query",
"text": "query WalletQuery {\n fiatBalances {\n ...FiatBalances_fiatBalances\n }\n balances {\n ...Balances_balances\n }\n}\n\nfragment Balances_balances on BalanceConnection {\n edges {\n node {\n id\n amount\n currency {\n name\n id\n }\n }\n }\n}\n\nfragment FiatBalances_fiatBalances on FiatBalanceConnection {\n edges {\n node {\n amountCents\n amountCurrency\n id\n }\n }\n}\n" "text": "query WalletQuery {\n currentUser {\n fiatBalance {\n ...FiatBalance_fiatBalance\n id\n }\n balance {\n ...Balance_balance\n id\n }\n id\n }\n}\n\nfragment Balance_balance on Balance {\n amount\n}\n\nfragment FiatBalance_fiatBalance on FiatBalance {\n amountCents\n amountCurrency\n}\n"
} }
}; };
})(); })();
(node as any).hash = '855efce679c691a77938b64376a1a805'; (node as any).hash = '61fbc56a1e87c83a8a0a4460c231be53';
export default node; export default node;

View File

@@ -4,28 +4,24 @@
# #
# Table name: balances # Table name: balances
# #
# id :bigint not null, primary key # id :bigint not null, primary key
# amount :decimal(20, 10) default(0.0), not null # amount :decimal(20, 10) default(0.0), not null
# created_at :datetime not null # created_at :datetime not null
# updated_at :datetime not null # updated_at :datetime not null
# currency_id :bigint not null # user_id :bigint not null
# user_id :bigint not null
# #
# Indexes # Indexes
# #
# index_balances_on_currency_id (currency_id) # index_balances_on_user_id (user_id)
# index_balances_on_user_id (user_id)
# #
# Foreign Keys # Foreign Keys
# #
# fk_rails_... (currency_id => currencies.id)
# fk_rails_... (user_id => users.id) # fk_rails_... (user_id => users.id)
# #
class Balance < ApplicationRecord class Balance < ApplicationRecord
include Trackable include Trackable
belongs_to :user belongs_to :user
belongs_to :currency
validates :amount, presence: true, numericality: { greater_than_or_equal_to: 0 } validates :amount, presence: true, numericality: { greater_than_or_equal_to: 0 }

View File

@@ -10,17 +10,14 @@
# status :string not null # status :string not null
# created_at :datetime not null # created_at :datetime not null
# updated_at :datetime not null # updated_at :datetime not null
# currency_id :bigint not null
# user_id :bigint not null # user_id :bigint not null
# #
# Indexes # Indexes
# #
# index_buy_crypto_orders_on_currency_id (currency_id) # index_buy_crypto_orders_on_user_id (user_id)
# index_buy_crypto_orders_on_user_id (user_id)
# #
# Foreign Keys # Foreign Keys
# #
# fk_rails_... (currency_id => currencies.id)
# fk_rails_... (user_id => users.id) # fk_rails_... (user_id => users.id)
# #
class BuyCryptoOrder < ApplicationRecord class BuyCryptoOrder < ApplicationRecord
@@ -28,7 +25,6 @@ class BuyCryptoOrder < ApplicationRecord
include Notifiable include Notifiable
belongs_to :user belongs_to :user
belongs_to :currency
monetize :paid_amount_cents monetize :paid_amount_cents

View File

@@ -1,14 +0,0 @@
# frozen_string_literal: true
# == Schema Information
#
# Table name: currencies
#
# id :bigint not null, primary key
# name :string not null
# created_at :datetime not null
# updated_at :datetime not null
#
class Currency < ApplicationRecord
validates :name, presence: true
end

View File

@@ -10,17 +10,14 @@
# status :string not null # status :string not null
# created_at :datetime not null # created_at :datetime not null
# updated_at :datetime not null # updated_at :datetime not null
# currency_id :bigint not null
# user_id :bigint not null # user_id :bigint not null
# #
# Indexes # Indexes
# #
# index_sell_crypto_orders_on_currency_id (currency_id) # index_sell_crypto_orders_on_user_id (user_id)
# index_sell_crypto_orders_on_user_id (user_id)
# #
# Foreign Keys # Foreign Keys
# #
# fk_rails_... (currency_id => currencies.id)
# fk_rails_... (user_id => users.id) # fk_rails_... (user_id => users.id)
# #
class SellCryptoOrder < ApplicationRecord class SellCryptoOrder < ApplicationRecord
@@ -28,7 +25,6 @@ class SellCryptoOrder < ApplicationRecord
include Notifiable include Notifiable
belongs_to :user belongs_to :user
belongs_to :currency
monetize :received_amount_cents monetize :received_amount_cents
@@ -41,7 +37,7 @@ class SellCryptoOrder < ApplicationRecord
" "
💸 New sell crypto order! 💸\n 💸 New sell crypto order! 💸\n
user: #{user.email} \n user: #{user.email} \n
amount: #{paid_amount} #{currency.name} amount: #{paid_amount} CAKE
" "
end end
end end

View File

@@ -4,23 +4,20 @@
# #
# Table name: stake_orders # Table name: stake_orders
# #
# id :bigint not null, primary key # id :bigint not null, primary key
# amount :decimal(20, 10) default(0.0), not null # amount :decimal(20, 10) default(0.0), not null
# pool_name :string not null # pool_name :string not null
# status :string not null # status :string not null
# created_at :datetime not null # created_at :datetime not null
# updated_at :datetime not null # updated_at :datetime not null
# currency_id :bigint # user_id :bigint not null
# user_id :bigint not null
# #
# Indexes # Indexes
# #
# index_stake_orders_on_currency_id (currency_id) # index_stake_orders_on_user_id (user_id)
# index_stake_orders_on_user_id (user_id)
# #
# Foreign Keys # Foreign Keys
# #
# fk_rails_... (currency_id => currencies.id)
# fk_rails_... (user_id => users.id) # fk_rails_... (user_id => users.id)
# #
class StakeOrder < ApplicationRecord class StakeOrder < ApplicationRecord
@@ -28,7 +25,6 @@ class StakeOrder < ApplicationRecord
include Notifiable include Notifiable
belongs_to :user belongs_to :user
belongs_to :currency
validates :pool_name, presence: true validates :pool_name, presence: true
validates :amount, presence: true validates :amount, presence: true

View File

@@ -29,7 +29,7 @@ class User < ApplicationRecord
has_many :documents, class_name: "UserDocument", dependent: :destroy has_many :documents, class_name: "UserDocument", dependent: :destroy
has_many :stake_orders, dependent: :restrict_with_error has_many :stake_orders, dependent: :restrict_with_error
has_many :balances, dependent: :restrict_with_error has_one :balance, dependent: :restrict_with_error
has_one :fiat_balance, dependent: :restrict_with_error has_one :fiat_balance, dependent: :restrict_with_error
validates :first_name, :last_name, :email, presence: true validates :first_name, :last_name, :email, presence: true

View File

@@ -24,13 +24,8 @@ class CreateUserBalances
end end
def create_balances def create_balances
Currency.in_batches.each do |relation| Balance.find_or_create_by(
relation.each do |currency| user_id: user.id
Balance.find_or_create_by( )
user_id: user.id,
currency_id: currency.id,
)
end
end
end end
end end

View File

@@ -9,10 +9,6 @@ pt-BR:
one: Administrador one: Administrador
other: Administradores other: Administradores
currency:
one: Moeda
other: Moedas
balance: balance:
one: Saldo one: Saldo
other: Saldos other: Saldos
@@ -46,9 +42,6 @@ pt-BR:
amount_formatted: Quantia amount_formatted: Quantia
amount_cents: Quantia amount_cents: Quantia
currency:
name: Nome
errors: errors:
models: models:
balance: balance:

View File

@@ -0,0 +1,11 @@
# frozen_string_literal: true
class DropCurrency < ActiveRecord::Migration[6.1]
def up
remove_reference(:balances, :currency, index: true, foreign_key: true)
remove_reference(:buy_crypto_orders, :currency, index: true, foreign_key: true)
remove_reference(:sell_crypto_orders, :currency, index: true, foreign_key: true)
remove_reference(:stake_orders, :currency, index: true, foreign_key: true)
drop_table(:currencies)
end
end

20
db/schema.rb generated
View File

@@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2021_08_18_185019) do ActiveRecord::Schema.define(version: 2021_08_28_041104) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
@@ -57,32 +57,22 @@ ActiveRecord::Schema.define(version: 2021_08_18_185019) do
create_table "balances", force: :cascade do |t| create_table "balances", force: :cascade do |t|
t.bigint "user_id", null: false t.bigint "user_id", null: false
t.bigint "currency_id", null: false
t.decimal "amount", precision: 20, scale: 10, default: "0.0", null: false t.decimal "amount", precision: 20, scale: 10, default: "0.0", null: false
t.datetime "created_at", precision: 6, null: false t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false
t.index ["currency_id"], name: "index_balances_on_currency_id"
t.index ["user_id"], name: "index_balances_on_user_id" t.index ["user_id"], name: "index_balances_on_user_id"
end end
create_table "buy_crypto_orders", force: :cascade do |t| create_table "buy_crypto_orders", force: :cascade do |t|
t.bigint "user_id", null: false t.bigint "user_id", null: false
t.bigint "currency_id", null: false
t.string "status", null: false t.string "status", null: false
t.integer "paid_amount_cents", default: 0, null: false t.integer "paid_amount_cents", default: 0, null: false
t.decimal "received_amount", precision: 20, scale: 10, default: "0.0", null: false t.decimal "received_amount", precision: 20, scale: 10, default: "0.0", null: false
t.datetime "created_at", precision: 6, null: false t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false
t.index ["currency_id"], name: "index_buy_crypto_orders_on_currency_id"
t.index ["user_id"], name: "index_buy_crypto_orders_on_user_id" t.index ["user_id"], name: "index_buy_crypto_orders_on_user_id"
end end
create_table "currencies", force: :cascade do |t|
t.string "name", null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
create_table "fiat_balances", force: :cascade do |t| create_table "fiat_balances", force: :cascade do |t|
t.bigint "user_id", null: false t.bigint "user_id", null: false
t.integer "amount_cents", default: 0, null: false t.integer "amount_cents", default: 0, null: false
@@ -94,13 +84,11 @@ ActiveRecord::Schema.define(version: 2021_08_18_185019) do
create_table "sell_crypto_orders", force: :cascade do |t| create_table "sell_crypto_orders", force: :cascade do |t|
t.bigint "user_id", null: false t.bigint "user_id", null: false
t.bigint "currency_id", null: false
t.string "status", null: false t.string "status", null: false
t.decimal "paid_amount", precision: 20, scale: 10, default: "0.0", null: false t.decimal "paid_amount", precision: 20, scale: 10, default: "0.0", null: false
t.integer "received_amount_cents", default: 0, null: false t.integer "received_amount_cents", default: 0, null: false
t.datetime "created_at", precision: 6, null: false t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false
t.index ["currency_id"], name: "index_sell_crypto_orders_on_currency_id"
t.index ["user_id"], name: "index_sell_crypto_orders_on_user_id" t.index ["user_id"], name: "index_sell_crypto_orders_on_user_id"
end end
@@ -111,8 +99,6 @@ ActiveRecord::Schema.define(version: 2021_08_18_185019) do
t.decimal "amount", precision: 20, scale: 10, default: "0.0", null: false t.decimal "amount", precision: 20, scale: 10, default: "0.0", null: false
t.datetime "created_at", precision: 6, null: false t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false
t.bigint "currency_id"
t.index ["currency_id"], name: "index_stake_orders_on_currency_id"
t.index ["user_id"], name: "index_stake_orders_on_user_id" t.index ["user_id"], name: "index_stake_orders_on_user_id"
end end
@@ -151,14 +137,10 @@ ActiveRecord::Schema.define(version: 2021_08_18_185019) do
add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id" add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id" add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id"
add_foreign_key "balances", "currencies"
add_foreign_key "balances", "users" add_foreign_key "balances", "users"
add_foreign_key "buy_crypto_orders", "currencies"
add_foreign_key "buy_crypto_orders", "users" add_foreign_key "buy_crypto_orders", "users"
add_foreign_key "fiat_balances", "users" add_foreign_key "fiat_balances", "users"
add_foreign_key "sell_crypto_orders", "currencies"
add_foreign_key "sell_crypto_orders", "users" add_foreign_key "sell_crypto_orders", "users"
add_foreign_key "stake_orders", "currencies"
add_foreign_key "stake_orders", "users" add_foreign_key "stake_orders", "users"
add_foreign_key "user_documents", "users" add_foreign_key "user_documents", "users"
end end

View File

@@ -2,8 +2,6 @@
AdminUser.create!(email: "admin@example.com", password: "password") AdminUser.create!(email: "admin@example.com", password: "password")
Currency.create!(name: "CAKE")
User.create!( User.create!(
first_name: "Test", first_name: "Test",
last_name: "User", last_name: "User",

294
erd.svg
View File

@@ -4,222 +4,180 @@
<!-- Generated by graphviz version 2.48.0 (0) <!-- Generated by graphviz version 2.48.0 (0)
--> -->
<!-- Title: XStake Pages: 1 --> <!-- Title: XStake Pages: 1 -->
<svg width="606pt" height="724pt" <svg width="606pt" height="674pt"
viewBox="0.00 0.00 605.60 724.10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> viewBox="0.00 0.00 605.60 673.60" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(28.8 695.3)"> <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(28.8 644.8)">
<title>XStake</title> <title>XStake</title>
<polygon fill="white" stroke="transparent" points="-28.8,28.8 -28.8,-695.3 576.8,-695.3 576.8,28.8 -28.8,28.8"/> <polygon fill="white" stroke="transparent" points="-28.8,28.8 -28.8,-644.8 576.8,-644.8 576.8,28.8 -28.8,28.8"/>
<text text-anchor="middle" x="274" y="-652.1" font-family="Arial Bold" font-size="13.00">XStake domain model</text> <text text-anchor="middle" x="274" y="-601.6" font-family="Arial Bold" font-size="13.00">XStake domain model</text>
<!-- m_AdminUser --> <!-- m_AdminUser -->
<g id="node1" class="node"> <g id="node1" class="node">
<title>m_AdminUser</title> <title>m_AdminUser</title>
<path fill="none" stroke="black" d="M12,-40C12,-40 150,-40 150,-40 156,-40 162,-46 162,-52 162,-52 162,-123 162,-123 162,-129 156,-135 150,-135 150,-135 12,-135 12,-135 6,-135 0,-129 0,-123 0,-123 0,-52 0,-52 0,-46 6,-40 12,-40"/> <path fill="none" stroke="black" d="M12,-100C12,-100 150,-100 150,-100 156,-100 162,-106 162,-112 162,-112 162,-183 162,-183 162,-189 156,-195 150,-195 150,-195 12,-195 12,-195 6,-195 0,-189 0,-183 0,-183 0,-112 0,-112 0,-106 6,-100 12,-100"/>
<text text-anchor="start" x="49" y="-122.2" font-family="Arial Bold" font-size="11.00">AdminUser</text> <text text-anchor="start" x="49" y="-182.2" font-family="Arial Bold" font-size="11.00">AdminUser</text>
<polyline fill="none" stroke="black" points="0,-115 162,-115 "/> <polyline fill="none" stroke="black" points="0,-175 162,-175 "/>
<text text-anchor="start" x="7" y="-101.5" font-family="Arial" font-size="10.00">email </text> <text text-anchor="start" x="7" y="-161.5" font-family="Arial" font-size="10.00">email </text>
<text text-anchor="start" x="34" y="-101.5" font-family="Arial Italic" font-size="10.00" fill="#999999">string U</text> <text text-anchor="start" x="34" y="-161.5" font-family="Arial Italic" font-size="10.00" fill="#999999">string U</text>
<text text-anchor="start" x="7" y="-88.5" font-family="Arial" font-size="10.00">encrypted_password </text> <text text-anchor="start" x="7" y="-148.5" font-family="Arial" font-size="10.00">encrypted_password </text>
<text text-anchor="start" x="101" y="-88.5" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text> <text text-anchor="start" x="101" y="-148.5" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text>
<text text-anchor="start" x="7" y="-75.5" font-family="Arial" font-size="10.00">remember_created_at </text> <text text-anchor="start" x="7" y="-135.5" font-family="Arial" font-size="10.00">remember_created_at </text>
<text text-anchor="start" x="105" y="-75.5" font-family="Arial Italic" font-size="10.00" fill="#999999">datetime</text> <text text-anchor="start" x="105" y="-135.5" font-family="Arial Italic" font-size="10.00" fill="#999999">datetime</text>
<text text-anchor="start" x="7" y="-62.5" font-family="Arial" font-size="10.00">reset_password_sent_at </text> <text text-anchor="start" x="7" y="-122.5" font-family="Arial" font-size="10.00">reset_password_sent_at </text>
<text text-anchor="start" x="117" y="-62.5" font-family="Arial Italic" font-size="10.00" fill="#999999">datetime</text> <text text-anchor="start" x="117" y="-122.5" font-family="Arial Italic" font-size="10.00" fill="#999999">datetime</text>
<text text-anchor="start" x="7" y="-49.5" font-family="Arial" font-size="10.00">reset_password_token </text> <text text-anchor="start" x="7" y="-109.5" font-family="Arial" font-size="10.00">reset_password_token </text>
<text text-anchor="start" x="109" y="-49.5" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text> <text text-anchor="start" x="109" y="-109.5" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text>
</g> </g>
<!-- m_Balance --> <!-- m_Balance -->
<g id="node2" class="node"> <g id="node2" class="node">
<title>m_Balance</title> <title>m_Balance</title>
<path fill="none" stroke="black" d="M223,-560C223,-560 343,-560 343,-560 349,-560 355,-566 355,-572 355,-572 355,-617 355,-617 355,-623 349,-629 343,-629 343,-629 223,-629 223,-629 217,-629 211,-623 211,-617 211,-617 211,-572 211,-572 211,-566 217,-560 223,-560"/> <path fill="none" stroke="black" d="M223,-522.5C223,-522.5 343,-522.5 343,-522.5 349,-522.5 355,-528.5 355,-534.5 355,-534.5 355,-566.5 355,-566.5 355,-572.5 349,-578.5 343,-578.5 343,-578.5 223,-578.5 223,-578.5 217,-578.5 211,-572.5 211,-566.5 211,-566.5 211,-534.5 211,-534.5 211,-528.5 217,-522.5 223,-522.5"/>
<text text-anchor="start" x="259.5" y="-616.2" font-family="Arial Bold" font-size="11.00">Balance</text> <text text-anchor="start" x="259.5" y="-565.7" font-family="Arial Bold" font-size="11.00">Balance</text>
<polyline fill="none" stroke="black" points="211,-609 355,-609 "/> <polyline fill="none" stroke="black" points="211,-558.5 355,-558.5 "/>
<text text-anchor="start" x="218" y="-595.5" font-family="Arial" font-size="10.00">amount </text> <text text-anchor="start" x="218" y="-545.5" font-family="Arial" font-size="10.00">amount </text>
<text text-anchor="start" x="254" y="-595.5" font-family="Arial Italic" font-size="10.00" fill="#999999">decimal (20,10)</text> <text text-anchor="start" x="254" y="-545.5" font-family="Arial Italic" font-size="10.00" fill="#999999">decimal (20,10)</text>
<text text-anchor="start" x="218" y="-582.5" font-family="Arial" font-size="10.00">currency_id </text> <text text-anchor="start" x="218" y="-532.5" font-family="Arial" font-size="10.00">user_id </text>
<text text-anchor="start" x="272" y="-582.5" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) FK</text> <text text-anchor="start" x="253" y="-532.5" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) FK</text>
<text text-anchor="start" x="218" y="-569.5" font-family="Arial" font-size="10.00">user_id </text>
<text text-anchor="start" x="253" y="-569.5" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) FK</text>
</g> </g>
<!-- m_PaperTrail::Version --> <!-- m_PaperTrail::Version -->
<g id="node6" class="node"> <g id="node5" class="node">
<title>m_PaperTrail::Version</title> <title>m_PaperTrail::Version</title>
<path fill="none" stroke="black" d="M416,-310C416,-310 536,-310 536,-310 542,-310 548,-316 548,-322 548,-322 548,-393 548,-393 548,-399 542,-405 536,-405 536,-405 416,-405 416,-405 410,-405 404,-399 404,-393 404,-393 404,-322 404,-322 404,-316 410,-310 416,-310"/> <path fill="none" stroke="black" d="M416,-400C416,-400 536,-400 536,-400 542,-400 548,-406 548,-412 548,-412 548,-483 548,-483 548,-489 542,-495 536,-495 536,-495 416,-495 416,-495 410,-495 404,-489 404,-483 404,-483 404,-412 404,-412 404,-406 410,-400 416,-400"/>
<text text-anchor="start" x="423.5" y="-392.2" font-family="Arial Bold" font-size="11.00">PaperTrail::Version</text> <text text-anchor="start" x="423.5" y="-482.2" font-family="Arial Bold" font-size="11.00">PaperTrail::Version</text>
<polyline fill="none" stroke="black" points="404,-385 548,-385 "/> <polyline fill="none" stroke="black" points="404,-475 548,-475 "/>
<text text-anchor="start" x="411" y="-371.5" font-family="Arial" font-size="10.00">event </text> <text text-anchor="start" x="411" y="-461.5" font-family="Arial" font-size="10.00">event </text>
<text text-anchor="start" x="439" y="-371.5" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text> <text text-anchor="start" x="439" y="-461.5" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text>
<text text-anchor="start" x="411" y="-358.5" font-family="Arial" font-size="10.00">item_id </text> <text text-anchor="start" x="411" y="-448.5" font-family="Arial" font-size="10.00">item_id </text>
<text text-anchor="start" x="446" y="-358.5" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) FK</text> <text text-anchor="start" x="446" y="-448.5" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) FK</text>
<text text-anchor="start" x="411" y="-345.5" font-family="Arial" font-size="10.00">item_type </text> <text text-anchor="start" x="411" y="-435.5" font-family="Arial" font-size="10.00">item_type </text>
<text text-anchor="start" x="457" y="-345.5" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text> <text text-anchor="start" x="457" y="-435.5" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text>
<text text-anchor="start" x="411" y="-332.5" font-family="Arial" font-size="10.00">object </text> <text text-anchor="start" x="411" y="-422.5" font-family="Arial" font-size="10.00">object </text>
<text text-anchor="start" x="441" y="-332.5" font-family="Arial Italic" font-size="10.00" fill="#999999">text</text> <text text-anchor="start" x="441" y="-422.5" font-family="Arial Italic" font-size="10.00" fill="#999999">text</text>
<text text-anchor="start" x="411" y="-319.5" font-family="Arial" font-size="10.00">whodunnit </text> <text text-anchor="start" x="411" y="-409.5" font-family="Arial" font-size="10.00">whodunnit </text>
<text text-anchor="start" x="459" y="-319.5" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text> <text text-anchor="start" x="459" y="-409.5" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text>
</g> </g>
<!-- m_Balance&#45;&gt;m_PaperTrail::Version --> <!-- m_Balance&#45;&gt;m_PaperTrail::Version -->
<g id="edge1" class="edge"> <g id="edge1" class="edge">
<title>m_Balance&#45;&gt;m_PaperTrail::Version</title> <title>m_Balance&#45;&gt;m_PaperTrail::Version</title>
<path fill="none" stroke="black" d="M351.08,-559.9C357.13,-555.47 362.89,-550.66 368,-545.5 405.48,-507.62 434.29,-453.96 452.52,-413.67"/> <path fill="none" stroke="black" d="M339.73,-522.35C349.2,-517.46 358.9,-512.38 368,-507.5 377,-502.67 386.38,-497.55 395.69,-492.41"/>
<polygon fill="black" stroke="black" points="455.47,-414.78 456.25,-405.28 449.71,-412.22 455.47,-414.78"/> <polygon fill="black" stroke="black" points="397.49,-495.02 403.84,-487.9 394.44,-489.5 397.49,-495.02"/>
</g> </g>
<!-- m_BuyCryptoOrder --> <!-- m_BuyCryptoOrder -->
<g id="node3" class="node"> <g id="node3" class="node">
<title>m_BuyCryptoOrder</title> <title>m_BuyCryptoOrder</title>
<path fill="none" stroke="black" d="M210,-435C210,-435 356,-435 356,-435 362,-435 368,-441 368,-447 368,-447 368,-518 368,-518 368,-524 362,-530 356,-530 356,-530 210,-530 210,-530 204,-530 198,-524 198,-518 198,-518 198,-447 198,-447 198,-441 204,-435 210,-435"/> <path fill="none" stroke="black" d="M210,-410.5C210,-410.5 356,-410.5 356,-410.5 362,-410.5 368,-416.5 368,-422.5 368,-422.5 368,-480.5 368,-480.5 368,-486.5 362,-492.5 356,-492.5 356,-492.5 210,-492.5 210,-492.5 204,-492.5 198,-486.5 198,-480.5 198,-480.5 198,-422.5 198,-422.5 198,-416.5 204,-410.5 210,-410.5"/>
<text text-anchor="start" x="237" y="-517.2" font-family="Arial Bold" font-size="11.00">BuyCryptoOrder</text> <text text-anchor="start" x="237" y="-479.7" font-family="Arial Bold" font-size="11.00">BuyCryptoOrder</text>
<polyline fill="none" stroke="black" points="198,-510 368,-510 "/> <polyline fill="none" stroke="black" points="198,-472.5 368,-472.5 "/>
<text text-anchor="start" x="205" y="-496.5" font-family="Arial" font-size="10.00">currency_id </text> <text text-anchor="start" x="205" y="-459.5" font-family="Arial" font-size="10.00">paid_amount_cents </text>
<text text-anchor="start" x="259" y="-496.5" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) FK</text> <text text-anchor="start" x="293" y="-459.5" font-family="Arial Italic" font-size="10.00" fill="#999999">integer</text>
<text text-anchor="start" x="205" y="-483.5" font-family="Arial" font-size="10.00">paid_amount_cents </text> <text text-anchor="start" x="205" y="-446.5" font-family="Arial" font-size="10.00">received_amount </text>
<text text-anchor="start" x="293" y="-483.5" font-family="Arial Italic" font-size="10.00" fill="#999999">integer</text> <text text-anchor="start" x="283" y="-446.5" font-family="Arial Italic" font-size="10.00" fill="#999999">decimal (20,10)</text>
<text text-anchor="start" x="205" y="-470.5" font-family="Arial" font-size="10.00">received_amount </text> <text text-anchor="start" x="205" y="-433.5" font-family="Arial" font-size="10.00">status </text>
<text text-anchor="start" x="283" y="-470.5" font-family="Arial Italic" font-size="10.00" fill="#999999">decimal (20,10)</text> <text text-anchor="start" x="236" y="-433.5" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text>
<text text-anchor="start" x="205" y="-457.5" font-family="Arial" font-size="10.00">status </text> <text text-anchor="start" x="205" y="-420.5" font-family="Arial" font-size="10.00">user_id </text>
<text text-anchor="start" x="236" y="-457.5" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text> <text text-anchor="start" x="240" y="-420.5" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) FK</text>
<text text-anchor="start" x="205" y="-444.5" font-family="Arial" font-size="10.00">user_id </text>
<text text-anchor="start" x="240" y="-444.5" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) FK</text>
</g>
<!-- m_Currency -->
<g id="node4" class="node">
<title>m_Currency</title>
<path fill="none" stroke="black" d="M21,-398C21,-398 141,-398 141,-398 147,-398 153,-404 153,-410 153,-410 153,-429 153,-429 153,-435 147,-441 141,-441 141,-441 21,-441 21,-441 15,-441 9,-435 9,-429 9,-429 9,-410 9,-410 9,-404 15,-398 21,-398"/>
<text text-anchor="start" x="54.5" y="-428.2" font-family="Arial Bold" font-size="11.00">Currency</text>
<polyline fill="none" stroke="black" points="9,-421 153,-421 "/>
<text text-anchor="start" x="16" y="-407.5" font-family="Arial" font-size="10.00">name </text>
<text text-anchor="start" x="44" y="-407.5" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text>
</g>
<!-- m_Currency&#45;&gt;m_Balance -->
<g id="edge11" class="edge">
<title>m_Currency&#45;&gt;m_Balance</title>
<path fill="none" stroke="black" d="M98.77,-441.41C119.93,-468.12 158.38,-513.63 198,-545.5 201.86,-548.61 205.95,-551.65 210.15,-554.6"/>
<polygon fill="black" stroke="black" points="208.6,-557.35 217.82,-559.79 212.14,-552.14 208.6,-557.35"/>
</g>
<!-- m_Currency&#45;&gt;m_BuyCryptoOrder -->
<g id="edge8" class="edge">
<title>m_Currency&#45;&gt;m_BuyCryptoOrder</title>
<path fill="none" stroke="black" d="M150.27,-441C162.68,-444.91 175.82,-449.05 188.81,-453.14"/>
<polygon fill="black" stroke="black" points="188.23,-456.27 197.76,-455.97 190.13,-450.26 188.23,-456.27"/>
</g>
<!-- m_SellCryptoOrder -->
<g id="node7" class="node">
<title>m_SellCryptoOrder</title>
<path fill="none" stroke="black" d="M214.5,-310C214.5,-310 351.5,-310 351.5,-310 357.5,-310 363.5,-316 363.5,-322 363.5,-322 363.5,-393 363.5,-393 363.5,-399 357.5,-405 351.5,-405 351.5,-405 214.5,-405 214.5,-405 208.5,-405 202.5,-399 202.5,-393 202.5,-393 202.5,-322 202.5,-322 202.5,-316 208.5,-310 214.5,-310"/>
<text text-anchor="start" x="238" y="-392.2" font-family="Arial Bold" font-size="11.00">SellCryptoOrder</text>
<polyline fill="none" stroke="black" points="202.5,-385 363.5,-385 "/>
<text text-anchor="start" x="210" y="-371.5" font-family="Arial" font-size="10.00">currency_id </text>
<text text-anchor="start" x="264" y="-371.5" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) FK</text>
<text text-anchor="start" x="210" y="-358.5" font-family="Arial" font-size="10.00">paid_amount </text>
<text text-anchor="start" x="269" y="-358.5" font-family="Arial Italic" font-size="10.00" fill="#999999">decimal (20,10)</text>
<text text-anchor="start" x="210" y="-345.5" font-family="Arial" font-size="10.00">received_amount_cents </text>
<text text-anchor="start" x="317" y="-345.5" font-family="Arial Italic" font-size="10.00" fill="#999999">integer</text>
<text text-anchor="start" x="210" y="-332.5" font-family="Arial" font-size="10.00">status </text>
<text text-anchor="start" x="241" y="-332.5" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text>
<text text-anchor="start" x="210" y="-319.5" font-family="Arial" font-size="10.00">user_id </text>
<text text-anchor="start" x="245" y="-319.5" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) FK</text>
</g>
<!-- m_Currency&#45;&gt;m_SellCryptoOrder -->
<g id="edge10" class="edge">
<title>m_Currency&#45;&gt;m_SellCryptoOrder</title>
<path fill="none" stroke="black" d="M151.39,-397.99C165.03,-393.76 179.51,-389.27 193.68,-384.88"/>
<polygon fill="black" stroke="black" points="194.78,-387.84 202.45,-382.16 192.92,-381.82 194.78,-387.84"/>
</g>
<!-- m_StakeOrder -->
<g id="node8" class="node">
<title>m_StakeOrder</title>
<path fill="none" stroke="black" d="M223,-185C223,-185 343,-185 343,-185 349,-185 355,-191 355,-197 355,-197 355,-268 355,-268 355,-274 349,-280 343,-280 343,-280 223,-280 223,-280 217,-280 211,-274 211,-268 211,-268 211,-197 211,-197 211,-191 217,-185 223,-185"/>
<text text-anchor="start" x="251" y="-267.2" font-family="Arial Bold" font-size="11.00">StakeOrder</text>
<polyline fill="none" stroke="black" points="211,-260 355,-260 "/>
<text text-anchor="start" x="218" y="-246.5" font-family="Arial" font-size="10.00">amount </text>
<text text-anchor="start" x="254" y="-246.5" font-family="Arial Italic" font-size="10.00" fill="#999999">decimal (20,10)</text>
<text text-anchor="start" x="218" y="-233.5" font-family="Arial" font-size="10.00">currency_id </text>
<text text-anchor="start" x="272" y="-233.5" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) FK</text>
<text text-anchor="start" x="218" y="-220.5" font-family="Arial" font-size="10.00">pool_name </text>
<text text-anchor="start" x="269" y="-220.5" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text>
<text text-anchor="start" x="218" y="-207.5" font-family="Arial" font-size="10.00">status </text>
<text text-anchor="start" x="249" y="-207.5" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text>
<text text-anchor="start" x="218" y="-194.5" font-family="Arial" font-size="10.00">user_id </text>
<text text-anchor="start" x="253" y="-194.5" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) FK</text>
</g>
<!-- m_Currency&#45;&gt;m_StakeOrder -->
<g id="edge12" class="edge">
<title>m_Currency&#45;&gt;m_StakeOrder</title>
<path fill="none" stroke="black" d="M100.24,-397.8C122.24,-372.15 160.91,-328.76 198,-295.5 201.47,-292.38 205.09,-289.26 208.79,-286.17"/>
<polygon fill="black" stroke="black" points="211.04,-288.4 215.99,-280.25 207.04,-283.53 211.04,-288.4"/>
</g> </g>
<!-- m_FiatBalance --> <!-- m_FiatBalance -->
<g id="node5" class="node"> <g id="node4" class="node">
<title>m_FiatBalance</title> <title>m_FiatBalance</title>
<path fill="none" stroke="black" d="M223,-86C223,-86 343,-86 343,-86 349,-86 355,-92 355,-98 355,-98 355,-143 355,-143 355,-149 349,-155 343,-155 343,-155 223,-155 223,-155 217,-155 211,-149 211,-143 211,-143 211,-98 211,-98 211,-92 217,-86 223,-86"/> <path fill="none" stroke="black" d="M223,-311C223,-311 343,-311 343,-311 349,-311 355,-317 355,-323 355,-323 355,-368 355,-368 355,-374 349,-380 343,-380 343,-380 223,-380 223,-380 217,-380 211,-374 211,-368 211,-368 211,-323 211,-323 211,-317 217,-311 223,-311"/>
<text text-anchor="start" x="250" y="-142.2" font-family="Arial Bold" font-size="11.00">FiatBalance</text> <text text-anchor="start" x="250" y="-367.2" font-family="Arial Bold" font-size="11.00">FiatBalance</text>
<polyline fill="none" stroke="black" points="211,-135 355,-135 "/> <polyline fill="none" stroke="black" points="211,-360 355,-360 "/>
<text text-anchor="start" x="218" y="-121.5" font-family="Arial" font-size="10.00">amount_cents </text> <text text-anchor="start" x="218" y="-346.5" font-family="Arial" font-size="10.00">amount_cents </text>
<text text-anchor="start" x="283" y="-121.5" font-family="Arial Italic" font-size="10.00" fill="#999999">integer</text> <text text-anchor="start" x="283" y="-346.5" font-family="Arial Italic" font-size="10.00" fill="#999999">integer</text>
<text text-anchor="start" x="218" y="-108.5" font-family="Arial" font-size="10.00">amount_currency </text> <text text-anchor="start" x="218" y="-333.5" font-family="Arial" font-size="10.00">amount_currency </text>
<text text-anchor="start" x="297" y="-108.5" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text> <text text-anchor="start" x="297" y="-333.5" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text>
<text text-anchor="start" x="218" y="-95.5" font-family="Arial" font-size="10.00">user_id </text> <text text-anchor="start" x="218" y="-320.5" font-family="Arial" font-size="10.00">user_id </text>
<text text-anchor="start" x="253" y="-95.5" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) FK</text> <text text-anchor="start" x="253" y="-320.5" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) FK</text>
</g> </g>
<!-- m_FiatBalance&#45;&gt;m_PaperTrail::Version --> <!-- m_FiatBalance&#45;&gt;m_PaperTrail::Version -->
<g id="edge2" class="edge"> <g id="edge2" class="edge">
<title>m_FiatBalance&#45;&gt;m_PaperTrail::Version</title> <title>m_FiatBalance&#45;&gt;m_PaperTrail::Version</title>
<path fill="none" stroke="black" d="M351.08,-155.1C357.13,-159.53 362.89,-164.34 368,-169.5 405.48,-207.38 434.29,-261.04 452.52,-301.33"/> <path fill="none" stroke="black" d="M348.66,-380.03C363.78,-388.1 380.05,-396.79 395.72,-405.16"/>
<polygon fill="black" stroke="black" points="449.71,-302.78 456.25,-309.72 455.47,-300.22 449.71,-302.78"/> <polygon fill="black" stroke="black" points="394.42,-408.04 403.84,-409.5 397.39,-402.48 394.42,-408.04"/>
</g>
<!-- m_SellCryptoOrder -->
<g id="node6" class="node">
<title>m_SellCryptoOrder</title>
<path fill="none" stroke="black" d="M214.5,-198.5C214.5,-198.5 351.5,-198.5 351.5,-198.5 357.5,-198.5 363.5,-204.5 363.5,-210.5 363.5,-210.5 363.5,-268.5 363.5,-268.5 363.5,-274.5 357.5,-280.5 351.5,-280.5 351.5,-280.5 214.5,-280.5 214.5,-280.5 208.5,-280.5 202.5,-274.5 202.5,-268.5 202.5,-268.5 202.5,-210.5 202.5,-210.5 202.5,-204.5 208.5,-198.5 214.5,-198.5"/>
<text text-anchor="start" x="238" y="-267.7" font-family="Arial Bold" font-size="11.00">SellCryptoOrder</text>
<polyline fill="none" stroke="black" points="202.5,-260.5 363.5,-260.5 "/>
<text text-anchor="start" x="210" y="-247.5" font-family="Arial" font-size="10.00">paid_amount </text>
<text text-anchor="start" x="269" y="-247.5" font-family="Arial Italic" font-size="10.00" fill="#999999">decimal (20,10)</text>
<text text-anchor="start" x="210" y="-234.5" font-family="Arial" font-size="10.00">received_amount_cents </text>
<text text-anchor="start" x="317" y="-234.5" font-family="Arial Italic" font-size="10.00" fill="#999999">integer</text>
<text text-anchor="start" x="210" y="-221.5" font-family="Arial" font-size="10.00">status </text>
<text text-anchor="start" x="241" y="-221.5" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text>
<text text-anchor="start" x="210" y="-208.5" font-family="Arial" font-size="10.00">user_id </text>
<text text-anchor="start" x="245" y="-208.5" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) FK</text>
</g>
<!-- m_StakeOrder -->
<g id="node7" class="node">
<title>m_StakeOrder</title>
<path fill="none" stroke="black" d="M223,-86.5C223,-86.5 343,-86.5 343,-86.5 349,-86.5 355,-92.5 355,-98.5 355,-98.5 355,-156.5 355,-156.5 355,-162.5 349,-168.5 343,-168.5 343,-168.5 223,-168.5 223,-168.5 217,-168.5 211,-162.5 211,-156.5 211,-156.5 211,-98.5 211,-98.5 211,-92.5 217,-86.5 223,-86.5"/>
<text text-anchor="start" x="251" y="-155.7" font-family="Arial Bold" font-size="11.00">StakeOrder</text>
<polyline fill="none" stroke="black" points="211,-148.5 355,-148.5 "/>
<text text-anchor="start" x="218" y="-135.5" font-family="Arial" font-size="10.00">amount </text>
<text text-anchor="start" x="254" y="-135.5" font-family="Arial Italic" font-size="10.00" fill="#999999">decimal (20,10)</text>
<text text-anchor="start" x="218" y="-122.5" font-family="Arial" font-size="10.00">pool_name </text>
<text text-anchor="start" x="269" y="-122.5" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text>
<text text-anchor="start" x="218" y="-109.5" font-family="Arial" font-size="10.00">status </text>
<text text-anchor="start" x="249" y="-109.5" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text>
<text text-anchor="start" x="218" y="-96.5" font-family="Arial" font-size="10.00">user_id </text>
<text text-anchor="start" x="253" y="-96.5" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) FK</text>
</g> </g>
<!-- m_User --> <!-- m_User -->
<g id="node9" class="node"> <g id="node8" class="node">
<title>m_User</title> <title>m_User</title>
<path fill="none" stroke="black" d="M12,-165.5C12,-165.5 150,-165.5 150,-165.5 156,-165.5 162,-171.5 162,-177.5 162,-177.5 162,-287.5 162,-287.5 162,-293.5 156,-299.5 150,-299.5 150,-299.5 12,-299.5 12,-299.5 6,-299.5 0,-293.5 0,-287.5 0,-287.5 0,-177.5 0,-177.5 0,-171.5 6,-165.5 12,-165.5"/> <path fill="none" stroke="black" d="M12,-225.5C12,-225.5 150,-225.5 150,-225.5 156,-225.5 162,-231.5 162,-237.5 162,-237.5 162,-347.5 162,-347.5 162,-353.5 156,-359.5 150,-359.5 150,-359.5 12,-359.5 12,-359.5 6,-359.5 0,-353.5 0,-347.5 0,-347.5 0,-237.5 0,-237.5 0,-231.5 6,-225.5 12,-225.5"/>
<text text-anchor="start" x="66.5" y="-286.7" font-family="Arial Bold" font-size="11.00">User</text> <text text-anchor="start" x="66.5" y="-346.7" font-family="Arial Bold" font-size="11.00">User</text>
<polyline fill="none" stroke="black" points="0,-279.5 162,-279.5 "/> <polyline fill="none" stroke="black" points="0,-339.5 162,-339.5 "/>
<text text-anchor="start" x="7" y="-266.5" font-family="Arial" font-size="10.00">email </text> <text text-anchor="start" x="7" y="-326.5" font-family="Arial" font-size="10.00">email </text>
<text text-anchor="start" x="34" y="-266.5" font-family="Arial Italic" font-size="10.00" fill="#999999">string U</text> <text text-anchor="start" x="34" y="-326.5" font-family="Arial Italic" font-size="10.00" fill="#999999">string U</text>
<text text-anchor="start" x="7" y="-253.5" font-family="Arial" font-size="10.00">encrypted_password </text> <text text-anchor="start" x="7" y="-313.5" font-family="Arial" font-size="10.00">encrypted_password </text>
<text text-anchor="start" x="101" y="-253.5" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text> <text text-anchor="start" x="101" y="-313.5" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text>
<text text-anchor="start" x="7" y="-240.5" font-family="Arial" font-size="10.00">first_name </text> <text text-anchor="start" x="7" y="-300.5" font-family="Arial" font-size="10.00">first_name </text>
<text text-anchor="start" x="56" y="-240.5" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text> <text text-anchor="start" x="56" y="-300.5" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text>
<text text-anchor="start" x="7" y="-227.5" font-family="Arial" font-size="10.00">last_name </text> <text text-anchor="start" x="7" y="-287.5" font-family="Arial" font-size="10.00">last_name </text>
<text text-anchor="start" x="56" y="-227.5" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text> <text text-anchor="start" x="56" y="-287.5" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text>
<text text-anchor="start" x="7" y="-214.5" font-family="Arial" font-size="10.00">remember_created_at </text> <text text-anchor="start" x="7" y="-274.5" font-family="Arial" font-size="10.00">remember_created_at </text>
<text text-anchor="start" x="105" y="-214.5" font-family="Arial Italic" font-size="10.00" fill="#999999">datetime</text> <text text-anchor="start" x="105" y="-274.5" font-family="Arial Italic" font-size="10.00" fill="#999999">datetime</text>
<text text-anchor="start" x="7" y="-201.5" font-family="Arial" font-size="10.00">reset_password_sent_at </text> <text text-anchor="start" x="7" y="-261.5" font-family="Arial" font-size="10.00">reset_password_sent_at </text>
<text text-anchor="start" x="117" y="-201.5" font-family="Arial Italic" font-size="10.00" fill="#999999">datetime</text> <text text-anchor="start" x="117" y="-261.5" font-family="Arial Italic" font-size="10.00" fill="#999999">datetime</text>
<text text-anchor="start" x="7" y="-188.5" font-family="Arial" font-size="10.00">reset_password_token </text> <text text-anchor="start" x="7" y="-248.5" font-family="Arial" font-size="10.00">reset_password_token </text>
<text text-anchor="start" x="109" y="-188.5" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text> <text text-anchor="start" x="109" y="-248.5" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text>
<text text-anchor="start" x="7" y="-175.5" font-family="Arial" font-size="10.00">wallet_address </text> <text text-anchor="start" x="7" y="-235.5" font-family="Arial" font-size="10.00">wallet_address </text>
<text text-anchor="start" x="76" y="-175.5" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text> <text text-anchor="start" x="76" y="-235.5" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text>
</g> </g>
<!-- m_User&#45;&gt;m_Balance --> <!-- m_User&#45;&gt;m_Balance -->
<g id="edge5" class="edge"> <g id="edge5" class="edge">
<title>m_User&#45;&gt;m_Balance</title> <title>m_User&#45;&gt;m_Balance</title>
<path fill="none" stroke="black" d="M122.66,-299.86C136.72,-325.37 151.54,-355.1 162,-383.5 187.49,-452.71 154.51,-485.93 198,-545.5 200.01,-548.25 202.23,-550.88 204.6,-553.37"/> <path fill="none" stroke="black" d="M105.93,-359.84C125.07,-405.99 155.71,-466.12 198,-507.5 203.62,-513 210.09,-517.95 216.88,-522.36"/>
<polygon fill="black" stroke="black" points="202.54,-555.76 211.23,-559.69 206.89,-551.2 202.54,-555.76"/>
</g> </g>
<!-- m_User&#45;&gt;m_BuyCryptoOrder --> <!-- m_User&#45;&gt;m_BuyCryptoOrder -->
<g id="edge7" class="edge"> <g id="edge7" class="edge">
<title>m_User&#45;&gt;m_BuyCryptoOrder</title> <title>m_User&#45;&gt;m_BuyCryptoOrder</title>
<path fill="none" stroke="black" d="M115.31,-299.85C135.98,-337.74 164.89,-384.52 198,-420.5 200.55,-423.28 203.25,-426.01 206.04,-428.69"/> <path fill="none" stroke="black" d="M154.65,-359.73C168.74,-371.99 183.61,-384.4 198,-395.5 202.09,-398.65 206.35,-401.83 210.69,-404.97"/>
<polygon fill="black" stroke="black" points="203.97,-431.07 212.73,-434.85 208.24,-426.43 203.97,-431.07"/> <polygon fill="black" stroke="black" points="208.89,-407.55 218.05,-410.22 212.55,-402.42 208.89,-407.55"/>
</g> </g>
<!-- m_User&#45;&gt;m_FiatBalance --> <!-- m_User&#45;&gt;m_FiatBalance -->
<g id="edge6" class="edge"> <g id="edge6" class="edge">
<title>m_User&#45;&gt;m_FiatBalance</title> <title>m_User&#45;&gt;m_FiatBalance</title>
<path fill="none" stroke="black" d="M162.2,-187.59C181.54,-176.76 201.91,-165.35 220.26,-155.07"/> <path fill="none" stroke="black" d="M162.2,-313.75C178.28,-318.01 195.08,-322.46 210.83,-326.64"/>
</g> </g>
<!-- m_User&#45;&gt;m_SellCryptoOrder --> <!-- m_User&#45;&gt;m_SellCryptoOrder -->
<g id="edge9" class="edge"> <g id="edge8" class="edge">
<title>m_User&#45;&gt;m_SellCryptoOrder</title> <title>m_User&#45;&gt;m_SellCryptoOrder</title>
<path fill="none" stroke="black" d="M162.2,-282.62C173.96,-289.98 186.11,-297.57 197.95,-304.97"/> <path fill="none" stroke="black" d="M162.2,-271.25C172.55,-268.5 183.21,-265.68 193.69,-262.9"/>
<polygon fill="black" stroke="black" points="196.38,-307.7 205.68,-309.8 199.72,-302.36 196.38,-307.7"/> <polygon fill="black" stroke="black" points="194.55,-265.93 202.44,-260.58 192.93,-259.84 194.55,-265.93"/>
</g> </g>
<!-- m_User&#45;&gt;m_StakeOrder --> <!-- m_User&#45;&gt;m_StakeOrder -->
<g id="edge4" class="edge"> <g id="edge4" class="edge">
<title>m_User&#45;&gt;m_StakeOrder</title> <title>m_User&#45;&gt;m_StakeOrder</title>
<path fill="none" stroke="black" d="M162.2,-232.5C175.14,-232.5 188.54,-232.5 201.49,-232.5"/> <path fill="none" stroke="black" d="M149.62,-225.41C165.09,-211.08 181.77,-196.39 198,-183.5 202.04,-180.29 206.27,-177.07 210.58,-173.9"/>
<polygon fill="black" stroke="black" points="201.83,-235.65 210.83,-232.5 201.83,-229.35 201.83,-235.65"/> <polygon fill="black" stroke="black" points="212.46,-176.43 217.91,-168.6 208.77,-171.32 212.46,-176.43"/>
</g> </g>
<!-- m_UserDocument --> <!-- m_UserDocument -->
<g id="node10" class="node"> <g id="node9" class="node">
<title>m_UserDocument</title> <title>m_UserDocument</title>
<path fill="none" stroke="black" d="M223,-0.5C223,-0.5 343,-0.5 343,-0.5 349,-0.5 355,-6.5 355,-12.5 355,-12.5 355,-44.5 355,-44.5 355,-50.5 349,-56.5 343,-56.5 343,-56.5 223,-56.5 223,-56.5 217,-56.5 211,-50.5 211,-44.5 211,-44.5 211,-12.5 211,-12.5 211,-6.5 217,-0.5 223,-0.5"/> <path fill="none" stroke="black" d="M223,-0.5C223,-0.5 343,-0.5 343,-0.5 349,-0.5 355,-6.5 355,-12.5 355,-12.5 355,-44.5 355,-44.5 355,-50.5 349,-56.5 343,-56.5 343,-56.5 223,-56.5 223,-56.5 217,-56.5 211,-50.5 211,-44.5 211,-44.5 211,-12.5 211,-12.5 211,-6.5 217,-0.5 223,-0.5"/>
<text text-anchor="start" x="241.5" y="-43.7" font-family="Arial Bold" font-size="11.00">UserDocument</text> <text text-anchor="start" x="241.5" y="-43.7" font-family="Arial Bold" font-size="11.00">UserDocument</text>
@@ -232,8 +190,8 @@
<!-- m_User&#45;&gt;m_UserDocument --> <!-- m_User&#45;&gt;m_UserDocument -->
<g id="edge3" class="edge"> <g id="edge3" class="edge">
<title>m_User&#45;&gt;m_UserDocument</title> <title>m_User&#45;&gt;m_UserDocument</title>
<path fill="none" stroke="black" d="M150.29,-165.23C154.45,-160.06 158.4,-154.8 162,-149.5 183.7,-117.6 171.21,-98.27 198,-70.5 200.88,-67.51 204.02,-64.71 207.33,-62.07"/> <path fill="none" stroke="black" d="M152.47,-225.27C155.95,-220.46 159.17,-215.52 162,-210.5 193.33,-154.91 158.09,-121.3 198,-71.5 200.61,-68.25 203.52,-65.22 206.66,-62.4"/>
<polygon fill="black" stroke="black" points="209.43,-64.44 214.84,-56.58 205.71,-59.35 209.43,-64.44"/> <polygon fill="black" stroke="black" points="208.86,-64.67 213.87,-56.55 204.89,-59.78 208.86,-64.67"/>
</g> </g>
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -4,27 +4,23 @@
# #
# Table name: balances # Table name: balances
# #
# id :bigint not null, primary key # id :bigint not null, primary key
# amount :decimal(20, 10) default(0.0), not null # amount :decimal(20, 10) default(0.0), not null
# created_at :datetime not null # created_at :datetime not null
# updated_at :datetime not null # updated_at :datetime not null
# currency_id :bigint not null # user_id :bigint not null
# user_id :bigint not null
# #
# Indexes # Indexes
# #
# index_balances_on_currency_id (currency_id) # index_balances_on_user_id (user_id)
# index_balances_on_user_id (user_id)
# #
# Foreign Keys # Foreign Keys
# #
# fk_rails_... (currency_id => currencies.id)
# fk_rails_... (user_id => users.id) # fk_rails_... (user_id => users.id)
# #
FactoryBot.define do FactoryBot.define do
factory :balance do factory :balance do
association :user association :user
association :currency
amount { (rand * (10000 - 0) + 0) } amount { (rand * (10000 - 0) + 0) }
end end
end end

View File

@@ -10,23 +10,19 @@
# status :string not null # status :string not null
# created_at :datetime not null # created_at :datetime not null
# updated_at :datetime not null # updated_at :datetime not null
# currency_id :bigint not null
# user_id :bigint not null # user_id :bigint not null
# #
# Indexes # Indexes
# #
# index_buy_crypto_orders_on_currency_id (currency_id) # index_buy_crypto_orders_on_user_id (user_id)
# index_buy_crypto_orders_on_user_id (user_id)
# #
# Foreign Keys # Foreign Keys
# #
# fk_rails_... (currency_id => currencies.id)
# fk_rails_... (user_id => users.id) # fk_rails_... (user_id => users.id)
# #
FactoryBot.define do FactoryBot.define do
factory :buy_crypto_order do factory :buy_crypto_order do
association :user association :user
association :currency
status { :processing } status { :processing }
paid_amount_cents { rand(10000) } paid_amount_cents { rand(10000) }
received_amount { rand * 10000 } received_amount { rand * 10000 }

View File

@@ -1,16 +0,0 @@
# frozen_string_literal: true
# == Schema Information
#
# Table name: currencies
#
# id :bigint not null, primary key
# name :string not null
# created_at :datetime not null
# updated_at :datetime not null
#
FactoryBot.define do
factory :currency do
name { "CAKE" }
end
end

View File

@@ -10,23 +10,19 @@
# status :string not null # status :string not null
# created_at :datetime not null # created_at :datetime not null
# updated_at :datetime not null # updated_at :datetime not null
# currency_id :bigint not null
# user_id :bigint not null # user_id :bigint not null
# #
# Indexes # Indexes
# #
# index_sell_crypto_orders_on_currency_id (currency_id) # index_sell_crypto_orders_on_user_id (user_id)
# index_sell_crypto_orders_on_user_id (user_id)
# #
# Foreign Keys # Foreign Keys
# #
# fk_rails_... (currency_id => currencies.id)
# fk_rails_... (user_id => users.id) # fk_rails_... (user_id => users.id)
# #
FactoryBot.define do FactoryBot.define do
factory :sell_crypto_order do factory :sell_crypto_order do
association :user association :user
association :currency
status { :processing } status { :processing }
received_amount_cents { rand(10000) } received_amount_cents { rand(10000) }
paid_amount { rand * 10000 } paid_amount { rand * 10000 }

View File

@@ -4,23 +4,20 @@
# #
# Table name: stake_orders # Table name: stake_orders
# #
# id :bigint not null, primary key # id :bigint not null, primary key
# amount :decimal(20, 10) default(0.0), not null # amount :decimal(20, 10) default(0.0), not null
# pool_name :string not null # pool_name :string not null
# status :string not null # status :string not null
# created_at :datetime not null # created_at :datetime not null
# updated_at :datetime not null # updated_at :datetime not null
# currency_id :bigint # user_id :bigint not null
# user_id :bigint not null
# #
# Indexes # Indexes
# #
# index_stake_orders_on_currency_id (currency_id) # index_stake_orders_on_user_id (user_id)
# index_stake_orders_on_user_id (user_id)
# #
# Foreign Keys # Foreign Keys
# #
# fk_rails_... (currency_id => currencies.id)
# fk_rails_... (user_id => users.id) # fk_rails_... (user_id => users.id)
# #
FactoryBot.define do FactoryBot.define do

View File

@@ -6,7 +6,6 @@ describe Inputs::CreateBuyCryptoOrderAttributesInput do
subject { described_class } subject { described_class }
describe "fields" do describe "fields" do
it { is_expected.to(accept_argument("currency_id").of_type("ID!")) }
it { is_expected.to(accept_argument("amount_cents").of_type("Int!")) } it { is_expected.to(accept_argument("amount_cents").of_type("Int!")) }
end end
end end

View File

@@ -6,7 +6,6 @@ describe Inputs::CreateSellCryptoOrderAttributesInput do
subject { described_class } subject { described_class }
describe "fields" do describe "fields" do
it { is_expected.to(accept_argument("currency_id").of_type("ID!")) }
it { is_expected.to(accept_argument("amount").of_type("String!")) } it { is_expected.to(accept_argument("amount").of_type("String!")) }
end end
end end

View File

@@ -5,10 +5,9 @@ require "rails_helper"
RSpec.describe(Mutations::CreateBuyCryptoOrder, type: :mutation) do RSpec.describe(Mutations::CreateBuyCryptoOrder, type: :mutation) do
let(:query_string) do let(:query_string) do
<<~GQL <<~GQL
mutation($currencyId: ID!, $amountCents: Int!) { mutation($amountCents: Int!) {
createBuyCryptoOrder(input: { createBuyCryptoOrder(input: {
order: { order: {
currencyId: $currencyId,
amountCents: $amountCents, amountCents: $amountCents,
} }
}) { }) {
@@ -22,9 +21,6 @@ RSpec.describe(Mutations::CreateBuyCryptoOrder, type: :mutation) do
status status
paidAmountCents paidAmountCents
receivedAmount receivedAmount
currency {
name
}
} }
} }
} }
@@ -33,7 +29,6 @@ RSpec.describe(Mutations::CreateBuyCryptoOrder, type: :mutation) do
context "when the user has enough balance" do context "when the user has enough balance" do
it "withdraws from his account and creates a buy order" do it "withdraws from his account and creates a buy order" do
currency = create(:currency)
user = create( user = create(
:user, :user,
fiat_balance: build( fiat_balance: build(
@@ -42,10 +37,7 @@ RSpec.describe(Mutations::CreateBuyCryptoOrder, type: :mutation) do
), ),
) )
currency_global_id = GraphQL::Schema::UniqueWithinType.encode("Currency", currency.id)
variables = { variables = {
"currencyId": currency_global_id,
"amountCents": 90_00, "amountCents": 90_00,
} }
@@ -65,9 +57,6 @@ RSpec.describe(Mutations::CreateBuyCryptoOrder, type: :mutation) do
"status" => "PROCESSING", "status" => "PROCESSING",
"paidAmountCents" => 90_00, "paidAmountCents" => 90_00,
"receivedAmount" => "0.0", "receivedAmount" => "0.0",
"currency" => {
"name" => "CAKE",
},
}, },
}, },
}, },
@@ -79,7 +68,6 @@ RSpec.describe(Mutations::CreateBuyCryptoOrder, type: :mutation) do
context "when the user does not have enough balance" do context "when the user does not have enough balance" do
it "returns withdrawl error" do it "returns withdrawl error" do
currency = create(:currency)
user = create( user = create(
:user, :user,
fiat_balance: build( fiat_balance: build(
@@ -88,10 +76,7 @@ RSpec.describe(Mutations::CreateBuyCryptoOrder, type: :mutation) do
), ),
) )
currency_global_id = GraphQL::Schema::UniqueWithinType.encode("Currency", currency.id)
variables = { variables = {
"currencyId": currency_global_id,
"amountCents": 90_00, "amountCents": 90_00,
} }

View File

@@ -5,10 +5,9 @@ require "rails_helper"
RSpec.describe(Mutations::CreateSellCryptoOrder, type: :mutation) do RSpec.describe(Mutations::CreateSellCryptoOrder, type: :mutation) do
let(:query_string) do let(:query_string) do
<<~GQL <<~GQL
mutation($currencyId: ID!, $amount: String!) { mutation($amount: String!) {
createSellCryptoOrder(input: { createSellCryptoOrder(input: {
order: { order: {
currencyId: $currencyId,
amount: $amount, amount: $amount,
} }
}) { }) {
@@ -22,9 +21,6 @@ RSpec.describe(Mutations::CreateSellCryptoOrder, type: :mutation) do
status status
paidAmount paidAmount
receivedAmountCents receivedAmountCents
currency {
name
}
} }
} }
} }
@@ -33,18 +29,12 @@ RSpec.describe(Mutations::CreateSellCryptoOrder, type: :mutation) do
context "when the user has enough balance" do context "when the user has enough balance" do
it "withdraws from his account and creates a buy order" do it "withdraws from his account and creates a buy order" do
currency = create(:currency)
user = create( user = create(
:user, :user,
balances: [ balance: build(:balance, amount: 1.0034)
build(:balance, currency: currency, amount: 1.0034),
]
) )
currency_global_id = GraphQL::Schema::UniqueWithinType.encode("Currency", currency.id)
variables = { variables = {
"currencyId": currency_global_id,
"amount": "0.80", "amount": "0.80",
} }
@@ -64,32 +54,23 @@ RSpec.describe(Mutations::CreateSellCryptoOrder, type: :mutation) do
"status" => "PROCESSING", "status" => "PROCESSING",
"paidAmount" => "0.8", "paidAmount" => "0.8",
"receivedAmountCents" => 0, "receivedAmountCents" => 0,
"currency" => {
"name" => "CAKE",
},
}, },
}, },
}, },
})) }))
expect(user.balances.first.reload.amount.to_s).to(eq("0.2034")) expect(user.balance.reload.amount.to_s).to(eq("0.2034"))
end end
end end
context "when the user does not have enough balance" do context "when the user does not have enough balance" do
it "returns withdrawl error" do it "returns withdrawl error" do
currency = create(:currency)
user = create( user = create(
:user, :user,
balances: [ balance: build(:balance, amount: 0.0034)
build(:balance, currency: currency, amount: 0.0034),
]
) )
currency_global_id = GraphQL::Schema::UniqueWithinType.encode("Currency", currency.id)
variables = { variables = {
"currencyId": currency_global_id,
"amount": "0.80", "amount": "0.80",
} }
@@ -115,7 +96,7 @@ RSpec.describe(Mutations::CreateSellCryptoOrder, type: :mutation) do
}, },
})) }))
expect(user.balances.first.reload.amount.to_s).to(eq("0.0034")) expect(user.balance.reload.amount.to_s).to(eq("0.0034"))
end end
end end
end end

View File

@@ -33,12 +33,9 @@ RSpec.describe(Mutations::CreateStakeOrder, type: :mutation) do
context "when the user has enough balance" do context "when the user has enough balance" do
it "withdraws from his account and creates a buy order" do it "withdraws from his account and creates a buy order" do
currency = create(:currency)
user = create( user = create(
:user, :user,
balances: [ balance: build(:balance, amount: 1.0034)
build(:balance, currency: currency, amount: 1.0034),
]
) )
variables = { variables = {
@@ -68,18 +65,15 @@ RSpec.describe(Mutations::CreateStakeOrder, type: :mutation) do
}, },
})) }))
expect(user.balances.first.reload.amount.to_s).to(eq("0.2034")) expect(user.balance.reload.amount.to_s).to(eq("0.2034"))
end end
end end
context "when the user does not have enough balance" do context "when the user does not have enough balance" do
it "returns withdrawl error" do it "returns withdrawl error" do
currency = create(:currency)
user = create( user = create(
:user, :user,
balances: [ balance: build(:balance, amount: 0.0034)
build(:balance, currency: currency, amount: 0.0034),
]
) )
variables = { variables = {
@@ -109,7 +103,7 @@ RSpec.describe(Mutations::CreateStakeOrder, type: :mutation) do
}, },
})) }))
expect(user.balances.first.reload.amount.to_s).to(eq("0.0034")) expect(user.balance.reload.amount.to_s).to(eq("0.0034"))
end end
end end
end end

View File

@@ -33,12 +33,9 @@ RSpec.describe(Mutations::CreateStakeRemoveOrder, type: :mutation) do
context "when the user has enough balance" do context "when the user has enough balance" do
it "withdraws from his account and creates a buy order" do it "withdraws from his account and creates a buy order" do
currency = create(:currency)
user = create( user = create(
:user, :user,
balances: [ balance: build(:balance, amount: 0)
build(:balance, currency: currency, amount: 0),
]
) )
variables = { variables = {
@@ -72,15 +69,12 @@ RSpec.describe(Mutations::CreateStakeRemoveOrder, type: :mutation) do
context "when it repeats the mutation with a request in `processing`" do context "when it repeats the mutation with a request in `processing`" do
it "update amount from the order" do it "update amount from the order" do
currency = create(:currency)
user = create( user = create(
:user, :user,
balances: [ balance: build(:balance, amount: 0)
build(:balance, currency: currency, amount: 0),
]
) )
create(:stake_order, amount: -200.8, user: user, pool_name: "CAKE/BNB", currency: currency) create(:stake_order, amount: -200.8, user: user, pool_name: "CAKE/BNB")
variables = { variables = {
"amount": "200.80", "amount": "200.80",

View File

@@ -6,7 +6,6 @@ RSpec.describe(Types::BuyCryptoOrderType) do
describe "arguments" do describe "arguments" do
it { is_expected.to(have_a_field(:id).of_type("ID!")) } it { is_expected.to(have_a_field(:id).of_type("ID!")) }
it { is_expected.to(have_a_field(:currency).of_type("Currency!")) }
it { is_expected.to(have_a_field(:paid_amount_cents).of_type("Int!")) } it { is_expected.to(have_a_field(:paid_amount_cents).of_type("Int!")) }
it { is_expected.to(have_a_field(:received_amount).of_type("String")) } it { is_expected.to(have_a_field(:received_amount).of_type("String")) }
it { is_expected.to(have_a_field(:status).of_type("ProcessStatus!")) } it { is_expected.to(have_a_field(:status).of_type("ProcessStatus!")) }

View File

@@ -6,7 +6,6 @@ RSpec.describe(Types::SellCryptoOrderType) do
describe "arguments" do describe "arguments" do
it { is_expected.to(have_a_field(:id).of_type("ID!")) } it { is_expected.to(have_a_field(:id).of_type("ID!")) }
it { is_expected.to(have_a_field(:currency).of_type("Currency!")) }
it { is_expected.to(have_a_field(:paid_amount).of_type("String!")) } it { is_expected.to(have_a_field(:paid_amount).of_type("String!")) }
it { is_expected.to(have_a_field(:received_amount_cents).of_type("Int")) } it { is_expected.to(have_a_field(:received_amount_cents).of_type("Int")) }
it { is_expected.to(have_a_field(:status).of_type("ProcessStatus!")) } it { is_expected.to(have_a_field(:status).of_type("ProcessStatus!")) }

View File

@@ -4,21 +4,18 @@
# #
# Table name: balances # Table name: balances
# #
# id :bigint not null, primary key # id :bigint not null, primary key
# amount :decimal(20, 10) default(0.0), not null # amount :decimal(20, 10) default(0.0), not null
# created_at :datetime not null # created_at :datetime not null
# updated_at :datetime not null # updated_at :datetime not null
# currency_id :bigint not null # user_id :bigint not null
# user_id :bigint not null
# #
# Indexes # Indexes
# #
# index_balances_on_currency_id (currency_id) # index_balances_on_user_id (user_id)
# index_balances_on_user_id (user_id)
# #
# Foreign Keys # Foreign Keys
# #
# fk_rails_... (currency_id => currencies.id)
# fk_rails_... (user_id => users.id) # fk_rails_... (user_id => users.id)
# #
require "rails_helper" require "rails_helper"
@@ -30,7 +27,6 @@ RSpec.describe(Balance, type: :model) do
describe "associations" do describe "associations" do
it { is_expected.to(belong_to(:user)) } it { is_expected.to(belong_to(:user)) }
it { is_expected.to(belong_to(:currency)) }
end end
describe ".withdrwal!" do describe ".withdrwal!" do

View File

@@ -10,17 +10,14 @@
# status :string not null # status :string not null
# created_at :datetime not null # created_at :datetime not null
# updated_at :datetime not null # updated_at :datetime not null
# currency_id :bigint not null
# user_id :bigint not null # user_id :bigint not null
# #
# Indexes # Indexes
# #
# index_buy_crypto_orders_on_currency_id (currency_id) # index_buy_crypto_orders_on_user_id (user_id)
# index_buy_crypto_orders_on_user_id (user_id)
# #
# Foreign Keys # Foreign Keys
# #
# fk_rails_... (currency_id => currencies.id)
# fk_rails_... (user_id => users.id) # fk_rails_... (user_id => users.id)
# #
require "rails_helper" require "rails_helper"
@@ -51,6 +48,5 @@ RSpec.describe(BuyCryptoOrder, type: :model) do
describe "associations" do describe "associations" do
it { is_expected.to(belong_to(:user)) } it { is_expected.to(belong_to(:user)) }
it { is_expected.to(belong_to(:currency)) }
end end
end end

View File

@@ -1,18 +0,0 @@
# frozen_string_literal: true
# == Schema Information
#
# Table name: currencies
#
# id :bigint not null, primary key
# name :string not null
# created_at :datetime not null
# updated_at :datetime not null
#
require "rails_helper"
RSpec.describe(Currency, type: :model) do
describe "validations" do
it { is_expected.to(validate_presence_of(:name)) }
end
end

View File

@@ -10,17 +10,14 @@
# status :string not null # status :string not null
# created_at :datetime not null # created_at :datetime not null
# updated_at :datetime not null # updated_at :datetime not null
# currency_id :bigint not null
# user_id :bigint not null # user_id :bigint not null
# #
# Indexes # Indexes
# #
# index_sell_crypto_orders_on_currency_id (currency_id) # index_sell_crypto_orders_on_user_id (user_id)
# index_sell_crypto_orders_on_user_id (user_id)
# #
# Foreign Keys # Foreign Keys
# #
# fk_rails_... (currency_id => currencies.id)
# fk_rails_... (user_id => users.id) # fk_rails_... (user_id => users.id)
# #
require "rails_helper" require "rails_helper"
@@ -51,6 +48,5 @@ RSpec.describe(SellCryptoOrder, type: :model) do
describe "associations" do describe "associations" do
it { is_expected.to(belong_to(:user)) } it { is_expected.to(belong_to(:user)) }
it { is_expected.to(belong_to(:currency)) }
end end
end end

View File

@@ -4,23 +4,20 @@
# #
# Table name: stake_orders # Table name: stake_orders
# #
# id :bigint not null, primary key # id :bigint not null, primary key
# amount :decimal(20, 10) default(0.0), not null # amount :decimal(20, 10) default(0.0), not null
# pool_name :string not null # pool_name :string not null
# status :string not null # status :string not null
# created_at :datetime not null # created_at :datetime not null
# updated_at :datetime not null # updated_at :datetime not null
# currency_id :bigint # user_id :bigint not null
# user_id :bigint not null
# #
# Indexes # Indexes
# #
# index_stake_orders_on_currency_id (currency_id) # index_stake_orders_on_user_id (user_id)
# index_stake_orders_on_user_id (user_id)
# #
# Foreign Keys # Foreign Keys
# #
# fk_rails_... (currency_id => currencies.id)
# fk_rails_... (user_id => users.id) # fk_rails_... (user_id => users.id)
# #
require "rails_helper" require "rails_helper"
@@ -33,6 +30,5 @@ RSpec.describe(StakeOrder, type: :model) do
describe "associations" do describe "associations" do
it { is_expected.to(belong_to(:user)) } it { is_expected.to(belong_to(:user)) }
it { is_expected.to(belong_to(:currency)) }
end end
end end

View File

@@ -33,7 +33,7 @@ RSpec.describe(User, type: :model) do
describe "associations" do describe "associations" do
it { is_expected.to(have_many(:documents)) } it { is_expected.to(have_many(:documents)) }
it { is_expected.to(have_many(:stake_orders)) } it { is_expected.to(have_many(:stake_orders)) }
it { is_expected.to(have_many(:balances)) } it { is_expected.to(have_one(:balance)) }
it { is_expected.to(have_one(:fiat_balance)) } it { is_expected.to(have_one(:fiat_balance)) }
end end
end end