get cake balance from bsc wallet

This commit is contained in:
João Geonizeli
2021-09-15 23:45:50 -03:00
parent d01502d765
commit fb957803cc
24 changed files with 453 additions and 79 deletions

1
.env
View File

@@ -4,6 +4,7 @@ MAILTRAP_ADDRESS=smtp.mailtrap.io
MAILTRAP_DOMAIN=smtp.mailtrap.io MAILTRAP_DOMAIN=smtp.mailtrap.io
MAILTRAP_PORT=2525 MAILTRAP_PORT=2525
MAILER_DEFAULT_URL_HOST=localhost:5000 MAILER_DEFAULT_URL_HOST=localhost:5000
TATUM_API_KEY=d8f66b09-d3ff-43ca-9b59-31b1b78d2660
# SLACK_WEBHOOK_URL=https://hooks.slack.com/services/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 # SLACK_WEBHOOK_URL=https://hooks.slack.com/services/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
# production # production

View File

@@ -29,6 +29,7 @@ gem "enumerize"
gem "graphql" gem "graphql"
gem "pundit" gem "pundit"
gem "ransack", "~> 2.4" gem "ransack", "~> 2.4"
gem "httparty", "~> 0.19.0"
group :development, :test do group :development, :test do
gem "dotenv-rails" gem "dotenv-rails"

View File

@@ -124,6 +124,9 @@ GEM
graphql (1.12.14) graphql (1.12.14)
graphql_playground-rails (2.1.0) graphql_playground-rails (2.1.0)
rails (>= 5.1.0) rails (>= 5.1.0)
httparty (0.19.0)
mime-types (~> 3.0)
multi_xml (>= 0.5.2)
i18n (1.8.10) i18n (1.8.10)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
image_processing (1.12.1) image_processing (1.12.1)
@@ -155,6 +158,9 @@ GEM
mini_mime (>= 0.1.1) mini_mime (>= 0.1.1)
marcel (1.0.1) marcel (1.0.1)
method_source (1.0.0) method_source (1.0.0)
mime-types (3.3.1)
mime-types-data (~> 3.2015)
mime-types-data (3.2021.0901)
mini_magick (4.11.0) mini_magick (4.11.0)
mini_mime (1.1.0) mini_mime (1.1.0)
mini_portile2 (2.6.1) mini_portile2 (2.6.1)
@@ -171,6 +177,7 @@ GEM
money (~> 6.13.2) money (~> 6.13.2)
railties (>= 3.0) railties (>= 3.0)
msgpack (1.4.2) msgpack (1.4.2)
multi_xml (0.6.0)
nio4r (2.5.8) nio4r (2.5.8)
nokogiri (1.12.1) nokogiri (1.12.1)
mini_portile2 (~> 2.6.1) mini_portile2 (~> 2.6.1)
@@ -366,6 +373,7 @@ DEPENDENCIES
foreman foreman
graphql graphql
graphql_playground-rails graphql_playground-rails
httparty (~> 0.19.0)
image_processing (~> 1.12) image_processing (~> 1.12)
listen (~> 3.3) listen (~> 3.3)
money-rails money-rails

View File

@@ -10,7 +10,10 @@ module Types
field :email, String, null: false field :email, String, null: false
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 :fiat_balance, FiatBalanceType, null: false field :fiat_balance, FiatBalanceType, null: false
field :wallet, WalletType, null: false
def wallet
Wallet.new(object)
end
end end
end end

View File

@@ -0,0 +1,9 @@
# frozen_string_literal: true
module Types
class WalletType < Types::BaseObject
graphql_name "Wallet"
field :address, String, null: true
field :cake_balance, String, null: false
end
end

View File

@@ -553,5 +553,10 @@ type User {
firstName: String! firstName: String!
id: ID! id: ID!
lastName: String! lastName: String!
walletAddress: String wallet: Wallet!
}
type Wallet {
address: String
cakeBalance: String!
} }

View File

@@ -27,7 +27,9 @@ query AppQuery {
fragment UserProvider_user on User { fragment UserProvider_user on User {
firstName firstName
walletAddress wallet {
address
}
} }
*/ */
@@ -79,11 +81,22 @@ const node: ConcreteRequest = {
"name": "firstName", "name": "firstName",
"storageKey": null "storageKey": null
}, },
{
"alias": null,
"args": null,
"concreteType": "Wallet",
"kind": "LinkedField",
"name": "wallet",
"plural": false,
"selections": [
{ {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "walletAddress", "name": "address",
"storageKey": null
}
],
"storageKey": null "storageKey": null
}, },
{ {
@@ -99,12 +112,12 @@ const node: ConcreteRequest = {
] ]
}, },
"params": { "params": {
"cacheID": "56b4be302cf9b9ec226ad8145170961b", "cacheID": "ae618245e5a3baf946034e1efe3682de",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "AppQuery", "name": "AppQuery",
"operationKind": "query", "operationKind": "query",
"text": "query AppQuery {\n currentUser {\n ...UserProvider_user\n id\n }\n}\n\nfragment UserProvider_user on User {\n firstName\n walletAddress\n}\n" "text": "query AppQuery {\n currentUser {\n ...UserProvider_user\n id\n }\n}\n\nfragment UserProvider_user on User {\n firstName\n wallet {\n address\n }\n}\n"
} }
}; };
(node as any).hash = 'aac57a65620cf50754d54f3c8d6495cf'; (node as any).hash = 'aac57a65620cf50754d54f3c8d6495cf';

View File

@@ -33,7 +33,9 @@ export const UserProvider: FC<Props> = ({ userRef, children }) => {
graphql` graphql`
fragment UserProvider_user on User { fragment UserProvider_user on User {
firstName firstName
walletAddress wallet {
address
}
} }
`, `,
userRef userRef
@@ -42,7 +44,7 @@ export const UserProvider: FC<Props> = ({ userRef, children }) => {
const user = userData const user = userData
? { ? {
firstName: userData.firstName, firstName: userData.firstName,
walletAddress: userData.walletAddress, walletAddress: userData.wallet.address,
} }
: null; : null;

View File

@@ -6,7 +6,9 @@ import { ReaderFragment } from "relay-runtime";
import { FragmentRefs } from "relay-runtime"; import { FragmentRefs } from "relay-runtime";
export type UserProvider_user = { export type UserProvider_user = {
readonly firstName: string; readonly firstName: string;
readonly walletAddress: string | null; readonly wallet: {
readonly address: string | null;
};
readonly " $refType": "UserProvider_user"; readonly " $refType": "UserProvider_user";
}; };
export type UserProvider_user$data = UserProvider_user; export type UserProvider_user$data = UserProvider_user;
@@ -30,16 +32,27 @@ const node: ReaderFragment = {
"name": "firstName", "name": "firstName",
"storageKey": null "storageKey": null
}, },
{
"alias": null,
"args": null,
"concreteType": "Wallet",
"kind": "LinkedField",
"name": "wallet",
"plural": false,
"selections": [
{ {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "walletAddress", "name": "address",
"storageKey": null
}
],
"storageKey": null "storageKey": null
} }
], ],
"type": "User", "type": "User",
"abstractKey": null "abstractKey": null
}; };
(node as any).hash = 'ef997d2646b4d39178c6f3318509a7cb'; (node as any).hash = '4f6b86f489ce0df288106cd92060b889';
export default node; export default node;

View File

@@ -1,14 +1,30 @@
import React from "react"; import React from "react";
import { useLazyLoadQuery } from "react-relay";
import { graphql } from "babel-plugin-relay/macro";
import { Pool } from "./Pool"; import { Pool } from "./Pool";
import { Spinner } from "../../components"; import { Spinner } from "../../components";
import { usePoolListing } from "./hooks"; import { usePoolListing } from "./hooks";
import type { PoolListingQuery } from "./__generated__/PoolListingQuery.graphql";
import { formatCake } from "../../utils/cake";
export const PoolListing = () => { export const PoolListing = () => {
const { isLoading, validPools } = usePoolListing(); const { isLoading, validPools } = usePoolListing();
// TODO<wallet>: puxar valor da wallet const { currentUser } = useLazyLoadQuery<PoolListingQuery>(
const balance = "0"; graphql`
query PoolListingQuery {
currentUser {
wallet {
cakeBalance
}
}
}
`,
{}
);
const balance = formatCake(currentUser?.wallet.cakeBalance);
if (isLoading && !validPools.length) { if (isLoading && !validPools.length) {
return ( return (

View File

@@ -0,0 +1,112 @@
/* tslint:disable */
/* eslint-disable */
// @ts-nocheck
import { ConcreteRequest } from "relay-runtime";
export type PoolListingQueryVariables = {};
export type PoolListingQueryResponse = {
readonly currentUser: {
readonly wallet: {
readonly cakeBalance: string;
};
} | null;
};
export type PoolListingQuery = {
readonly response: PoolListingQueryResponse;
readonly variables: PoolListingQueryVariables;
};
/*
query PoolListingQuery {
currentUser {
wallet {
cakeBalance
}
id
}
}
*/
const node: ConcreteRequest = (function(){
var v0 = {
"alias": null,
"args": null,
"concreteType": "Wallet",
"kind": "LinkedField",
"name": "wallet",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "cakeBalance",
"storageKey": null
}
],
"storageKey": null
};
return {
"fragment": {
"argumentDefinitions": [],
"kind": "Fragment",
"metadata": null,
"name": "PoolListingQuery",
"selections": [
{
"alias": null,
"args": null,
"concreteType": "User",
"kind": "LinkedField",
"name": "currentUser",
"plural": false,
"selections": [
(v0/*: any*/)
],
"storageKey": null
}
],
"type": "Query",
"abstractKey": null
},
"kind": "Request",
"operation": {
"argumentDefinitions": [],
"kind": "Operation",
"name": "PoolListingQuery",
"selections": [
{
"alias": null,
"args": null,
"concreteType": "User",
"kind": "LinkedField",
"name": "currentUser",
"plural": false,
"selections": [
(v0/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "id",
"storageKey": null
}
],
"storageKey": null
}
]
},
"params": {
"cacheID": "555226365d27590d8236ea1effdf9ddc",
"id": null,
"metadata": {},
"name": "PoolListingQuery",
"operationKind": "query",
"text": "query PoolListingQuery {\n currentUser {\n wallet {\n cakeBalance\n }\n id\n }\n}\n"
}
};
})();
(node as any).hash = 'afdc45802c0d92b114c2ebb5c3530ec2';
export default node;

View File

@@ -9,6 +9,7 @@ import { commitCreateSellCryptoOrderMutation } from "./createSellCryptoOrder";
import { commitCreateBuyCryptoOrderMutation } from "./createBuyCryptoOrder"; import { commitCreateBuyCryptoOrderMutation } from "./createBuyCryptoOrder";
import { Input, Button } from "../../../../components"; import { Input, Button } from "../../../../components";
import type { ExchangePanel_user$key } from "./__generated__/ExchangePanel_user.graphql"; import type { ExchangePanel_user$key } from "./__generated__/ExchangePanel_user.graphql";
import { formatCake } from "../../../../utils/cake";
const tabBaseStyles = const tabBaseStyles =
"w-full text-base font-bold text-black px-4 py-2 focus:ring-blue-500"; "w-full text-base font-bold text-black px-4 py-2 focus:ring-blue-500";
@@ -32,14 +33,15 @@ export const ExchangePanel: FC<Props> = ({ userRef }) => {
fiatBalance { fiatBalance {
amountCents amountCents
} }
wallet {
cakeBalance
}
} }
`, `,
userRef userRef
); );
// TODO<wallet>: puxar valor da wallet const balanceAmount = formatCake(user?.wallet.cakeBalance);
const balanceAmount = 0;
const fiatBalanceAmount = user?.fiatBalance.amountCents ?? 0; const fiatBalanceAmount = user?.fiatBalance.amountCents ?? 0;
const avaliableCrypto = new BigNumber(balanceAmount); const avaliableCrypto = new BigNumber(balanceAmount);

View File

@@ -8,6 +8,9 @@ export type ExchangePanel_user = {
readonly fiatBalance: { readonly fiatBalance: {
readonly amountCents: number; readonly amountCents: number;
}; };
readonly wallet: {
readonly cakeBalance: string;
};
readonly " $refType": "ExchangePanel_user"; readonly " $refType": "ExchangePanel_user";
}; };
export type ExchangePanel_user$data = ExchangePanel_user; export type ExchangePanel_user$data = ExchangePanel_user;
@@ -41,10 +44,28 @@ const node: ReaderFragment = {
} }
], ],
"storageKey": null "storageKey": null
},
{
"alias": null,
"args": null,
"concreteType": "Wallet",
"kind": "LinkedField",
"name": "wallet",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "cakeBalance",
"storageKey": null
}
],
"storageKey": null
} }
], ],
"type": "User", "type": "User",
"abstractKey": null "abstractKey": null
}; };
(node as any).hash = '2058ddb20a60f148a524083fa0a680ea'; (node as any).hash = '88cc0dedfa3a3b9bb73d6b4745e0cf5a';
export default node; export default node;

View File

@@ -68,6 +68,9 @@ fragment ExchangePanel_user on User {
amountCents amountCents
id id
} }
wallet {
cakeBalance
}
} }
*/ */
@@ -192,6 +195,24 @@ return {
], ],
"storageKey": null "storageKey": null
}, },
{
"alias": null,
"args": null,
"concreteType": "Wallet",
"kind": "LinkedField",
"name": "wallet",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "cakeBalance",
"storageKey": null
}
],
"storageKey": null
},
(v0/*: any*/) (v0/*: any*/)
], ],
"storageKey": null "storageKey": null
@@ -301,12 +322,12 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "30aa6f9d81cfe033aee64b8577d15936", "cacheID": "2168c066ea4bb43d5ab066a00a35a33b",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "ExchangeQuery", "name": "ExchangeQuery",
"operationKind": "query", "operationKind": "query",
"text": "query ExchangeQuery {\n currentUser {\n ...ExchangePanel_user\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_user on User {\n fiatBalance {\n amountCents\n id\n }\n}\n" "text": "query ExchangeQuery {\n currentUser {\n ...ExchangePanel_user\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_user on User {\n fiatBalance {\n amountCents\n id\n }\n wallet {\n cakeBalance\n }\n}\n"
} }
}; };
})(); })();

View File

@@ -1,13 +1,30 @@
import { graphql } from "babel-plugin-relay/macro";
import type { FC } from "react"; import type { FC } from "react";
import React from "react"; import React from "react";
import { useFragment } from "react-relay";
import { Table, TableRow } from "../../components"; import { Table, TableRow } from "../../components";
import { formatCake } from "../../utils/cake";
import { getCurrencyLogo } from "../../utils/getCurrencyLogo"; import { getCurrencyLogo } from "../../utils/getCurrencyLogo";
import type { Balance_wallet$key } from "./__generated__/Balance_wallet.graphql";
export const Balance: FC = () => { type Props = {
const node = { userRef: Balance_wallet$key;
amount: "PUXAR VALOR DA CARTEIRA", };
};
export const Balance: FC<Props> = ({ userRef }) => {
const { wallet } = useFragment<Balance_wallet$key>(
graphql`
fragment Balance_wallet on User {
wallet {
cakeBalance
}
}
`,
userRef
);
const cakeBalance = formatCake(wallet.cakeBalance);
return ( return (
<div className="-mx-4 sm:-mx-8 px-4 sm:px-8 py-4 overflow-x-auto"> <div className="-mx-4 sm:-mx-8 px-4 sm:px-8 py-4 overflow-x-auto">
@@ -27,7 +44,7 @@ export const Balance: FC = () => {
<p className="text-gray-900 whitespace-no-wrap">CAKE</p> <p className="text-gray-900 whitespace-no-wrap">CAKE</p>
</div> </div>
</div>, </div>,
node.amount, cakeBalance,
]} ]}
/> />
</Table> </Table>

View File

@@ -6,22 +6,24 @@ import { useFragment } from "react-relay";
import type { FiatBalance_fiatBalance$key } from "./__generated__/FiatBalance_fiatBalance.graphql"; import type { FiatBalance_fiatBalance$key } from "./__generated__/FiatBalance_fiatBalance.graphql";
type Props = { type Props = {
fiatBalancesRef: FiatBalance_fiatBalance$key; userRef: FiatBalance_fiatBalance$key;
}; };
export const FiatBalance: FC<Props> = ({ fiatBalancesRef }) => { export const FiatBalance: FC<Props> = ({ userRef }) => {
const userFiatBalance = useFragment<FiatBalance_fiatBalance$key>( const { fiatBalance } = useFragment<FiatBalance_fiatBalance$key>(
graphql` graphql`
fragment FiatBalance_fiatBalance on FiatBalance { fragment FiatBalance_fiatBalance on User {
fiatBalance {
amountCents amountCents
amountCurrency amountCurrency
} }
}
`, `,
fiatBalancesRef userRef
); );
if (!userFiatBalance) return null; if (!fiatBalance) return null;
const { amountCents, amountCurrency } = userFiatBalance; const { amountCents, amountCurrency } = fiatBalance;
const amount = (amountCents ? amountCents / 100 : 0).toFixed(2); const amount = (amountCents ? amountCents / 100 : 0).toFixed(2);

View File

@@ -15,9 +15,8 @@ export const Wallet: FC = () => {
graphql` graphql`
query WalletQuery { query WalletQuery {
currentUser { currentUser {
fiatBalance {
...FiatBalance_fiatBalance ...FiatBalance_fiatBalance
} ...Balance_wallet
} }
} }
`, `,
@@ -30,8 +29,8 @@ export const Wallet: FC = () => {
<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">
<FiatBalance fiatBalancesRef={currentUser.fiatBalance} /> <FiatBalance userRef={currentUser} />
<Balance /> <Balance userRef={currentUser} />
</div> </div>
</div> </div>
</div> </div>

View File

@@ -0,0 +1,50 @@
/* tslint:disable */
/* eslint-disable */
// @ts-nocheck
import { ReaderFragment } from "relay-runtime";
import { FragmentRefs } from "relay-runtime";
export type Balance_wallet = {
readonly wallet: {
readonly cakeBalance: string;
};
readonly " $refType": "Balance_wallet";
};
export type Balance_wallet$data = Balance_wallet;
export type Balance_wallet$key = {
readonly " $data"?: Balance_wallet$data;
readonly " $fragmentRefs": FragmentRefs<"Balance_wallet">;
};
const node: ReaderFragment = {
"argumentDefinitions": [],
"kind": "Fragment",
"metadata": null,
"name": "Balance_wallet",
"selections": [
{
"alias": null,
"args": null,
"concreteType": "Wallet",
"kind": "LinkedField",
"name": "wallet",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "cakeBalance",
"storageKey": null
}
],
"storageKey": null
}
],
"type": "User",
"abstractKey": null
};
(node as any).hash = '27ddb42954aa66b033735eeea5746516';
export default node;

View File

@@ -5,8 +5,10 @@
import { ReaderFragment } from "relay-runtime"; import { ReaderFragment } from "relay-runtime";
import { FragmentRefs } from "relay-runtime"; import { FragmentRefs } from "relay-runtime";
export type FiatBalance_fiatBalance = { export type FiatBalance_fiatBalance = {
readonly fiatBalance: {
readonly amountCents: number; readonly amountCents: number;
readonly amountCurrency: string; readonly amountCurrency: string;
};
readonly " $refType": "FiatBalance_fiatBalance"; readonly " $refType": "FiatBalance_fiatBalance";
}; };
export type FiatBalance_fiatBalance$data = FiatBalance_fiatBalance; export type FiatBalance_fiatBalance$data = FiatBalance_fiatBalance;
@@ -22,6 +24,14 @@ const node: ReaderFragment = {
"kind": "Fragment", "kind": "Fragment",
"metadata": null, "metadata": null,
"name": "FiatBalance_fiatBalance", "name": "FiatBalance_fiatBalance",
"selections": [
{
"alias": null,
"args": null,
"concreteType": "FiatBalance",
"kind": "LinkedField",
"name": "fiatBalance",
"plural": false,
"selections": [ "selections": [
{ {
"alias": null, "alias": null,
@@ -38,8 +48,11 @@ const node: ReaderFragment = {
"storageKey": null "storageKey": null
} }
], ],
"type": "FiatBalance", "storageKey": null
}
],
"type": "User",
"abstractKey": null "abstractKey": null
}; };
(node as any).hash = 'dc28e4dca104c7d25465a30412661af2'; (node as any).hash = '4371bbd59e9a50e7f32aa65bf982c19e';
export default node; export default node;

View File

@@ -7,9 +7,7 @@ import { FragmentRefs } from "relay-runtime";
export type WalletQueryVariables = {}; export type WalletQueryVariables = {};
export type WalletQueryResponse = { export type WalletQueryResponse = {
readonly currentUser: { readonly currentUser: {
readonly fiatBalance: { readonly " $fragmentRefs": FragmentRefs<"FiatBalance_fiatBalance" | "Balance_wallet">;
readonly " $fragmentRefs": FragmentRefs<"FiatBalance_fiatBalance">;
};
} | null; } | null;
}; };
export type WalletQuery = { export type WalletQuery = {
@@ -22,17 +20,24 @@ export type WalletQuery = {
/* /*
query WalletQuery { query WalletQuery {
currentUser { currentUser {
fiatBalance {
...FiatBalance_fiatBalance ...FiatBalance_fiatBalance
id ...Balance_wallet
}
id id
} }
} }
fragment FiatBalance_fiatBalance on FiatBalance { fragment Balance_wallet on User {
wallet {
cakeBalance
}
}
fragment FiatBalance_fiatBalance on User {
fiatBalance {
amountCents amountCents
amountCurrency amountCurrency
id
}
} }
*/ */
@@ -58,22 +63,16 @@ return {
"kind": "LinkedField", "kind": "LinkedField",
"name": "currentUser", "name": "currentUser",
"plural": false, "plural": false,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "FiatBalance",
"kind": "LinkedField",
"name": "fiatBalance",
"plural": false,
"selections": [ "selections": [
{ {
"args": null, "args": null,
"kind": "FragmentSpread", "kind": "FragmentSpread",
"name": "FiatBalance_fiatBalance" "name": "FiatBalance_fiatBalance"
} },
], {
"storageKey": null "args": null,
"kind": "FragmentSpread",
"name": "Balance_wallet"
} }
], ],
"storageKey": null "storageKey": null
@@ -122,6 +121,24 @@ return {
], ],
"storageKey": null "storageKey": null
}, },
{
"alias": null,
"args": null,
"concreteType": "Wallet",
"kind": "LinkedField",
"name": "wallet",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "cakeBalance",
"storageKey": null
}
],
"storageKey": null
},
(v0/*: any*/) (v0/*: any*/)
], ],
"storageKey": null "storageKey": null
@@ -129,14 +146,14 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "4397ad78f82d23c0a186b71bea7c3898", "cacheID": "4631f43e84d22d8fdfa82706d907f478",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "WalletQuery", "name": "WalletQuery",
"operationKind": "query", "operationKind": "query",
"text": "query WalletQuery {\n currentUser {\n fiatBalance {\n ...FiatBalance_fiatBalance\n id\n }\n id\n }\n}\n\nfragment FiatBalance_fiatBalance on FiatBalance {\n amountCents\n amountCurrency\n}\n" "text": "query WalletQuery {\n currentUser {\n ...FiatBalance_fiatBalance\n ...Balance_wallet\n id\n }\n}\n\nfragment Balance_wallet on User {\n wallet {\n cakeBalance\n }\n}\n\nfragment FiatBalance_fiatBalance on User {\n fiatBalance {\n amountCents\n amountCurrency\n id\n }\n}\n"
} }
}; };
})(); })();
(node as any).hash = '83fd609428103b13e79c14d20fefaabe'; (node as any).hash = 'a91fc17a25b5a68672b3016813de17bc';
export default node; export default node;

View File

@@ -0,0 +1,2 @@
export const formatCake = (value?: string) =>
parseFloat(value ?? "0").toFixed(5);

View File

@@ -5,6 +5,10 @@ module Processable
included do included do
enumerize :status, in: [:processing, :completed, :canceled], default: :processing enumerize :status, in: [:processing, :completed, :canceled], default: :processing
status.values.each do |value|
scope value, -> { where(status: value) }
end
end end
def processing? def processing?

View File

@@ -0,0 +1,21 @@
# frozen_string_literal: true
class BscClient
include HTTParty
base_uri "api-eu1.tatum.io/v3"
def initialize
@headers = {
"x-api-key": ENV["TATUM_API_KEY"],
}
end
def token_balance(token, token_decimals, wallet_address)
result = self.class.get(
"https://api-eu1.tatum.io/v3/blockchain/token/balance/BSC/#{token}/#{wallet_address}",
headers: @headers
).parsed_response["balance"]
result.to_f / (10**token_decimals)
end
end

View File

@@ -0,0 +1,22 @@
# frozen_string_literal: true
class Wallet
attr_reader :user, :address, :cake_balance
def initialize(user)
@user = user
@address = user.wallet_address
@cake_balance = total_cake
end
private
def total_cake
return "0" if address.blank?
BscClient.new.token_balance(
"0x0e09fabb73bd3ade0a17ecc321fd13a19e81ce82",
18,
address,
)
end
end