Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"build": "npm run build:node && npm run build:browser",
"build:node": "tsup src/index.ts --env.NODE_ENV=node",
"build:browser": "tsup src/index.ts --env.NODE_ENV=browser",
"prepublish": "npm run build"
"prepublish": "npm run build",
"test": "vitest"
},
"repository": {
"type": "git",
Expand All @@ -29,7 +30,8 @@
"tsup": "^8.2.4",
"tsx": "4.19.0",
"typescript": "5.5.4",
"@types/node": "22.10.2"
"@types/node": "22.10.2",
"vitest": "^2.1.8"
},
"dependencies": {
"@connectrpc/connect": "1.4",
Expand Down
142 changes: 142 additions & 0 deletions test/index.test.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import { describe, test, expect } from "vitest";
import { QueryClient, SyncClient } from "../src/cardano";

describe("QueryClient", () => {
let queryClient = new QueryClient({
uri: "http://localhost:50051",
});
test("readParams", async () => {
const params = await queryClient.readParams();
expect(params).toEqual({
coinsPerUtxoByte: 0n,
maxTxSize: 4096n,
minFeeCoefficient: 0n,
minFeeConstant: 0n,
maxBlockBodySize: 0n,
maxBlockHeaderSize: 2000000n,
stakeKeyDeposit: 0n,
poolDeposit: 0n,
poolRetirementEpochBound: 0n,
desiredNumberOfPools: 0n,
minPoolCost: 0n,
maxValueSize: 0n,
collateralPercentage: 0n,
maxCollateralInputs: 0n
});
});
test("readUtxosByOutputRef", async () => {
const utxo = await queryClient.readUtxosByOutputRef([
{
txHash: Buffer.from("8c1cb0c06b48dc4238775f81f3276634fbc243131323be95767055ef3d095515", "hex"),
outputIndex: 0,
},
]);
expect(Buffer.from(utxo[0].nativeBytes!).toString("hex")).toEqual("8282d818582583581c73d9939a59f42a1f3ca3b6aba56f82e52de28c70cbe36870cff5a197a10242182a001aaa7d769f1ac7145b00");
});
test("searchUtxosByAddress", async () => {
const utxo = await queryClient.searchUtxosByAddress(Buffer.from("82d818582583581c73d9939a59f42a1f3ca3b6aba56f82e52de28c70cbe36870cff5a197a10242182a001aaa7d769f", "hex"));
expect(Buffer.from(utxo[0].nativeBytes!).toString("hex")).toEqual("8282d818582583581c73d9939a59f42a1f3ca3b6aba56f82e52de28c70cbe36870cff5a197a10242182a001aaa7d769f1ac7145b00");
});
test("searchUtxosByPaymentPart", async () => {
const utxo = await queryClient.searchUtxosByPaymentPart(Buffer.from("c8c47610a36034aac6fc58848bdae5c278d994ff502c05455e3b3ee8", "hex"));
expect(Buffer.from(utxo[0].nativeBytes!).toString("hex")).toEqual("82583900c8c47610a36034aac6fc58848bdae5c278d994ff502c05455e3b3ee8f8ed3a0eea0ef835ffa7bbfcde55f7fe9d2cc5d55ea62cecb42bab3c1b00000002540be400");
});
test("searchUtxosByDelegationPart", async () => {
const utxo = await queryClient.searchUtxosByDelegationPart(Buffer.from("f8ed3a0eea0ef835ffa7bbfcde55f7fe9d2cc5d55ea62cecb42bab3c", "hex"));
expect(Buffer.from(utxo[0].nativeBytes!).toString("hex")).toEqual("82583900c8c47610a36034aac6fc58848bdae5c278d994ff502c05455e3b3ee8f8ed3a0eea0ef835ffa7bbfcde55f7fe9d2cc5d55ea62cecb42bab3c1b00000002540be400");
});
test("searchUtxosByAsset", async () => {
const utxo = await queryClient.searchUtxosByAsset();
expect(utxo.length).toBe(0); // TODO: genesis has no custom assets, so we'd need to setup the tests for this
});
test("searchUtxosByAddressWithAsset", async () => {
const utxo = await queryClient.searchUtxosByAddressWithAsset(Buffer.from("82d818582583581c73d9939a59f42a1f3ca3b6aba56f82e52de28c70cbe36870cff5a197a10242182a001aaa7d769f", "hex"));
expect(utxo.length).toBe(0); // TODO: genesis has no custom assets, so we'd need to setup the tests for this
});
test("searchUtxosByPaymentPartWithAsset", async () => {
const utxo = await queryClient.searchUtxosByPaymentPartWithAsset(Buffer.from("c8c47610a36034aac6fc58848bdae5c278d994ff502c05455e3b3ee8", "hex"));
expect(utxo.length).toBe(0); // TODO: genesis has no custom assets, so we'd need to setup the tests for this
});
test("searchUtxosByDelegationPartWithAsset", async () => {
const utxo = await queryClient.searchUtxosByDelegationPartWithAsset(Buffer.from("f8ed3a0eea0ef835ffa7bbfcde55f7fe9d2cc5d55ea62cecb42bab3c", "hex"));
expect(utxo.length).toBe(0); // TODO: genesis has no custom assets, so we'd need to setup the tests for this
});
});

describe("SyncClient", () => {
let syncClient = new SyncClient({
uri: "http://localhost:50051",
});
test("followTip", async () => {
const generator = syncClient.followTip([{
slot: 601,
hash: 'f2158441116a89f567534577323deddc9b44422a06bebfde24b666292e4e3123',
}]);
const block1 = await (generator[Symbol.asyncIterator]()).next();
expect(block1).toStrictEqual({
value: {
action: 'reset',
point: {
slot: '601',
hash: 'f2158441116a89f567534577323deddc9b44422a06bebfde24b666292e4e3123'
}
},
done: false
});
const block2 = await (generator[Symbol.asyncIterator]()).next();
expect({ body: block2.value.block.body?.toJson(), header: block2.value.block.header?.toJson() }).toEqual({
body: {
// TODO: this is missing for some reason
// tx: [],
},
header: {
hash: "ENFFlzZi/rS1v86fbYRg+3xhAW9r7LzZ1MggN6m86rw=",
slot: "602",
height: "1",
}
})
});
test("readTip", async () => {
const tip = await syncClient.readTip();
expect(Number(tip.slot)).toBeGreaterThan(1)
});
test("fetchBlock", async () => {
const block = await syncClient.fetchBlock({
slot: 601,
hash: 'f2158441116a89f567534577323deddc9b44422a06bebfde24b666292e4e3123',
});
expect({ body: block.body?.toJson(), header: block.header?.toJson() }).toEqual({
body: {
// TODO: this is missing for some reason
// tx: [],
},
header: {
hash: "DdxBJbBKFI8l/2ybtQaqSs/7xEkCBymZGP3vwHWYFiU=",
slot: "601",
// TODO: this is missing for some reason
// height: "0",
}
})
});
test("fetchHistory", async () => {
const block = await syncClient.fetchHistory({
slot: 601,
hash: 'f2158441116a89f567534577323deddc9b44422a06bebfde24b666292e4e3123',
});
expect({ body: block.body?.toJson(), header: block.header?.toJson() }).toEqual({
body: {
// TODO: this is missing for some reason
// tx: [],
},
header: {
hash: "DdxBJbBKFI8l/2ybtQaqSs/7xEkCBymZGP3vwHWYFiU=",
slot: "601",
// TODO: this is missing for some reason
// height: "0",
Comment on lines +134 to +135
Copy link
Copy Markdown
Contributor Author

@SebastienGllmt SebastienGllmt Mar 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fields equal to the default value for the data type seem to be missing if you call toJson, so I think this is probably a bug in the toJson implementation (these fields are not optional)

Either that, or these are purposely left out as a performance improvement when sending data over the wire, and there is a separate way you're support to JSONify these objects when you care about getting the full object properly

}
})
});
});

// TODO: test SubmitClient. It's hard since it's stateful, so we need to mock the backend
// TODO: test WatchClient. It's hard since it's stateful, so we need to mock the backend
92 changes: 92 additions & 0 deletions test/shelley-genesis.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
{
"activeSlotsCoeff" : 1.0,
"epochLength" : 600,
"genDelegs" : {
"337bc5ef0f1abf205624555c13a37258c42b46b1259a6b1a6d82574e" : {
"delegate" : "41fd6bb31f34469320aa47cf6ccc3918e58a06d60ea1f2361efe2458",
"vrf" : "7053e3ecd2b19db13e5338aa75fb518fc08b6c218f56ad65760d3eb074be95d4"
}
},
"initialFunds" : {
"00c8c47610a36034aac6fc58848bdae5c278d994ff502c05455e3b3ee8f8ed3a0eea0ef835ffa7bbfcde55f7fe9d2cc5d55ea62cecb42bab3c" : 10000000000,
"004048ff89ca4f88e66598e620aa0c7128c2145d9a181ae9a4a81ca8e3e849af38840c5562dd382be37c9e76545c8191f9d8f6df1d20cfcee0" : 10000000000,
"00ca6e1b1f320d543a24adeabc0aa4627635c7349b639f86f74bdfdd78d31b28c9619a58b3792a7394ab85deb36889c4d7b0632c8167b855d2" : 10000000000,
"0007d781fe8e33883e371f9550c2f1087321fc32e06e80b65e349ccb027702d6880e86e77a0520efa37ede45002a1de43b68692e175b742e67" : 10000000000,
"00627b2598dd71129167825160c564067d1d245e79cc237094815c5cb2b125e30ec2f4ce4059a069e08c3cd82cdfc9451bfb22487f8a25ceef" : 10000000000,
"00c6cf7bd50f37f7e4cc161fc00f07e9b2226ba5552ccaf30d315fa0135bbc8cbd9ab5379f368fc8d3500c37a9d14074cc6ddad89e3686f0e0" : 10000000000,
"005164ab186715c86378020956d892cf72f67636b78967d67cfe7360479130dc89cf7a9bc89109f939956b66f93293ade4c3920b72fd40beea" : 10000000000,
"003dd38742e9848c6f12c13ddb1f9464fc0ce0bb92102768087975317e5a9f869fcd913562c9b0e0f01f77e5359ea780d37f9355f9702eff8b" : 10000000000,
"0088e7e670b45cab2322b518ef7b6f66d30aec0d923dc463e467091a790f67796b9fa71224f2846cebbcf4950c11e040ee124d30f6e164bcd5" : 10000000000,
"00c70b8421617802d3f23956cab1957e1d306cd4808589b41760e97927ebfd6053ba12b38288b2b6d5d4c4618d6a8ce59d50580e9c6f704af5" : 10000000000,
"00c0933b8238f6f3332e48c34cf1a8e0555943b33cd4abc53aefb7d6124b7ce40dd496bdc02b34602f3a773ff7cccee873991e4c8866f3a70b" : 10000000000,
"0069f7d7289de2f01cd1e0265ac5be943b41775abae0ce6b3eac0edee0ce9cadb7cdec2bded3ef8a7bbe3352869bfc1387754c9ee6b1782d9c" : 10000000000,
"00709a7070005c652c27df73dbbde3319a90b127bea96aded1c5fb87a59c51dbcf90fa890174497f3f66a0dad06eb7f131e06567995e9c50a5" : 10000000000,
"00fc576df3a279885a7a4d0fc500372daa1d96f26c6763542ecd2ad8551753024adea37c134edebb68dc0cfaed5a7009e8305fe1fed8d0ccd1" : 10000000000,
"003346a630e6972bf38cce87219db1d63061e7cd324cad88c18e504f2990cac68e973f51256ca938683fa4ea12173d7d047d940fbb883bd0e8" : 10000000000,
"0028b862d001e6a64a02b3560cbc532eab4557593477c39cc523e0b9fc527100898c11e731194171b908aad463770d6cbf7ec8871c4cb1e518" : 10000000000,
"005e0e57040b06e9d71e0f28f126262838a68db0b52b4fd1b3877dda2203d5d7d4f19c5ee3a1ed51bb670779de19d40aaff2e5e9468cc05c5e" : 10000000000,
"00367f65ab69b1e6715c8d5a14964214c9505ed17032266b3209a2c40dcbae9a2a881e603ff39d36e987bacfb87ee98051f222c5fe3efd350c" : 10000000000,
"00c5c4ca287f3b53948b5468e5e23b1c87fe61ce52c0d9afd65d070795038751a619d463e91eaed0a774ebdb2f8e12a01a378a153bc3627323" : 10000000000,
"00ef198fb7c35e1968308a0b75cfee54a46e13e86dd3354283300831d624165c357b5a0413906a0bfea8ba57587331f0836a186d632ed041b8" : 10000000000,
"60ba957a0fff6816021b2afa7900beea68fd10f2d78fb5b64de0d2379c" : 3000000000000000,
"007290ea8fa9433c1045a4c8473959ad608e6c03a58c7de33bdbd3ce6f295b987135610616f3c74e11c94d77b6ced5ccc93a7d719cfb135062" : 300000000000,
"605276322ac7882434173dcc6441905f6737689bd309b68ad8b3614fd8" : 3000000000000000,
"60a0f1aa7dca95017c11e7e373aebcf0c4568cf47ec12b94f8eb5bba8b" : 3000000000000000
},
"maxKESEvolutions" : 60,
"maxLovelaceSupply" : 45000000000000000,
"networkId" : "Testnet",
"networkMagic" : 42,
"protocolParams" : {
"a0" : 0.0,
"decentralisationParam" : 0,
"eMax" : 18,
"extraEntropy" : {
"tag" : "NeutralNonce"
},
"keyDeposit" : 2000000,
"maxBlockBodySize" : 90112,
"maxBlockHeaderSize" : 1100,
"maxTxSize" : 16384,
"minFeeA" : 44,
"minFeeB" : 155381,
"minPoolCost" : 170000000,
"minUTxOValue" : 1000000,
"nOpt" : 100,
"poolDeposit" : 500000000,
"protocolVersion" : {
"major" : 9,
"minor" : 0
},
"rho" : 0.003,
"tau" : 0.2
},
"securityParam" : 300,
"slotLength" : 1,
"slotsPerKESPeriod" : 129600,
"staking" : {
"pools" : {
"7301761068762f5900bde9eb7c1c15b09840285130f5b0f53606cc57" : {
"cost" : 340000000,
"margin" : 0,
"metadata" : null,
"owners" : [ ],
"pledge" : 0,
"publicKey" : "7301761068762f5900bde9eb7c1c15b09840285130f5b0f53606cc57",
"relays" : [ ],
"rewardAccount" : {
"credential" : {
"keyHash" : "11a14edf73b08a0a27cb98b2c57eb37c780df18fcfcf6785ed5df84a"
},
"network" : "Testnet"
},
"vrf" : "c2b62ffa92ad18ffc117ea3abeb161a68885000a466f9c71db5e4731d6630061"
}
},
"stake" : {
"295b987135610616f3c74e11c94d77b6ced5ccc93a7d719cfb135062" : "7301761068762f5900bde9eb7c1c15b09840285130f5b0f53606cc57"
}
},
"systemStart" : "2025-01-23T14:17:13.653573Z",
"updateQuorum" : 1
}
13 changes: 13 additions & 0 deletions vitest.config.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { defineConfig } from 'vitest/config'
import path from 'node:path'

export default defineConfig({
test: {
include: ['test/**/*.test.mts'],
},
resolve: {
alias: {
"@sdk/grpcTransport": path.resolve(__dirname, "./src/grpcTransport.node.ts"),
},
},
})