Skip to content

feat(history): show muxed contract (W) destinations - #1035

Merged
CassioMG merged 25 commits into
mainfrom
cg-p30-history-w
Nov 7, 2026
Merged

CassioMG merged 25 commits into
mainfrom
cg-p30-history-w

Conversation

@CassioMG

@CassioMG CassioMG commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

TL;DR

History now shows a token transfer to a muxed contract address (W…) as sent to that W, as the extension does in stellar/freighter#3049. Horizon reports the base contract and the mux id separately, so rows built from its balance changes now rebuild the W from the two. A transfer to a muxed account (M…) gets the same treatment and shows the M, where it showed the base G. There's no separate mux-id row and no memo row.

It also stops one unreadable Soroban record from breaking history. Today that row silently disappears, and a token's details screen throws while rendering. Now the record shows as a generic contract row, and token details loads.

Closes stellar/wallet-eng-monorepo#109

Changed lines

Files Added Removed Share of changed lines
Source code 3 112 18 18%
Tests 4 595 1 82%
Total 7 707 19

Source code is the app code under src/. Tests are the unit tests.

Screenshots and Videos

After testnet's Protocol 30 upgrade: real sends of 0.000001 XLM to WA7Q…LLEM. A transfer's sheet shows the W.

History, with the two sends at the top A send's sheet
History listing two sends of 0.000001 XLM A send's sheet showing WA7Q...LLEM as the recipient

Before the upgrade, these showed that testnet history was unchanged.

A SAC transfer, row then sheet Generic contract row Token details, then the transfer
History row and detail sheet for a SAC transfer Generic contract row's sheet XLM token details listing the transfer
Implementation details (for agents)

This PR is based on cg-p30-sdk-bump, which is #1034 (stellar/wallet-eng-monorepo#100: SDK 17.4.0 and the shared W helpers), and merges after it.

What changed

  1. Balance-change rows rebuild the W or M for display.
    • AssetBalanceChange gains destination_muxed_id?: string (types.ts), the same field as the SDK's Horizon BalanceChange.
    • A new module-private getDebitDestination handles a debit whose id is set: buildMuxedContract(to, id) when to is a contract, and createMuxedAccount(to, id) when it's a G, as feat(history): show muxed contract (W) destinations freighter#3049 does. Anything else returns to as is.
    • An id that doesn't build is logged and falls back to the base C or G. A throw there would otherwise drop the whole diff.
    • The credit/debit decision and the filter that picks the user's changes still compare the raw to and from.

/**
* Gets the address to show as the destination of a debit.
*
* For a transfer to a muxed address, Horizon reports the base address in `to`
* and the mux id in `destination_muxed_id`, so the muxed address is rebuilt
* from the two: a `W…` for a contract (`C…`) and an `M…` for an account
* (`G…`). Any other `to` is returned as is. Use it for a debit only. On a
* credit the mux id belongs to the user's own address, not to the
* counterparty.
*
* Display only. Which changes involve the user, and whether one is a credit or
* a debit, are still decided on the raw `from` and `to`, which this never
* rewrites.
*
* Never throws: an id that doesn't build (not a decimal uint64, or out of
* range) is logged and `to` is shown instead, so one malformed id can't drop
* the row. An empty id is absent rather than invalid, so it isn't logged.
*
* @param change - A balance change in which the user is the sender.
* @returns The `W…` or `M…` for a debit to a muxed address, otherwise
* `change.to`.
*/
function getDebitDestination(change: AssetBalanceChange): string {
if (!change.destination_muxed_id) {
return change.to;
}
if (StrKey.isValidEd25519PublicKey(change.to)) {
// createMuxedAccount logs an id it can't encode and returns null.
return (
createMuxedAccount(change.to, change.destination_muxed_id) ?? change.to
);
}
if (!isContractId(change.to)) {
return change.to;
}
try {
return buildMuxedContract(change.to, change.destination_muxed_id);
} catch (error) {
logger.error("getDebitDestination", "Invalid destination_muxed_id", error);
return change.to;
}
}

const isCredit = change.to === publicKey;
const destination = isCredit ? change.from : getDebitDestination(change);

  1. getAttrsFromSorobanHorizonOp returns null for a record it can't read, instead of throwing.
    • A missing or null transaction_attr is checked first. It logs "Soroban record has no transaction_attr" and returns null.
    • Only the envelope decode (TransactionBuilder.fromXdr) sits in a try. A decode failure logs "Failed to decode Soroban operation" and returns null.
    • Every caller already treats null as "not a token call".
    • getTokenInvocationArgs runs outside the try. Nothing in it throws for an envelope that decodes, so a regression there would surface instead of being logged as a bad record.
    • Its new JSDoc documents both record shapes.

export const getAttrsFromSorobanHorizonOp = (
operation: Horizon.ServerApi.OperationRecord,
networkDetails: NetworkDetails,
) => {
if (!isSorobanOp(operation)) {
return null;
}
const attrs = (operation as any).transaction_attr;
if (!attrs) {
logger.error(
"getAttrsFromSorobanHorizonOp",
"Soroban record has no transaction_attr",
operation.id,
);
return null;
}
if (attrs.contractId) {
return {
contractId: attrs.contractId,
fnName: attrs.fnName,
...attrs.args,
};
}
let transaction: Transaction;
try {
transaction = TransactionBuilder.fromXdr(
attrs.envelope_xdr as string,
networkDetails.networkPassphrase,
) as Transaction;
} catch (error) {
logger.error(
"getAttrsFromSorobanHorizonOp",
"Failed to decode Soroban operation",
error,
);
return null;
}
// only one op per tx in Soroban right now
const invokeHostFn = transaction
.operations[0] as Operation.InvokeHostFunction;
return getTokenInvocationArgs(invokeHostFn);
};

No new rows, strings or components.

Where the W comes from

Case Records Source of the W Change here
Direct SAC transfer to a W Horizon the envelope's to, which SDK 17.4.0 decodes as the W tests only
Direct SAC transfer to a W Mercury transaction_attr.args.to, once stellar/freighter-backend#329 is deployed tests only
Contract-internal payment to a W, or a transfer whose envelope can't be decoded Horizon only the base C in asset_balance_changes[].to, plus destination_muxed_id rebuilt by getDebitDestination

A transfer to an M takes the same paths. A direct transfer's row already showed the M from the envelope; a row built from balance changes now rebuilds it from the base G and the id.

Where each one shows:

  • A direct transfer's row and sheet read transferDetails.to (mapper).
  • The generic and default contract rows read assetDiffs[].destination (generic, default), and so does the detail sheet's counterparty (sheet).
  • The memo row only ever shows for classic payments and account creation (shouldShowMemo), so it stays hidden for both contract layouts with no change.

Robustness fix, before and after

Before, a Soroban record the app couldn't read made getAttrsFromSorobanHorizonOp throw. That could be XDR newer than the app's SDK, or a record with no envelope. (A record with no transaction_attr at all still drops from History, because the row mapper reads it first; freighter-backend always sends one.)

  • History dropped the row. mapHistoryItemData rejected, and HistoryItem catches the rejection and renders nothing (catch, empty render).
  • Token details threw during render. The token filter runs inside a useMemo, so the throw escaped the render. This applied to XLM, a classic asset or a Soroban token. The path is useGetHistoryData → getFilteredHistoryData → filterOperationsByToken → getIsSupportedSorobanOp → getAttrsFromSorobanHorizonOp.

After, the function logs once per call and returns null.

  • History shows a generic contract row, with its amount when Horizon reports balance changes.
  • Token details loads. The record isn't listed under the token, because the token filter matches on the decoded invocation, which this record doesn't have.

Parity with stellar/freighter#3049

Extension (stellar/freighter#3049) This PR
destination_muxed_id on the balance-change type added, optional added, optional
When a muxed address is rebuilt a debit with an id set: a W for a contract to, an M for a G the same rule
Matching the user base address (isSameAccount) raw to/from, unchanged; Horizon reports the base address there
Mux-id row none none
Memo row for a W hidden hidden: contract rows never show it
Debit to an M payee shows the rebuilt M shows the rebuilt M
Direct transfer to a W in a Horizon record the row is built from the balance changes, so it shows the rebuilt W the transfer row reads the decoded invocation, so it shows the W from the envelope; balance changes drive only generic contract rows
Malformed destination_muxed_id (defensive only: Horizon always sends a decimal u64) falls back to the base address and reports it to Sentry logged (sent to Sentry in release builds); shows the base C or G and keeps the row and its amount
Undecodable Soroban record null, reported to Sentry; the guard wraps the envelope decode and the argument read null, logged (sent to Sentry in release builds); the guard wraps only the envelope decode, and a missing transaction_attr is checked before Mercury's pre-decoded shape is read
Fee-bumped Soroban record decoded through the fee bump decoded through the fee bump: SDK 17.4.0's FeeBumpTransaction reads operations through to the inner transaction; now pinned by a test

Corrections to the issue

  • No mux-id row in the detail sheet. The W carries the id, and the memo row stays hidden, as for M. This matches feat(history): show muxed contract (W) destinations freighter#3049.
  • stellar/wallet-eng-monorepo#111 isn't consumed. Mobile reads history only from freighter-backend v1's /account-history. There's no v2 or wallet-backend history path that would read toMuxedId.
  • The tests aren't in mappers/payment.test.ts. That suite covers classic payments only. helpers.test.ts already covers the memo rule for contract rows, so it gets no new case.
  • No smart-wallet matching. Mobile users are always G accounts, so there's no C account to attribute credits to. Matching stays on the raw addresses, unchanged.

Tests added (+36 tests, +1 suite)

  • mappers/soroban.test.ts: getAttrsFromSorobanHorizonOp.
    • Decodes Mercury and Horizon records without logging, including a fee-bumped Horizon envelope.
    • Returns null without logging for a call that isn't a token transfer or mint.
    • Returns null and logs exactly once for four unreadable shapes: XDR that doesn't decode and no envelope (as a decode failure), and no transaction_attr and a null transaction_attr (as a missing transaction_attr).
    • Returns null without logging for a non-Soroban record in Mercury's classic shape (no envelope), so classic operations in a token-filtered history are never logged.
  • Same file, through the real mapHistoryItemData:
    • A direct transfer to a W is a debit row whose recipient is the W, from both the Horizon envelope and Mercury's args.to.
    • An undecodable envelope falls back to a generic row that still shows the W from the balance change.
    • A transfer to an M shows the M on its generic row.
  • helpers/assetBalanceChanges.test.ts:
    • Mux ids "0", "1234" and u64 max build the W.
    • With no id, the row shows the C.
    • Five malformed ids ("", "abc", "-1", "0x10", 2^64) keep the change and show the C.
    • An invalid id logs once; an empty one doesn't.
    • For a G, id "1234" builds the M, and no id shows the G. The same five malformed ids keep the change and show the G; an invalid id logs once, an empty one doesn't.
    • No rebuild on a credit, from a C or a G.
  • helpers/history.test.ts: the token filter skips an undecodable Soroban record instead of throwing.
  • New TransactionDetailsBottomSheetCustomContent.test.tsx: the sheet shows WA7Q...LLEM, no memo row and no separate mux-id row, in both the balance-change and the transfer layout.

The tests fail without the changes they cover:

  • Pointing debits back at to makes the generic-row cases receive the base C or G.
  • Reading only plain transactions makes the fee-bump case return null.
  • Removing the try makes it reject with the XDR error.
  • Removing the transaction_attr check makes both missing-transaction_attr cases throw a TypeError.

Verification

  • yarn test at a0e22a4c: 335 suites passed, 1 skipped; 4867 tests passed, 6 skipped.
  • yarn lint:ts: clean.
  • ESLint and Prettier are clean on the 7 changed files. yarn check still exits 1 on lint debt already on main: ESLint has 111 errors in 18 files and Prettier flags 9 files, none of them touched here.
  • yarn lint:translations: no missing translations; no strings were added.
  • Device check on testnet, before its Protocol 30 upgrade. This ran on a dev build of this branch before 219ee9f0 (the M rebuild, which today's data can't reach: the account has no M payee), on an iPhone 17 simulator (iOS 26.5) and a Pixel 10 Pro emulator (API 37).
    • Setup: the account had no SAC transfer, so 1 XLM was sent from the app to a testnet contract, CCCG…KHKN (a native SAC transfer). For a generic contract row, two throwaway accounts made a native SAC transfer_from that credited the account 0.5 XLM.
    • History loads, and the transfer reads "XLM · Sent · -1.00 XLM". The iOS simulator's locale renders it as -1,00.
    • Its detail sheet shows 1.00 XLM to CCCG...KHKN, with no memo row.
    • The generic contract row shows "+0.50 XLM", and its sheet shows the amount and the sender.
    • XLM's token details loads and lists the transfer.
    • The app logged no decode or balance-change errors.
    • Neither new code path runs on this data: no served record carries destination_muxed_id, and every envelope decodes. So these screens are what main shows.
  • Testnet W check, 2026-11-03, after the Protocol 30 upgrade, on a dev build of this branch at 61045c3f, on a Pixel 10 Pro emulator (API 37), with backend v1 pointed at its staging environment (a local, uncommitted change to the app's STG URL). Backend v1's staging is private and only reachable locally through sshuttle; it was the only deployment with feat: protocol-30 muxed contract (W) address support freighter-backend#329 that day. Backend v1 has no public staging, so Always require memo on error + UI tweaks #329 goes public when it reaches production.
    • Two sends of 0.000001 XLM to WA7QYNF7…E2LLEM (base CA7QYNF7…UWDA, mux id 1234), made from the app on feat(send): support muxed contract (W) destinations #1036's branch, show in History as "XLM · Sent · -0.000001 XLM", and each sheet shows 0.000001 XLM to WA7Q…LLEM.
    • These are direct SAC transfers, so the W comes from the record itself (the table's first two rows), and getDebitDestination doesn't run on them. Horizon serves their balance changes as the base contract plus destination_muxed_id: "1234", the shape it rebuilds.

Follow-ups / out of scope

  • Mercury records show a direct transfer's W once feat: protocol-30 muxed contract (W) address support freighter-backend#329 reaches production. On 2026-11-03 it was only on backend v1's staging, which is private; backend v1 has no public staging.
  • Mercury records carry no balance changes. A contract-internal payment to a W in Mercury mode shows as a generic contract row without the W, as it does today.
  • Repeated logging. An unreadable record is logged each time history is evaluated, which includes the 30-second background poll and token filtering. A backend serving such records would log repeatedly. Worth revisiting only if a systemic decode regression becomes plausible.

🤖 Generated with Claude Code

CassioMG and others added 16 commits October 29, 2026 22:57
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Cover the Protocol 30 SDK surface the wallet depends on: the SEP-23
muxed contract (W) strkey vector, ScAddress arm 5 round-trips, the
CAP-87 ML-DSA cost types (86-94) and the CAP-88 millisecond
StellarValue arms. All four fail against the 17.0.1 SDK.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Pin which transaction memos fold into a muxed (M...) address on stellar-sdk 17.4.0. Decimal uint64 ids fold; hex, padded, empty and out-of-range values do not. The tests run against the real SDK, with only services/backend mocked.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
fast-text-encoding, the app's global TextDecoder, throws when it is asked
for { fatal: true }. SDK 17.4.0 asks for it in its bounded-fetch adapter, so
federation addresses did not resolve and stellar.toml asset icons did not
load on device. The SDK also asks for it in XdrString.toStringStrict(), so
scValToNative returned raw bytes instead of strings for symbols and strings.

Wrap the global TextDecoder so a UTF-8 decoder built with { fatal: true }
validates its input with a WHATWG-conformant check and throws a TypeError on
malformed bytes. Every other decoder is built and used as before, and the
wrapper does nothing where TextDecoder already supports fatal, as on Node
and in Jest.

The polyfill requires fast-text-encoding itself and installs Buffer first,
as shim.js does later, so the decoder keeps decoding through Buffer.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A TextDecoder built with { fatal: true } and the default ignoreBOM now drops
one leading U+FEFF from its output, as the native decoder does.
fast-text-encoding never strips it, so a stellar.toml or federation response
that starts with a BOM failed to parse on device: smol-toml and JSON.parse
both reject the BOM.

The SDK's bounded fetch builds its decoder with the default ignoreBOM, so it
gets the stripping. XdrString.toStringStrict() and the WASM name parser pass
ignoreBOM: true and keep the BOM. A strict decoder now reports the ignoreBOM
option it honors. Non-fatal decoders are unchanged and still keep a BOM.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A TextDecoder built with { fatal: true } now reads only the window of a
DataView or non-Uint8Array typed array that byteOffset and byteLength
describe, as the native decoder does. It used to validate and decode the
whole backing buffer, as fast-text-encoding does. Every caller in the app
passes a Uint8Array, which is unchanged, so this brings the strict path in
line with the native decoder rather than changing what the app decodes.
Non-fatal decoders still hand their input straight to the base.

The UTF8_LABEL comment now says which labels the strict path treats as
UTF-8, and that the Buffer-backed base accepts only utf-8 and utf8. The
tests gain a view-window check against the native decoder, a parity check for
decode() with no input on a non-fatal decoder, and a JSDoc on the hex helper.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The decodeUtf8At comment said React Native's TextDecoder throws on fatal,
which stopped being true with the strict TextDecoder polyfill. It now says
why the function exists: the escape renderer needs one code point and its
width at an index, which a decoder of a whole buffer cannot give.

The strkey scrubbing tests add a letter before, a letter after and one more
base32 character after a W key, so the leading anchor, the trailing anchor
and the exact length are each pinned on their own. The memo folding tests
split the non-folding memos by reason: not a canonical decimal id, and not a
uint64. The SDK compatibility suite's header and top-level title now cover
SDK 17 and Protocols 27 and 30. No production code changes.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
stellarSdkV15.test.ts has covered more than SDK 15 since it gained the
Protocol 27 (CAP-71) block and the Protocol 30 block, so it becomes
stellarSdkCompat.test.ts, with a version-free top-level describe.

It also gains a block for the Horizon submission errors of the SDK 16+
HTTP client. SDK 16 replaced axios with fetch, and 16.1.0 / 17.0.0 made
submitTransaction reject with TransactionFailedError or BadResponseError.
The app reads those errors through isHorizonError: response.status for
the 504 retry and the log-severity split, and
response.data.extras.result_codes in the transaction builder and
useManageTokens. Every app test built that error by hand, so nothing
pinned it to the real SDK. The new tests drive the real Horizon.Server
against a stubbed fetch for a 400 with result codes, a 429 without them,
and a 504. If the SDK stops exposing response.data, the first two fail.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

Android Emulator preview APK is ready: https://github.com/stellar/freighter-mobile/releases/tag/untagged-c13189405d9fef601f7c
Backend: V1 prod + V2 staging (no sandbox configured for @CassioMG). SDF collaborators only — install instructions in the release description.

@github-actions

github-actions Bot commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

iOS Simulator preview build is ready: https://github.com/stellar/freighter-mobile/releases/tag/untagged-0a8979cee6068de01d8d
Backend: V1 prod + V2 staging (no sandbox configured for @CassioMG). SDF collaborators only — install instructions in the release description.

CassioMG and others added 2 commits October 30, 2026 17:40
Horizon reports a transfer to a muxed account (M…) like one to a muxed
contract (W…): the base G… in `to` and the mux id in
`destination_muxed_id`. getDebitDestination now rebuilds the M with
createMuxedAccount, as the extension does, and an id that won't encode
is logged and shows the G.

Also pin that getAttrsFromSorobanHorizonOp decodes a fee-bumped Soroban
envelope.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
17.4.0 is now older than the 7-day npmMinimalAgeGate, so the
temporary npmPreapprovedPackages entry is no longer needed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@CassioMG
CassioMG marked this pull request as ready for review November 2, 2026 22:24
@CassioMG
CassioMG requested a lite review from Copilot November 2, 2026 22:24
@CassioMG CassioMG self-assigned this Nov 2, 2026

Copilot AI left a comment

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.

🔵 Needs a closer look

Approval should wait for Protocol 30 and Mercury backend availability so iOS and Android can be validated against real Horizon and Mercury W-address balance-change and envelope records.

No open issues 🎉

What changed in this PR

Updates history rendering to support muxed contract (W…) and account (M…) destinations, while making unreadable Soroban records fall back safely instead of breaking history or token details.

Changes:

  • Reconstructs muxed destinations from Horizon balance-change data for debit rows.
  • Makes Soroban decoding resilient by logging failures and returning null.
  • Adds coverage for muxed destinations, malformed IDs, fee-bumped transactions, generic fallback rows, and detail-sheet rendering.
File Description
src/​helpers/​soroban.ts Adds guarded Soroban invocation decoding with graceful failure handling.
src/​helpers/​assetBalanceChanges.ts Reconstructs W… and M… debit destinations from balance changes.
src/​components/​screens/​HistoryScreen/​types.ts Adds the optional destination_muxed_id balance-change field.
__tests__/​helpers/​history.test.ts Verifies undecodable Soroban operations are skipped during token filtering.
__tests__/​helpers/​assetBalanceChanges.test.ts Tests muxed destination reconstruction, invalid IDs, credits, and debits.
__tests__/​components/​screens/​HistoryScreen/​TransactionDetailsBottomSheetCustomContent.test.tsx Verifies W-address display without memo or mux-ID rows.
__tests__/​components/​screens/​HistoryScreen/​mappers/​soroban.test.ts Covers Horizon, Mercury, fee-bumped, direct, generic, and undecodable Soroban history records.

Review effort: Lite

Brings in b4489ad, which re-comments the stellar-sdk age-gate bypass in
.yarnrc.yml, and 9e5e0d2, which renames the SDK compatibility tests.
This branch started before both, so it still had the bypass on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…eros

The scrubber tests checked a W with one extra character but not one with
a character missing: a 68-character run must stay untouched, since only a
69-character M or W is a key. buildMuxedContract's comment says it drops
leading zeros from the id; nothing asserted it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CassioMG and others added 2 commits November 2, 2026 17:18
AGENTS.md and the dependencies guide still said Node 20, but
package.json's engines field asks for >= 22.12.0 and every workflow runs
Node 22. Prettier, run by the pre-commit hook, also re-pads the Best
Practices table in AGENTS.md, which wasn't formatted before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Brings in 900fd03 (two missing tests: a too-short W in the scrubber,
buildMuxedContract's leading zeros) and b80ca26 (Node 22 in the docs).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@CassioMG
CassioMG requested a review from a team November 3, 2026 21:01
Comment thread src/helpers/soroban.ts Resolved
A missing transaction_attr is now checked and logged explicitly, and the
try only wraps TransactionBuilder.fromXdr. getTokenInvocationArgs runs
outside it, so a regression there surfaces instead of being logged as an
unreadable record.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Base automatically changed from cg-p30-sdk-bump to main November 6, 2026 23:18
CassioMG and others added 2 commits November 6, 2026 15:21
Brings in #1034 (squash-merged as 3999960) now that this PR targets
main. package.json and yarn.lock take main's versions: this PR doesn't
change them, and main's carry #1034's later typescript-wallet-sdk-km
6.0.0 bump.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Brings in #1037 (squash-merged as fa85619).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@CassioMG
CassioMG merged commit 8e78952 into main Nov 7, 2026
11 of 25 checks passed
@CassioMG
CassioMG deleted the cg-p30-history-w branch November 7, 2026 00:01
CassioMG added a commit that referenced this pull request Nov 7, 2026
Brings in #1035 (squash-merged as 8e78952). Its soroban.ts change
(history attributes, near the end of the file) and this PR's (contract
destinations, near the top) don't overlap, so the file merged cleanly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

3 participants