Skip to content

Tsm operation generic#949

Merged
Ryang-21 merged 9 commits intotypescript-migrationfrom
tsm-operation-generic
Mar 25, 2026
Merged

Tsm operation generic#949
Ryang-21 merged 9 commits intotypescript-migrationfrom
tsm-operation-generic

Conversation

@Ryang-21
Copy link
Contributor

What

  • Added Operation generic for preserving operation type on xdr <-> Operation roundtrip. This ensures backwards compatibility with manual type declarations
  • Moved generated xdr type declarations to src under ./src/generated to fix circular dependency in type declarations
  • Added types/test.ts to prettierignore to prevent formatting breaking type assertions

@github-actions
Copy link

github-actions bot commented Mar 24, 2026

Size Change: 0 B

Total Size: 1.76 MB

ℹ️ View Unchanged
Filename Size
dist/stellar-base.cjs.js 696 kB
dist/stellar-base.js 715 kB
dist/stellar-base.min.js 346 kB

compressed-size-action

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces a generic xdr.Operation<T> typing flow so Operation.fromXDRObject() can preserve the specific operation result type across an XDR → Operation roundtrip, and it relocates generated XDR .d.ts wiring under src/generated to avoid declaration circularities.

Changes:

  • Add a generic parameter to Operation.fromXDRObject() and update many operation builders to return xdr.Operation<SpecificResultType>.
  • Rework signer-related types (SignerOpts, SetOptionsOpts<T>, SetOptionsResult<T>) to support more precise typing.
  • Update generated XDR .d.ts link files and build/type tooling ignores (notably .prettierignore, type assertion test expectations).

Reviewed changes

Copilot reviewed 33 out of 37 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
types/test.ts Updates $ExpectType assertions to reflect the new generic fromXDRObject typing.
test/unit/operations/clawback_claimable_balance.test.ts Minor formatting change to an expectation.
src/operations/types.ts Introduces new signer option types, updates result/opts types to use them, and adjusts OperationRecord docs.
src/operations/set_trustline_flags.ts Returns xdr.Operation<SetTrustLineFlagsResult> for typed roundtrip.
src/operations/set_options.ts Makes setOptions generic and returns xdr.Operation<SetOptionsResult<T>>.
src/operations/revoke_sponsorship.ts Returns typed xdr.Operation<...Result> variants for revoke sponsorship ops.
src/operations/restore_footprint.ts Returns xdr.Operation<RestoreFootprintResult>.
src/operations/payment.ts Returns xdr.Operation<PaymentResult>.
src/operations/path_payment_strict_send.ts Returns xdr.Operation<PathPaymentStrictSendResult>.
src/operations/path_payment_strict_receive.ts Returns xdr.Operation<PathPaymentStrictReceiveResult>.
src/operations/manage_sell_offer.ts Returns xdr.Operation<ManageSellOfferResult>.
src/operations/manage_data.ts Returns xdr.Operation<ManageDataResult>.
src/operations/manage_buy_offer.ts Returns xdr.Operation<ManageBuyOfferResult>.
src/operations/liquidity_pool_withdraw.ts Returns xdr.Operation<LiquidityPoolWithdrawResult>.
src/operations/liquidity_pool_deposit.ts Returns xdr.Operation<LiquidityPoolDepositResult>.
src/operations/invoke_host_function.ts Returns xdr.Operation<InvokeHostFunctionResult> for host-function-related builders.
src/operations/inflation.ts Returns xdr.Operation<InflationResult>.
src/operations/extend_footprint_ttl.ts Returns xdr.Operation<ExtendFootprintTTLResult>.
src/operations/end_sponsoring_future_reserves.ts Returns xdr.Operation<EndSponsoringFutureReservesResult>.
src/operations/create_passive_sell_offer.ts Returns xdr.Operation<CreatePassiveSellOfferResult>.
src/operations/create_claimable_balance.ts Returns xdr.Operation<CreateClaimableBalanceResult>.
src/operations/create_account.ts Returns xdr.Operation<CreateAccountResult>.
src/operations/clawback_claimable_balance.ts Returns xdr.Operation<ClawbackClaimableBalanceResult>.
src/operations/clawback.ts Returns xdr.Operation<ClawbackResult>.
src/operations/claim_claimable_balance.ts Returns xdr.Operation<ClaimClaimableBalanceResult>.
src/operations/change_trust.ts Returns xdr.Operation<ChangeTrustResult>.
src/operations/bump_sequence.ts Returns xdr.Operation<BumpSequenceResult>.
src/operations/begin_sponsoring_future_reserves.ts Returns xdr.Operation<BeginSponsoringFutureReservesResult>.
src/operations/allow_trust.ts Returns xdr.Operation<AllowTrustResult>.
src/operations/account_merge.ts Returns xdr.Operation<AccountMergeResult>.
src/operation.ts Makes fromXDRObject accept xdr.Operation<T> to preserve operation type through the roundtrip.
src/generated/next_generated.d.ts Repoints xdr type exports to the local generated declarations.
src/generated/next.d.ts Updates the Operation generic constraint import to reference OperationRecord.
src/generated/curr_generated.d.ts Repoints xdr type exports to the local generated declarations.
src/generated/curr.d.ts Updates the Operation generic constraint to use OperationRecord.
package.json Adjusts build:types copying to only include src/generated/*.d.ts.
.prettierignore Fixes ignore paths and adds types/test.ts to avoid Prettier breaking type assertions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 208 to +216
const newSignerXDR1 = StellarSdk.Operation.setOptions({
signer: { ed25519PublicKey: sourceKey.publicKey(), weight: '1' }
});
const newSigner1 = StellarSdk.Operation.fromXDRObject(newSignerXDR1); // $ExpectType OperationRecord
if (newSigner1.type === 'setOptions') {
newSigner1.signer; // $ExpectType Signer | undefined
}
StellarSdk.Operation.fromXDRObject(newSignerXDR1); // $ExpectType SetOptionsResult<{ ed25519PublicKey: string; weight: string; }>

const newSignerXDR2 = StellarSdk.Operation.setOptions({
signer: { sha256Hash: Buffer.from(''), weight: '1' }
});
const newSigner2 = StellarSdk.Operation.fromXDRObject(newSignerXDR2); // $ExpectType OperationRecord
if (newSigner2.type === 'setOptions') {
newSigner2.signer; // $ExpectType Signer | undefined
}
StellarSdk.Operation.fromXDRObject(newSignerXDR2); // $ExpectType SetOptionsResult<{ sha256Hash: Buffer<ArrayBuffer>; weight: string; }>
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

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

These $ExpectType assertions for Operation.fromXDRObject(Operation.setOptions(...)) appear to encode the input signer types (e.g. weight: string), but fromXDRObject() reads the weight from XDR and returns it as a number. If the goal is to preserve the operation kind (not the un-normalized input types), the expected types here should likely use weight: number (and Buffer<ArrayBufferLike> for sha256Hash, consistent with the rest of this file).

Copilot uses AI. Check for mistakes.
Comment on lines +99 to +101
export interface BaseSignerOpt {
weight?: number | string;
}
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

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

SignerOpts makes weight optional via BaseSignerOpt, but Operation.setOptions() requires signer.weight at runtime (it passes weight! into new xdr.Signer(...)). This allows code to type-check while producing an invalid XDR / runtime exception when weight is omitted. Suggestion: keep SignerKey-only types for cases like revoke-signer, and introduce a separate SetOptionsSignerOpts where weight is required (or make weight required in SignerOpts and use a different type for revoke-signer).

Copilot uses AI. Check for mistakes.
Comment on lines 242 to 245
export interface RevokeSignerSponsorshipOpts {
account: string;
signer: SignerKeyOptions;
signer: SignerOpts;
source?: string;
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

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

RevokeSignerSponsorshipOpts.signer is now typed as SignerOpts, which includes ed25519SignedPayload (and weight) even though revokeSignerSponsorship() only supports ed25519PublicKey, preAuthTx, and sha256Hash and ignores/throws for signed payload. This makes the public type contract broader than the implementation. Suggestion: use a dedicated RevokeSignerSponsorshipSignerOpts/SignerKeyOptions union that matches the supported signer key arms (or extend the implementation to handle ed25519SignedPayload).

Copilot uses AI. Check for mistakes.
Comment on lines +51 to 55
export function setOptions<T extends SignerOpts = never>(
this: OperationClass,
opts: SetOptionsOpts,
): xdr.Operation {
opts: SetOptionsOpts<T>,
): xdr.Operation<SetOptionsResult<T>> {
let inflationDest: xdr.AccountId | null = null;
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

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

The new generic signature ties the returned xdr.Operation type to the input signer shape (SetOptionsResult<T>). However, at runtime fromXDRObject() always returns signer.weight as a number (coming from XDR), even when the caller passed weight as a string. This can make the inferred return type from fromXDRObject(op) disagree with runtime values. Consider decoupling the generic from raw input types (e.g., return xdr.Operation<SetOptionsResult> with a normalized signer type) or normalizing the signer/weight types so the generic matches runtime.

Copilot uses AI. Check for mistakes.
source?: string;
}
export interface BaseSignerOpt {
weight?: number | string;
Copy link
Contributor

Choose a reason for hiding this comment

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

Should weight be required?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah it definitely should I am surprised it was not required prior

@Ryang-21 Ryang-21 merged commit 2688ae4 into typescript-migration Mar 25, 2026
7 checks passed
@Ryang-21 Ryang-21 deleted the tsm-operation-generic branch March 25, 2026 20:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TS migration: generated declarations diverge from hand-written public API

3 participants