Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ A breaking change will get clearly marked in this log.

## Unreleased

### Added
* Added
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: finish adding added 😉


### Fixed
* `RpcServer.pollTransaction` off-by-one: the polling loop used `<` instead of `<=`, causing one fewer attempt than configured([#1373](https://github.com/stellar/js-stellar-sdk/pull/1373)).
* `requestAirdrop` error path: fixed incorrect property access (`error.response.detail` instead of `error.response.data.detail`) when checking for `createAccountAlreadyExist` ([#1373](https://github.com/stellar/js-stellar-sdk/pull/1373)).
Expand All @@ -31,6 +34,8 @@ A breaking change will get clearly marked in this log.
* `AccountResponse` constructor now uses explicit field-by-field assignment instead of `Object.entries` dynamic assignment for type safety ([#1373](https://github.com/stellar/js-stellar-sdk/pull/1373)).
* Added `transactions` collection to `Api.AccountRecord` and `AccountResponse` ([#1373](https://github.com/stellar/js-stellar-sdk/pull/1373)).
* Added range checks for U32/I32 values in `Spec`: bigint values are now validated against min/max bounds before conversion, throwing a `RangeError` instead of silently truncating ([#1373](https://github.com/stellar/js-stellar-sdk/pull/1373)).
* `rpc.Server.getLatestLedger()` now includes `closeTime`, `headerXdr`, and `metadataXdr` in the typed response, with `headerXdr`/`metadataXdr` parsed into XDR objects instead of raw base64 strings ([#1389
](https://github.com/stellar/js-stellar-sdk/pull/1389)).

### Deprecated
* `BalanceResponse.revocable` is deprecated in favor of `authorizedToMaintainLiabilities`, which correctly reflects the trustline flag semantics ([#1372](https://github.com/stellar/js-stellar-sdk/pull/1372)).
Expand Down
16 changes: 16 additions & 0 deletions src/rpc/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,22 @@ export namespace Api {
id: string;
sequence: number;
protocolVersion: string;
closeTime: string;
/** a base-64 encoded {@link xdr.LedgerHeaderHistoryEntry} instance */
headerXdr: xdr.LedgerHeader;
/** a base-64 encoded {@link xdr.LedgerCloseMeta} instance */
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

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

GetLatestLedgerResponse JSDoc/typing is internally inconsistent: the comments say headerXdr/metadataXdr are base64-encoded XDR strings (and even reference xdr.LedgerHeaderHistoryEntry), but the types are parsed XDR objects (xdr.LedgerHeader / xdr.LedgerCloseMeta). Please update the docs to match the actual types (and ensure the referenced XDR type matches what parseRawLatestLedger returns).

Suggested change
/** a base-64 encoded {@link xdr.LedgerHeaderHistoryEntry} instance */
headerXdr: xdr.LedgerHeader;
/** a base-64 encoded {@link xdr.LedgerCloseMeta} instance */
/** a parsed {@link xdr.LedgerHeader} instance */
headerXdr: xdr.LedgerHeader;
/** a parsed {@link xdr.LedgerCloseMeta} instance */

Copilot uses AI. Check for mistakes.
metadataXdr: xdr.LedgerCloseMeta;
}

export interface RawGetLatestLedgerResponse {
id: string;
sequence: number;
protocolVersion: string;
closeTime: string;
/** a base-64 encoded {@link xdr.LedgerHeaderHistoryEntry} instance */
headerXdr: string;
/** a base-64 encoded {@link xdr.LedgerCloseMeta} instance */
metadataXdr: string;
}

export enum GetTransactionStatus {
Expand Down
18 changes: 18 additions & 0 deletions src/rpc/parsers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -295,3 +295,21 @@ export function parseRawLedger(raw: Api.RawLedgerResponse): Api.LedgerResponse {
headerXdr,
};
}

export function parseRawLatestLedger(
raw: Api.RawGetLatestLedgerResponse,
): Api.GetLatestLedgerResponse {
if (!raw.headerXdr || !raw.metadataXdr) {
throw new TypeError(`invalid response missing fields`);
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

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

parseRawLatestLedger throws a generic invalid response missing fields error when headerXdr/metadataXdr are absent. For debugging, please include which field(s) are missing (similar to parseRawLedger) and ideally mention the RPC method/response type in the message.

Suggested change
throw new TypeError(`invalid response missing fields`);
let missingFields: string;
if (!raw.metadataXdr && !raw.headerXdr) {
missingFields = "metadataXdr and headerXdr";
} else if (!raw.metadataXdr) {
missingFields = "metadataXdr";
} else {
missingFields = "headerXdr";
}
throw new TypeError(
`invalid getLatestLedger response missing fields: ${missingFields}`,
);

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This suggestion returns a better error for the user

}
const headerXdr = xdr.LedgerHeader.fromXDR(raw.headerXdr, "base64");
const metadataXdr = xdr.LedgerCloseMeta.fromXDR(raw.metadataXdr, "base64");
return {
id: raw.id,
sequence: raw.sequence,
protocolVersion: raw.protocolVersion,
closeTime: raw.closeTime,
headerXdr,
metadataXdr,
};
}
6 changes: 5 additions & 1 deletion src/rpc/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
parseRawTransactions,
parseTransactionInfo,
parseRawLedger,
parseRawLatestLedger,
} from "./parsers";
import { Utils } from "../utils";
import { HttpClient } from "../http-client";
Expand Down Expand Up @@ -954,8 +955,11 @@ export class RpcServer {
* console.log("protocolVersion:", response.protocolVersion);
* });
*/

public async getLatestLedger(): Promise<Api.GetLatestLedgerResponse> {
return this._getLatestLedger().then(parseRawLatestLedger);
}

public async _getLatestLedger(): Promise<Api.RawGetLatestLedgerResponse> {
return jsonrpc.postObject(
this.httpClient,
this.serverURL.toString(),
Expand Down
27 changes: 25 additions & 2 deletions test/unit/server/soroban/get_classic_entries.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,25 @@ function expectLedgerEntryFound(
},
},
};
mockPost.mockResolvedValue(mockResponse);
mockPost.mockImplementation((_: any, body: any) => {
if (body && body.method === "getLatestLedger") {
return Promise.resolve({
data: {
result: {
id: "hashed_id",
sequence: 123,
protocolVersion: 20,
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

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

Type mismatch: Api.RawGetLatestLedgerResponse.protocolVersion is declared as a string, but this getLatestLedger mock returns a number (20). Consider using a string here (or updating the API types/parsing if the RPC response is numeric) so tests validate the intended schema.

Suggested change
protocolVersion: 20,
protocolVersion: "20",

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We define protocolVersion as a string in GetLatestLedgerResponse. Is this using a different type?

closeTime: "124",
headerXdr:
"AAAAGrP0s/PGggfZROfm4UrD2ul0kjwslx8W5YhzlGrP1kmlLqJv3aMl3XEf5FOicCD8tDOT0RNfC5huOz82oO+R2lYAAAAAaeEr4gAAAAAAAAABAAAAALVdELK7fShO1cA6R6XhtZDJD1eDVUccxFB7voIE0jyLAAAAQEMyjPK8bIfQbIrUCHW40CP4+YvCImxg16wuSIjEl43NwDbpsGwu3wQmbi/u8WIZsL6MSTLMXlyXYJDZsRM1pQVU05gS2Au4O3vlO2eyFYdtVS8dCHe0xpQYHXySoXVMo7cVZULv/3jAlcjIvlsAn9k0QMOkSYl3lWBCxEKVK785AB+dnA3gtrOnZAAAAAABMFvNhVUAAAAAAAAAAAABiJMAAABkAExLQAAAAMgQFSWR4kocJqxbAsjAStNr1C1FPlc8QXXsjTfs9IydXFT0EtE8W/9jSNRWmLdX985erJs28eCPXUKZpEvoEx+1H5C0OqNqUACzQFS756EBZ0pgw/b3mKoBb8yYOXC9yWGOFIykqWNbxH+1ZyiD369YvoPJhDkeL1vb0PUdGO+NuAAAAAA=",
metadataXdr:
"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",
},
},
});
}
return Promise.resolve(mockResponse);
});

return call().then((entry: any) => {
expect(entry).toBeInstanceOf(expectedType);
Expand Down Expand Up @@ -58,7 +76,12 @@ function expectLedgerEntryNotFound(
},
},
};
mockPost.mockResolvedValue(mockResponse);
mockPost.mockImplementation((url: any, body: any) => {
if (body && body.method === "getLatestLedger") {
return Promise.resolve({ data: { result: { latestLedger: 0 } } });
}
return Promise.resolve(mockResponse);
});

return call()
.then(() => Promise.reject(new Error("Expected rejection")))
Expand Down
16 changes: 15 additions & 1 deletion test/unit/server/soroban/get_latest_ledger.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { StellarSdk } from "../../../test-utils/stellar-sdk-import";
import { serverUrl } from "../../../constants";

const { Server } = StellarSdk.rpc;
const { xdr } = StellarSdk;

describe("Server#getLatestLedger", () => {
let server: any;
Expand All @@ -23,12 +24,25 @@ describe("Server#getLatestLedger", () => {
id: "hashed_id",
sequence: 123,
protocolVersion: 20,
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

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

Type mismatch: Api.RawGetLatestLedgerResponse.protocolVersion is declared as a string, but this mock response uses a number (20). This makes it easy for runtime/type drift to slip through—either update the mock to a string value or adjust the API types/parsing if the RPC actually returns a number.

Suggested change
protocolVersion: 20,
protocolVersion: "20",

Copilot uses AI. Check for mistakes.
closeTime: "124",
headerXdr:
"AAAAGrP0s/PGggfZROfm4UrD2ul0kjwslx8W5YhzlGrP1kmlLqJv3aMl3XEf5FOicCD8tDOT0RNfC5huOz82oO+R2lYAAAAAaeEr4gAAAAAAAAABAAAAALVdELK7fShO1cA6R6XhtZDJD1eDVUccxFB7voIE0jyLAAAAQEMyjPK8bIfQbIrUCHW40CP4+YvCImxg16wuSIjEl43NwDbpsGwu3wQmbi/u8WIZsL6MSTLMXlyXYJDZsRM1pQVU05gS2Au4O3vlO2eyFYdtVS8dCHe0xpQYHXySoXVMo7cVZULv/3jAlcjIvlsAn9k0QMOkSYl3lWBCxEKVK785AB+dnA3gtrOnZAAAAAABMFvNhVUAAAAAAAAAAAABiJMAAABkAExLQAAAAMgQFSWR4kocJqxbAsjAStNr1C1FPlc8QXXsjTfs9IydXFT0EtE8W/9jSNRWmLdX985erJs28eCPXUKZpEvoEx+1H5C0OqNqUACzQFS756EBZ0pgw/b3mKoBb8yYOXC9yWGOFIykqWNbxH+1ZyiD369YvoPJhDkeL1vb0PUdGO+NuAAAAAA=",
metadataXdr:
"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",
};
const expectedResponse = {
id: result.id,
sequence: result.sequence,
protocolVersion: result.protocolVersion,
closeTime: result.closeTime,
headerXdr: xdr.LedgerHeader.fromXDR(result.headerXdr, "base64"),
metadataXdr: xdr.LedgerCloseMeta.fromXDR(result.metadataXdr, "base64"),
};
const mockResponse = { data: { result } };
mockPost.mockResolvedValue(mockResponse);

const response = await server.getLatestLedger();
expect(response).toEqual(result);
expect(response).toEqual(expectedResponse);
expect(mockPost).toHaveBeenCalledWith(serverUrl, {
jsonrpc: "2.0",
id: 1,
Expand Down
Loading