Skip to content

Conversation

dynst
Copy link
Contributor

@dynst dynst commented Jun 12, 2025

TypeScript return types are narrowed in a way that's still backwards-compatible.

@dynst
Copy link
Contributor Author

dynst commented Jun 12, 2025

This repository exceeded its LFS budget. The account responsible for the budget should increase it to restore access.

CircleCI output
Cloning git repository - git@github.com:cosmos/cosmjs.git
Fetching from remote repository
Checking out branch
Cloning into '.'...
From github.com:cosmos/cosmjs
 * [new ref]               refs/pull/1666/head -> origin/pull/1666
Downloading .yarn/cache/@agoric-babel-standalone-npm-7.9.5-d7c88bfb35-d5bae2402a.zip (4.6 MB)
Error downloading object: .yarn/cache/@agoric-babel-standalone-npm-7.9.5-d7c88bfb35-d5bae2402a.zip (3b2b29e): Smudge error: Error downloading .yarn/cache/@agoric-babel-standalone-npm-7.9.5-d7c88bfb35-d5bae2402a.zip (3b2b29e1a7e1b6f059ef1c4c2429defd1bbb9fb7187b7c63c5f243caf13fb5f7): batch response: This repository exceeded its LFS budget. The account responsible for the budget should increase it to restore access.

Errors logged to '/home/circleci/project/.git/lfs/logs/20250612T163655.63273083.log'.
Use `git lfs logs last` to view the log.
error: external filter 'git-lfs filter-process' failed
fatal: .yarn/cache/@agoric-babel-standalone-npm-7.9.5-d7c88bfb35-d5bae2402a.zip: smudge filter lfs failed
failed to checkout: exit status 128

@webmaster128
Copy link
Member

Thanks. LFS budget was fixed now.

I am happy for the new implementation. But can we do that without changing the types of CosmJS interfaces? Is it possible to use bech32 decoding without knowing the prefix?

@dynst
Copy link
Contributor Author

dynst commented Jun 17, 2025

But can we do that without changing the types of CosmJS interfaces? Is it possible to use bech32 decoding without knowing the prefix?

For a backwards compatible 0.33.2 release, existing TypeScript code can't break if it was expecting a string to be returned from the encoding function, and a more-specific-kind-of-string gets returned now, right? I tested it out. Things only break if you change the types of a function's arguments to be more-specific and strict than the caller provides.

The new return type of the decode function and some address-getters doesn't force users to change anything, but it does give them the choice to take advantage of the new type to enforce more compile-time constraints (statically ensuring this string is a valid address) in their codebase.

And if you mean, is it possible to use this library's decode function without casting (address as `${string}1${string}`), it really does require that.

@webmaster128
Copy link
Member

I am trying to use @scure/base without changing public interfaces. But hitting some issues. See paulmillr/scure-base#43

@dynst
Copy link
Contributor Author

dynst commented Aug 15, 2025

If no breaking type interface changes ever happen in CosmJS, why are there so many semver-incompatible versions (0.33, 0.34, 0.35), which indicate breaking changes?

@dynst dynst force-pushed the encoding-compat branch 2 times, most recently from ad4a5e0 to 6350748 Compare August 25, 2025 20:21
@webmaster128
Copy link
Member

webmaster128 commented Oct 2, 2025

There are breaking changes in public APIs every now and then and if they improve the user experience I am happy to do them. But I don't want to make unnecessary changes that require users to rewrite half of their app just to get an overly strict type into functionality that every user is perfectly happy with.

limit = Infinity,
): { readonly prefix: string; readonly data: Uint8Array } {
const decodedAddress = bech32.decode(address, limit);
const decodedAddress = bech32.decode(address as `${string}1${string}`, limit);
Copy link
Member

Choose a reason for hiding this comment

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

This is an unsafe cast, isn't it? address might be any string but we tell bech32.decode it is guaranteed to have a certain structure. I guess if we add an

function isBech32Structure(input: string): input is ${string}1${string} {
    // return false if malformatted
}

we get a safe type narrowing

*/
export function normalizeBech32(address: string): string {
const { prefix, data } = fromBech32(address);
const { prefix, data } = fromBech32(address as `${string}1${string}`);
Copy link
Member

Choose a reason for hiding this comment

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

This change is not needed anymore as fromBech32 accepts any string

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.

2 participants