Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds newly supported classic ops, tweaks route and query for history #8

Merged
merged 23 commits into from
Dec 13, 2023
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
a8f793d
adds newly supported classic ops, tweaks route and query for history
aristidesstaffieri Nov 20, 2023
4ef8f68
uses correct xdr key for transfer from
aristidesstaffieri Nov 20, 2023
304c16c
adds classic side balances query, adds history formatter first key
aristidesstaffieri Nov 21, 2023
3afa0c2
adds keys for account history items in history transformer
aristidesstaffieri Nov 21, 2023
ed05853
adds rpc compatible formatter for token op details
aristidesstaffieri Nov 22, 2023
9b80708
adds remaining classic side ops to history
aristidesstaffieri Nov 22, 2023
3e871e8
catch up to main branch, update transformer to match horizon response
aristidesstaffieri Nov 29, 2023
9e735ff
updates test for new wuery patterns and transform patterns
aristidesstaffieri Nov 29, 2023
a672def
use symbols instead of strings when subscribing to token events
aristidesstaffieri Nov 29, 2023
3b076c8
removes unused import
aristidesstaffieri Nov 29, 2023
b6c9584
Merge remote-tracking branch 'origin' into feat/more-classic-ops
aristidesstaffieri Nov 29, 2023
476d03d
add formatter to xlm balance in transformer to match horizon schema
aristidesstaffieri Nov 29, 2023
6441b53
remove decimals for classic balances, clients assume 7 currently
aristidesstaffieri Nov 30, 2023
28c62fe
uses ascii version of asset code for composite key in map
aristidesstaffieri Nov 30, 2023
1321cae
tweaks response for balances when asset is classic side
aristidesstaffieri Nov 30, 2023
e8b6c6b
adds starting balance to payments queries
aristidesstaffieri Nov 30, 2023
ecaa84c
adds asset type, asset type interface, and balance type to tx history
aristidesstaffieri Dec 1, 2023
ce70f29
Merge remote-tracking branch 'origin' into feat/more-classic-ops
aristidesstaffieri Dec 4, 2023
51e5f4e
adds network option to all routes, updates test
aristidesstaffieri Dec 5, 2023
45fccf8
fixes bad logic in fallback horizon response builder
aristidesstaffieri Dec 5, 2023
ce46724
removes extra log in service
aristidesstaffieri Dec 7, 2023
88eded1
adds txInfoByTx to all classic side op queries in history
aristidesstaffieri Dec 13, 2023
52f73be
adds ledger close time to all tx info blocks
aristidesstaffieri Dec 13, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/helper/format.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import BigNumber from "bignumber.js";

// Adopted from https://github.com/ethers-io/ethers.js/blob/master/packages/bignumber/src.ts/fixednumber.ts#L27
export const formatTokenAmount = (amount: BigNumber, decimals: number) => {
let formatted = amount.toString();

if (decimals > 0) {
formatted = amount.shiftedBy(-decimals).toFixed(decimals).toString();

// Trim trailing zeros
while (formatted[formatted.length - 1] === "0") {
formatted = formatted.substring(0, formatted.length - 1);
}

if (formatted.endsWith(".")) {
formatted = formatted.substring(0, formatted.length - 1);
}
}

return formatted;
};
30 changes: 30 additions & 0 deletions src/helper/horizon-rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { AssetType, Horizon } from "stellar-sdk";

export const BASE_RESERVE = 0.5;
export const BASE_RESERVE_MIN_COUNT = 2;
const TRANSACTIONS_LIMIT = 100;

export interface Issuer {
key: string;
Expand Down Expand Up @@ -75,6 +76,16 @@ export function getBalanceIdentifier(
}
}

export function getAssetType(code?: string) {
if (!code) {
return "native";
}
if (code.length > 4) {
return "credit_alphanum12";
}
return "credit_alphanum4";
}

export const makeDisplayableBalances = (
accountDetails: Horizon.ServerApi.AccountRecord
) => {
Expand Down Expand Up @@ -199,3 +210,22 @@ export const fetchAccountDetails = async (
throw new Error(JSON.stringify(error));
}
};

export const fetchAccountHistory = async (
pubKey: string,
server: Horizon.Server
) => {
try {
const operationsData = await server
.operations()
.forAccount(pubKey)
.order("desc")
.join("transactions")
.limit(TRANSACTIONS_LIMIT)
.call();

return operationsData.records || [];
} catch (error) {
throw new Error(JSON.stringify(error));
}
};
3 changes: 1 addition & 2 deletions src/helper/soroban-rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ import {
xdr,
SorobanRpc,
} from "stellar-sdk";

type NetworkNames = keyof typeof Networks;
import { NetworkNames } from "./validate";

const SOROBAN_RPC_URLS: { [key in keyof typeof Networks]?: string } = {
TESTNET: "https://soroban-testnet.stellar.org/",
Expand Down
76 changes: 75 additions & 1 deletion src/helper/test-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,13 @@ const queryMockResponse = {
},
},
[query.getAccountHistory]: {
eventByContractId: {
transferFromEvent: {
edges: [],
},
transferToEvent: {
edges: [],
},
mintEvent: {
edges: [],
},
createAccountByPublicKey: {
Expand All @@ -116,13 +122,81 @@ const queryMockResponse = {
publickey:
"CCWAMYJME4H5CKG7OLXGC2T4M6FL52XCZ3OQOAV6LL3GLA4RO4WH3ASP",
},
assetByAsset: {
code: "DT",
issuer:
"CCWAMYJME4H5CKG7OLXGC2T4M6FL52XCZ3OQOAV6LL3GLA4RO4WH3ASP",
},
accountByDestination: {
publickey: pubKey,
},
},
},
],
},
pathPaymentsStrictSendByPublicKey: {
nodes: [],
},
pathPaymentsStrictSendToPublicKey: {
nodes: [],
},
pathPaymentsStrictReceiveByPublicKey: {
nodes: [],
},
pathPaymentsStrictReceiveToPublicKey: {
nodes: [],
},
manageBuyOfferByPublicKey: {
edges: [],
},
manageSellOfferByPublicKey: {
edges: [],
},
createPassiveSellOfferByPublicKey: {
nodes: [],
},
changeTrustByPublicKey: {
nodes: [],
},
accountMergeByPublicKey: {
edges: [],
},
bumpSequenceByPublicKey: {
edges: [],
},
claimClaimableBalanceByPublicKey: {
edges: [],
},
createClaimableBalanceByPublicKey: {
edges: [],
},
allowTrustByPublicKey: {
edges: [],
},
manageDataByPublicKey: {
edges: [],
},
beginSponsoringFutureReservesByPublicKey: {
edges: [],
},
endSponsoringFutureReservesByPublicKey: {
edges: [],
},
revokeSponsorshipByPublicKey: {
edges: [],
},
clawbackByPublicKey: {
edges: [],
},
setTrustLineFlagsByPublicKey: {
edges: [],
},
liquidityPoolDepositByPublicKey: {
edges: [],
},
liquidityPoolWithdrawByPublicKey: {
edges: [],
},
},
};

Expand Down
10 changes: 8 additions & 2 deletions src/helper/validate.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { StrKey } from "stellar-sdk";
import { Networks, StrKey } from "stellar-sdk";

export type NetworkNames = keyof typeof Networks;

const isContractId = (contractId: string) => {
try {
Expand All @@ -18,4 +20,8 @@ const isPubKey = (pubKey: string) => {
}
};

export { isContractId, isPubKey };
const isNetwork = (network: string): network is NetworkNames => {
return Object.keys(Networks).includes(network);
};

export { isContractId, isPubKey, isNetwork };
27 changes: 24 additions & 3 deletions src/route/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,38 @@
import { getDevServer, queryMockResponse, pubKey } from "../helper/test-helper";
import { transformAccountHistory } from "../service/mercury/helpers/transformers";
import { query } from "../service/mercury/queries";

describe("API routes", () => {
describe("/account-history/:pubKey", () => {
it("can fetch an account history for a pub key", async () => {
const tokenDetails = {
CCWAMYJME4H5CKG7OLXGC2T4M6FL52XCZ3OQOAV6LL3GLA4RO4WH3ASP: {
name: "Test Token",
symbol: "TST",
decimals: 7,
},
CBGTG7XFRY3L6OKAUTR6KGDKUXUQBX3YDJ3QFDYTGVMOM7VV4O7NCODG: {
name: "Test Token 2",
symbol: "TST",
decimals: 7,
},
};
const server = await getDevServer();
const response = await fetch(
`http://localhost:${
(server?.server?.address() as any).port
}/api/v1/account-history/${pubKey}`
);
const { data } = await response.json();
const data = await response.json();
expect(response.status).toEqual(200);
expect(data).toMatchObject(queryMockResponse[query.getAccountHistory]);
expect(data).toMatchObject(
transformAccountHistory(
{ data: queryMockResponse[query.getAccountHistory] } as any,
pubKey,
"TESTNET",
tokenDetails as any
)
);
server.close();
});

Expand All @@ -35,7 +55,7 @@ describe("API routes", () => {
const response = await fetch(
`http://localhost:${
(server?.server?.address() as any).port
}/api/v1/account-balances/${pubKey}?contract_ids=CCWAMYJME4H5CKG7OLXGC2T4M6FL52XCZ3OQOAV6LL3GLA4RO4WH3ASP`
}/api/v1/account-balances/${pubKey}?contract_ids=CCWAMYJME4H5CKG7OLXGC2T4M6FL52XCZ3OQOAV6LL3GLA4RO4WH3ASP&network=TESTNET`
);
expect(response.status).toEqual(200);
server.close();
Expand All @@ -47,6 +67,7 @@ describe("API routes", () => {
"CCWAMYJME4H5CKG7OLXGC2T4M6FL52XCZ3OQOAV6LL3GLA4RO4WH3ASP",
"CBGTG7XFRY3L6OKAUTR6KGDKUXUQBX3YDJ3QFDYTGVMOM7VV4O7NCODG",
],
network: "TESTNET",
};
const server = await getDevServer();
const response = await fetch(
Expand Down
Loading
Loading