From 174fb733c2dce1c5f9c8ccc8768dbce04d999c84 Mon Sep 17 00:00:00 2001 From: kalepail Date: Fri, 5 Jun 2026 11:47:31 -0400 Subject: [PATCH 1/4] Prepare auth signing for Protocol 27 --- package.json | 4 +- .../smart-account-kit-bindings/package.json | 2 +- pnpm-lock.yaml | 59 +++++--- src/kit.ts | 3 +- src/kit/auth-payload.test.ts | 114 ++++++++++++++- src/kit/auth-payload.ts | 137 +++++++++++++++++- src/kit/tx-ops.ts | 64 ++++---- src/kit/webauthn-ops.ts | 15 +- src/managers/multi-signer-manager.ts | 55 +++++-- 9 files changed, 374 insertions(+), 79 deletions(-) diff --git a/package.json b/package.json index 8439be7..5939ee6 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ }, "dependencies": { "@simplewebauthn/browser": "^13.3.0", - "@stellar/stellar-sdk": ">=15.0.1", + "@stellar/stellar-sdk": ">=15.1.0", "base64url": "^3.0.1", "smart-account-kit-bindings": "workspace:*" }, @@ -72,7 +72,7 @@ "packageManager": "pnpm@10.33.0", "peerDependencies": { "@creit-tech/stellar-wallets-kit": ">=2.1.0", - "@stellar/stellar-sdk": ">=15.0.1" + "@stellar/stellar-sdk": ">=15.1.0" }, "peerDependenciesMeta": { "@creit-tech/stellar-wallets-kit": { diff --git a/packages/smart-account-kit-bindings/package.json b/packages/smart-account-kit-bindings/package.json index eb1071c..fedfd6b 100644 --- a/packages/smart-account-kit-bindings/package.json +++ b/packages/smart-account-kit-bindings/package.json @@ -27,7 +27,7 @@ "url": "https://github.com/kalepail/smart-account-kit" }, "peerDependencies": { - "@stellar/stellar-sdk": ">=15.0.1" + "@stellar/stellar-sdk": ">=15.1.0" }, "publishConfig": { "registry": "https://registry.npmjs.org/", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8350ca2..6a7e09e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,7 +5,7 @@ settings: excludeLinksFromLockfile: false overrides: - '@stellar/stellar-sdk': '>=15.0.1' + '@stellar/stellar-sdk': '>=15.1.0' importers: @@ -15,8 +15,8 @@ importers: specifier: ^13.3.0 version: 13.3.0 '@stellar/stellar-sdk': - specifier: '>=15.0.1' - version: 15.0.1 + specifier: '>=15.1.0' + version: 15.1.0 base64url: specifier: ^3.0.1 version: 3.0.1 @@ -26,7 +26,7 @@ importers: devDependencies: '@creit-tech/stellar-wallets-kit': specifier: jsr:2.1.0 - version: '@jsr/creit-tech__stellar-wallets-kit@2.1.0(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2))(@stellar/stellar-sdk@15.0.1)(@trezor/connect@9.7.2(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@6.0.2)(utf-8-validate@5.0.10)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@types/react@19.2.14)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(near-api-js@5.1.1)(react@19.2.4)(tslib@2.8.1)(typescript@6.0.2)(utf-8-validate@5.0.10)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)' + version: '@jsr/creit-tech__stellar-wallets-kit@2.1.0(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2))(@stellar/stellar-sdk@15.1.0)(@trezor/connect@9.7.2(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@6.0.2)(utf-8-validate@5.0.10)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@types/react@19.2.14)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(near-api-js@5.1.1)(react@19.2.4)(tslib@2.8.1)(typescript@6.0.2)(utf-8-validate@5.0.10)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)' '@types/node': specifier: ^25.5.2 version: 25.5.2 @@ -41,13 +41,13 @@ importers: dependencies: '@creit-tech/stellar-wallets-kit': specifier: npm:@jsr/creit-tech__stellar-wallets-kit@^2.1.0 - version: '@jsr/creit-tech__stellar-wallets-kit@2.1.0(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2))(@stellar/stellar-sdk@15.0.1)(@trezor/connect@9.7.2(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@6.0.2)(utf-8-validate@5.0.10)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@types/react@19.2.14)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(near-api-js@5.1.1)(react@19.2.4)(tslib@2.8.1)(typescript@6.0.2)(utf-8-validate@5.0.10)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)' + version: '@jsr/creit-tech__stellar-wallets-kit@2.1.0(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2))(@stellar/stellar-sdk@15.1.0)(@trezor/connect@9.7.2(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@6.0.2)(utf-8-validate@5.0.10)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@types/react@19.2.14)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(near-api-js@5.1.1)(react@19.2.4)(tslib@2.8.1)(typescript@6.0.2)(utf-8-validate@5.0.10)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)' '@stellar/stellar-base': specifier: ^15.0.0 version: 15.0.0 '@stellar/stellar-sdk': - specifier: '>=15.0.1' - version: 15.0.1 + specifier: '>=15.1.0' + version: 15.1.0 buffer: specifier: ^6.0.3 version: 6.0.3 @@ -86,8 +86,8 @@ importers: specifier: ^13.3.0 version: 13.3.0 '@stellar/stellar-sdk': - specifier: '>=15.0.1' - version: 15.0.1 + specifier: '>=15.1.0' + version: 15.1.0 smart-account-kit: specifier: workspace:^ version: link:../.. @@ -137,8 +137,8 @@ importers: packages/smart-account-kit-bindings: dependencies: '@stellar/stellar-sdk': - specifier: '>=15.0.1' - version: 15.0.1 + specifier: '>=15.1.0' + version: 15.1.0 buffer: specifier: 6.0.3 version: 6.0.3 @@ -1598,8 +1598,8 @@ packages: resolution: {integrity: sha512-XQhxUr9BYiEcFcgc4oWcCMR9QJCny/GmmGsuwPKf/ieIcOeb5149KLHYx9mJCA0ea8QbucR2/GzV58QbXOTxQA==} engines: {node: '>=20.0.0'} - '@stellar/stellar-sdk@15.0.1': - resolution: {integrity: sha512-iZjWKXtfohsPh+CX9wRyQNIlXLeA9VyuQB6UMC7AFBD9XnR92eOjnlfeONzk/Bsrkk6+UPlpzSy2MuF+ydHP1A==} + '@stellar/stellar-sdk@15.1.0': + resolution: {integrity: sha512-GsJUcWx2yboVzYdhTe/LHS3V1wVLSHkUkglC5bBoYWGJt31vzIhbSGno60NP9CdCTNkLJdnrsLJ63oA58Zvh5A==} engines: {node: '>=20.0.0'} hasBin: true @@ -1649,7 +1649,7 @@ packages: '@trezor/connect-plugin-stellar@9.2.6': resolution: {integrity: sha512-RA0Q4GHaf1mFxgSX183yyH+5tWEgS1j+sfe9KiUyIn/VnpXeUnaCpQuKMomAjGXQ5oNuvikTOdHYOqsvuEdOyw==} peerDependencies: - '@stellar/stellar-sdk': '>=15.0.1' + '@stellar/stellar-sdk': '>=15.1.0' '@trezor/connect': 9.x.x tslib: ^2.6.2 @@ -2042,6 +2042,9 @@ packages: axios@1.14.0: resolution: {integrity: sha512-3Y8yrqLSwjuzpXuZ0oIYZ/XGgLwUIBU3uLvbcpb0pidD9ctpShJd43KSlEEkVQg6DS0G9NKyzOvBfUtDKEyHvQ==} + axios@1.15.0: + resolution: {integrity: sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q==} + base-x@3.0.11: resolution: {integrity: sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==} @@ -3950,7 +3953,7 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 - '@jsr/creit-tech__stellar-wallets-kit@2.1.0(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2))(@stellar/stellar-sdk@15.0.1)(@trezor/connect@9.7.2(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@6.0.2)(utf-8-validate@5.0.10)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@types/react@19.2.14)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(near-api-js@5.1.1)(react@19.2.4)(tslib@2.8.1)(typescript@6.0.2)(utf-8-validate@5.0.10)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)': + '@jsr/creit-tech__stellar-wallets-kit@2.1.0(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2))(@stellar/stellar-sdk@15.1.0)(@trezor/connect@9.7.2(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@6.0.2)(utf-8-validate@5.0.10)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@types/react@19.2.14)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(near-api-js@5.1.1)(react@19.2.4)(tslib@2.8.1)(typescript@6.0.2)(utf-8-validate@5.0.10)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)': dependencies: '@albedo-link/intent': 0.12.0 '@creit.tech/xbull-wallet-connect': 0.4.0 @@ -3964,7 +3967,7 @@ snapshots: '@reown/appkit': 1.8.19(@types/react@19.2.14)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.4)(typescript@6.0.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@stellar/freighter-api': 6.0.0 '@stellar/stellar-base': 14.0.1 - '@trezor/connect-plugin-stellar': 9.2.6(@stellar/stellar-sdk@15.0.1)(@trezor/connect@9.7.2(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@6.0.2)(utf-8-validate@5.0.10)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(tslib@2.8.1) + '@trezor/connect-plugin-stellar': 9.2.6(@stellar/stellar-sdk@15.1.0)(@trezor/connect@9.7.2(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@6.0.2)(utf-8-validate@5.0.10)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(tslib@2.8.1) '@trezor/connect-web': 9.7.2(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@6.0.2)(utf-8-validate@5.0.10)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@twind/core': 1.1.3(typescript@6.0.2) '@twind/preset-autoprefix': 1.0.7(@twind/core@1.1.3(typescript@6.0.2))(typescript@6.0.2) @@ -4216,7 +4219,7 @@ snapshots: dependencies: '@actions/exec': 1.1.1 '@openzeppelin/relayer-sdk': 1.10.0 - '@stellar/stellar-sdk': 15.0.1 + '@stellar/stellar-sdk': 15.1.0 axios: 1.14.0 transitivePeerDependencies: - debug @@ -5561,10 +5564,10 @@ snapshots: buffer: 6.0.3 sha.js: 2.4.12 - '@stellar/stellar-sdk@15.0.1': + '@stellar/stellar-sdk@15.1.0': dependencies: '@stellar/stellar-base': 15.0.0 - axios: 1.14.0 + axios: 1.15.0 bignumber.js: 9.3.1 commander: 14.0.3 eventsource: 2.0.2 @@ -5604,7 +5607,7 @@ snapshots: '@trezor/blockchain-link-utils@1.5.1(bufferutil@4.0.9)(tslib@2.8.1)(utf-8-validate@5.0.10)': dependencies: '@mobily/ts-belt': 3.13.1 - '@stellar/stellar-sdk': 15.0.1 + '@stellar/stellar-sdk': 15.1.0 '@trezor/env-utils': 1.5.0(tslib@2.8.1) '@trezor/protobuf': 1.5.1(tslib@2.8.1) '@trezor/utils': 9.5.0(tslib@2.8.1) @@ -5621,7 +5624,7 @@ snapshots: '@trezor/blockchain-link-utils@1.5.2(bufferutil@4.0.9)(tslib@2.8.1)(utf-8-validate@5.0.10)': dependencies: '@mobily/ts-belt': 3.13.1 - '@stellar/stellar-sdk': 15.0.1 + '@stellar/stellar-sdk': 15.1.0 '@trezor/env-utils': 1.5.0(tslib@2.8.1) '@trezor/protobuf': 1.5.2(tslib@2.8.1) '@trezor/utils': 9.5.0(tslib@2.8.1) @@ -5643,7 +5646,7 @@ snapshots: '@solana-program/token-2022': 0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2)) '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2) - '@stellar/stellar-sdk': 15.0.1 + '@stellar/stellar-sdk': 15.1.0 '@trezor/blockchain-link-types': 1.5.0(tslib@2.8.1) '@trezor/blockchain-link-utils': 1.5.1(bufferutil@4.0.9)(tslib@2.8.1)(utf-8-validate@5.0.10) '@trezor/env-utils': 1.5.0(tslib@2.8.1) @@ -5689,9 +5692,9 @@ snapshots: - expo-localization - react-native - '@trezor/connect-plugin-stellar@9.2.6(@stellar/stellar-sdk@15.0.1)(@trezor/connect@9.7.2(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@6.0.2)(utf-8-validate@5.0.10)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(tslib@2.8.1)': + '@trezor/connect-plugin-stellar@9.2.6(@stellar/stellar-sdk@15.1.0)(@trezor/connect@9.7.2(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@6.0.2)(utf-8-validate@5.0.10)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(tslib@2.8.1)': dependencies: - '@stellar/stellar-sdk': 15.0.1 + '@stellar/stellar-sdk': 15.1.0 '@trezor/connect': 9.7.2(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@6.0.2)(utf-8-validate@5.0.10)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@trezor/utils': 9.5.0(tslib@2.8.1) tslib: 2.8.1 @@ -6571,6 +6574,14 @@ snapshots: transitivePeerDependencies: - debug + axios@1.15.0: + dependencies: + follow-redirects: 1.15.11 + form-data: 4.0.5 + proxy-from-env: 2.1.0 + transitivePeerDependencies: + - debug + base-x@3.0.11: dependencies: safe-buffer: 5.2.1 diff --git a/src/kit.ts b/src/kit.ts index fedb3fa..fdb273b 100644 --- a/src/kit.ts +++ b/src/kit.ts @@ -124,6 +124,7 @@ import { findWebAuthnSignerForCredential, resolveContextRuleIdsForEntry, } from "./kit/context-rules"; +import { normalizeSignatureExpirationLedger } from "./kit/auth-payload"; import { validateAddress, validateAmount, xlmToStroops } from "./utils"; @@ -669,7 +670,7 @@ export class SmartAccountKit { */ private async calculateExpiration(): Promise { const { sequence } = await this.rpc.getLatestLedger(); - return sequence + this.signatureExpirationLedgers; + return normalizeSignatureExpirationLedger(sequence + this.signatureExpirationLedgers); } /** diff --git a/src/kit/auth-payload.test.ts b/src/kit/auth-payload.test.ts index ce10440..cbad12b 100644 --- a/src/kit/auth-payload.test.ts +++ b/src/kit/auth-payload.test.ts @@ -1,9 +1,12 @@ -import { Keypair, hash, xdr } from "@stellar/stellar-sdk"; +import { Address, Keypair, hash, xdr } from "@stellar/stellar-sdk"; import { describe, expect, it } from "vitest"; import type { AuthPayload, Signer } from "smart-account-kit-bindings"; import { buildAuthDigest, buildAddressSignatureScVal, + buildSignaturePayload, + createAddressCredentials, + getAddressCredentials, readAuthPayload, upsertAuthPayloadSigner, writeAuthPayload, @@ -20,6 +23,31 @@ function makeAccount(seedByte: number): string { return Keypair.fromRawEd25519Seed(Buffer.alloc(32, seedByte)).publicKey(); } +function makeAuthEntry(address: string): xdr.SorobanAuthorizationEntry { + return new xdr.SorobanAuthorizationEntry({ + credentials: createAddressCredentials( + new xdr.SorobanAddressCredentials({ + address: Address.fromString(address).toScAddress(), + nonce: xdr.Int64.fromString("7"), + signatureExpirationLedger: 1, + signature: xdr.ScVal.scvVoid(), + }) + ), + rootInvocation: new xdr.SorobanAuthorizedInvocation({ + function: xdr.SorobanAuthorizedFunction.sorobanAuthorizedFunctionTypeContractFn( + new xdr.InvokeContractArgs({ + contractAddress: xdr.ScAddress.scAddressTypeContract( + hash(Buffer.from("contract")) + ), + functionName: "do_it", + args: [], + }) + ), + subInvocations: [], + }), + }); +} + describe("auth-payload", () => { it("round-trips AuthPayload with signer map and context rule ids", () => { const signer = makeDelegatedSigner( @@ -88,4 +116,88 @@ describe("auth-payload", () => { expect(entries?.[1].key().sym().toString()).toBe("signature"); expect(Buffer.from(entries?.[1].val().bytes() ?? [])).toEqual(signature); }); + + it("unwraps address credentials through the shared helper", () => { + const account = makeAccount(4); + const entry = makeAuthEntry(account); + const credentials = getAddressCredentials(entry.credentials()); + + expect(entry.credentials().switch().name).toBe("sorobanCredentialsAddress"); + expect(credentials.nonce().toString()).toBe("7"); + expect(Address.fromScAddress(credentials.address()).toString()).toBe(account); + }); + + it("requires explicit opt-in for ADDRESS_V2 credentials", () => { + const credentials = getAddressCredentials(makeAuthEntry(makeAccount(5)).credentials()); + + expect(() => createAddressCredentials(credentials, { version: "address_v2" })).toThrow( + "ADDRESS_V2 credentials require an SDK with Protocol 27 credential support" + ); + }); + + it("rejects unsupported address credential versions", () => { + const credentials = getAddressCredentials(makeAuthEntry(makeAccount(6)).credentials()); + + expect(() => + createAddressCredentials(credentials, { version: "bogus" as never }) + ).toThrow("Unsupported Soroban address credential version: bogus"); + }); + + it("does not sign address-bound credentials without P27 preimage support", () => { + const credentials = getAddressCredentials(makeAuthEntry(makeAccount(7)).credentials()); + const fakeAddressV2Entry = { + credentials: () => ({ + switch: () => ({ name: "sorobanCredentialsAddressV2" }), + addressV2: () => credentials, + }), + rootInvocation: () => makeAuthEntry(makeAccount(8)).rootInvocation(), + } as unknown as xdr.SorobanAuthorizationEntry; + + expect(() => + buildSignaturePayload("Test SDF Network ; September 2015", fakeAddressV2Entry, 123) + ).toThrow( + "Address-bound Soroban auth credentials require an SDK with Protocol 27 auth preimage support" + ); + expect(credentials.signatureExpirationLedger()).toBe(1); + }); + + it("keeps the submitted expiration in sync with the signed payload", () => { + const entry = makeAuthEntry(makeAccount(9)); + const payload = buildSignaturePayload("Test SDF Network ; September 2015", entry, 123); + + expect(payload).toHaveLength(32); + expect(getAddressCredentials(entry.credentials()).signatureExpirationLedger()).toBe(123); + }); + + it("rounds fractional signature expirations up before XDR serialization", () => { + const entry = makeAuthEntry(makeAccount(10)); + const payload = buildSignaturePayload("Test SDF Network ; September 2015", entry, 123.2); + + expect(payload).toHaveLength(32); + expect(getAddressCredentials(entry.credentials()).signatureExpirationLedger()).toBe(124); + }); + + it("rejects non-finite signature expirations without mutating the entry", () => { + const entry = makeAuthEntry(makeAccount(11)); + + expect(() => + buildSignaturePayload("Test SDF Network ; September 2015", entry, Number.NaN) + ).toThrow("Signature expiration ledger must be a finite number"); + expect(getAddressCredentials(entry.credentials()).signatureExpirationLedger()).toBe(1); + }); + + it("rejects out-of-range signature expirations without mutating the entry", () => { + const negativeEntry = makeAuthEntry(makeAccount(12)); + const oversizedEntry = makeAuthEntry(makeAccount(13)); + + expect(() => + buildSignaturePayload("Test SDF Network ; September 2015", negativeEntry, -1) + ).toThrow("Signature expiration ledger must fit in u32"); + expect(getAddressCredentials(negativeEntry.credentials()).signatureExpirationLedger()).toBe(1); + + expect(() => + buildSignaturePayload("Test SDF Network ; September 2015", oversizedEntry, 0x1_0000_0000) + ).toThrow("Signature expiration ledger must fit in u32"); + expect(getAddressCredentials(oversizedEntry.credentials()).signatureExpirationLedger()).toBe(1); + }); }); diff --git a/src/kit/auth-payload.ts b/src/kit/auth-payload.ts index 31b5d5a..be706c7 100644 --- a/src/kit/auth-payload.ts +++ b/src/kit/auth-payload.ts @@ -11,16 +11,145 @@ export function buildSignaturePayload( entry: xdr.SorobanAuthorizationEntry, expiration: number ): Buffer { - const preimage = xdr.HashIdPreimage.envelopeTypeSorobanAuthorization( + return hash(buildSignaturePreimage(networkPassphrase, entry, expiration).toXDR()); +} + +export function buildSignaturePreimage( + networkPassphrase: string, + entry: xdr.SorobanAuthorizationEntry, + expiration: number +): xdr.HashIdPreimage { + const credentials = getAddressCredentials(entry.credentials()); + const normalizedExpiration = normalizeSignatureExpirationLedger(expiration); + + const hashIdPreimage = xdr.HashIdPreimage as unknown as { + envelopeTypeSorobanAuthorizationWithAddress?: (value: unknown) => xdr.HashIdPreimage; + }; + const withAddressPreimage = (xdr as unknown as { + HashIdPreimageSorobanAuthorizationWithAddress?: new (fields: { + networkId: Buffer; + nonce: xdr.Int64; + signatureExpirationLedger: number; + invocation: xdr.SorobanAuthorizedInvocation; + address: xdr.ScAddress; + }) => unknown; + }).HashIdPreimageSorobanAuthorizationWithAddress; + + if (usesAddressBoundPayload(entry.credentials())) { + if (!hashIdPreimage.envelopeTypeSorobanAuthorizationWithAddress || !withAddressPreimage) { + throw new Error( + "Address-bound Soroban auth credentials require an SDK with Protocol 27 auth preimage support" + ); + } + + credentials.signatureExpirationLedger(normalizedExpiration); + return hashIdPreimage.envelopeTypeSorobanAuthorizationWithAddress( + new withAddressPreimage({ + networkId: hash(Buffer.from(networkPassphrase)), + nonce: credentials.nonce(), + signatureExpirationLedger: normalizedExpiration, + invocation: entry.rootInvocation(), + address: credentials.address(), + }) + ); + } + + credentials.signatureExpirationLedger(normalizedExpiration); + return xdr.HashIdPreimage.envelopeTypeSorobanAuthorization( new xdr.HashIdPreimageSorobanAuthorization({ networkId: hash(Buffer.from(networkPassphrase)), - nonce: entry.credentials().address().nonce(), - signatureExpirationLedger: expiration, + nonce: credentials.nonce(), + signatureExpirationLedger: normalizedExpiration, invocation: entry.rootInvocation(), }) ); +} + +export function normalizeSignatureExpirationLedger(expiration: number): number { + if (!Number.isFinite(expiration)) { + throw new Error("Signature expiration ledger must be a finite number"); + } + + const normalizedExpiration = Math.ceil(expiration); + if (normalizedExpiration < 0 || normalizedExpiration > 0xffffffff) { + throw new Error("Signature expiration ledger must fit in u32"); + } + + return normalizedExpiration; +} + +export function getAddressCredentials( + credentials: xdr.SorobanCredentials +): xdr.SorobanAddressCredentials { + const typedCredentials = credentials as unknown as { + address: () => xdr.SorobanAddressCredentials; + addressV2?: () => xdr.SorobanAddressCredentials; + addressWithDelegates?: () => { + addressCredentials: () => xdr.SorobanAddressCredentials; + }; + }; + + const credentialType = credentials.switch().name as string; + switch (credentialType) { + case "sorobanCredentialsAddress": + return typedCredentials.address(); + case "sorobanCredentialsAddressV2": + if (!typedCredentials.addressV2) { + throw new Error( + "ADDRESS_V2 credentials require an SDK with Protocol 27 credential support" + ); + } + return typedCredentials.addressV2(); + case "sorobanCredentialsAddressWithDelegates": + if (!typedCredentials.addressWithDelegates) { + throw new Error( + "ADDRESS_WITH_DELEGATES credentials require an SDK with Protocol 27 credential support" + ); + } + return typedCredentials.addressWithDelegates().addressCredentials(); + } + + throw new Error(`Soroban credentials do not contain address credentials: ${credentials.switch().name}`); +} + +export function getAuthEntryAddress(entry: xdr.SorobanAuthorizationEntry): string { + return Address.fromScAddress(getAddressCredentials(entry.credentials()).address()).toString(); +} + +export function createAddressCredentials( + credentials: xdr.SorobanAddressCredentials, + options?: { version?: "legacy" | "address_v2" } +): xdr.SorobanCredentials { + const credentialFactory = xdr.SorobanCredentials as unknown as { + sorobanCredentialsAddressV2?: ( + credentials: xdr.SorobanAddressCredentials + ) => xdr.SorobanCredentials; + sorobanCredentialsAddress: ( + credentials: xdr.SorobanAddressCredentials + ) => xdr.SorobanCredentials; + }; + + const version = (options?.version ?? "legacy") as string; + if (version === "address_v2") { + if (!credentialFactory.sorobanCredentialsAddressV2) { + throw new Error( + "ADDRESS_V2 credentials require an SDK with Protocol 27 credential support" + ); + } + return credentialFactory.sorobanCredentialsAddressV2(credentials); + } + + if (version !== "legacy") { + throw new Error(`Unsupported Soroban address credential version: ${version}`); + } + + return credentialFactory.sorobanCredentialsAddress(credentials); +} - return hash(preimage.toXDR()); +function usesAddressBoundPayload(credentials: xdr.SorobanCredentials): boolean { + const credentialType = credentials.switch().name as string; + return credentialType === "sorobanCredentialsAddressV2" || + credentialType === "sorobanCredentialsAddressWithDelegates"; } export function buildAuthDigest( diff --git a/src/kit/tx-ops.ts b/src/kit/tx-ops.ts index 2a3fef4..9942cda 100644 --- a/src/kit/tx-ops.ts +++ b/src/kit/tx-ops.ts @@ -21,7 +21,12 @@ import { FRIENDBOT_URL, LEDGERS_PER_HOUR, } from "../constants"; -import { buildAddressSignatureScVal } from "./auth-payload"; +import { + buildAddressSignatureScVal, + buildSignaturePreimage, + createAddressCredentials, + getAddressCredentials, +} from "./auth-payload"; import { validateAddress, validateAmount, xlmToStroops, stroopsToXlm } from "../utils"; type ResolveContextRuleIds = ( @@ -566,7 +571,7 @@ export async function fundWallet( const expirationLedger = currentLedger + LEDGERS_PER_HOUR; // ~1 hour for (const entry of authEntries) { - const credType = entry.credentials().switch().name; + const credType = entry.credentials().switch().name as string; // For source_account credentials, convert to Address credentials // so the Relayer can use its own channel accounts @@ -574,50 +579,53 @@ export async function fundWallet( // Generate a nonce for the new Address credential const nonce = xdr.Int64.fromString(Date.now().toString()); - const preimage = xdr.HashIdPreimage.envelopeTypeSorobanAuthorization( - new xdr.HashIdPreimageSorobanAuthorization({ - networkId: hash(Buffer.from(deps.networkPassphrase)), - nonce, - signatureExpirationLedger: expirationLedger, - invocation: entry.rootInvocation(), - }) - ); - const payload = hash(preimage.toXDR()); - const signature = tempKeypair.sign(payload); - // Create new Address credentials entry to replace source_account const addressEntry = new xdr.SorobanAuthorizationEntry({ - credentials: xdr.SorobanCredentials.sorobanCredentialsAddress( + credentials: createAddressCredentials( new xdr.SorobanAddressCredentials({ address: Address.fromString(tempKeypair.publicKey()).toScAddress(), nonce, signatureExpirationLedger: expirationLedger, - signature: buildAddressSignatureScVal( - tempKeypair.rawPublicKey(), - signature - ), + signature: xdr.ScVal.scvVoid(), }) ), rootInvocation: entry.rootInvocation(), }); + const preimage = buildSignaturePreimage( + deps.networkPassphrase, + addressEntry, + expirationLedger + ); + const payload = hash(preimage.toXDR()); + const signature = tempKeypair.sign(payload); + getAddressCredentials(addressEntry.credentials()).signature( + buildAddressSignatureScVal( + tempKeypair.rawPublicKey(), + signature + ) + ); signedAuthEntries.push(addressEntry); continue; } + if (credType === "sorobanCredentialsAddressWithDelegates") { + return { + success: false, + hash: "", + error: "ADDRESS_WITH_DELEGATES auth entries are not supported by fundWallet() yet", + }; + } + // For Address credentials, sign them - if (credType === "sorobanCredentialsAddress") { - const credentials = entry.credentials().address(); + if ( + credType === "sorobanCredentialsAddress" || + credType === "sorobanCredentialsAddressV2" + ) { + const credentials = getAddressCredentials(entry.credentials()); credentials.signatureExpirationLedger(expirationLedger); - const preimage = xdr.HashIdPreimage.envelopeTypeSorobanAuthorization( - new xdr.HashIdPreimageSorobanAuthorization({ - networkId: hash(Buffer.from(deps.networkPassphrase)), - nonce: credentials.nonce(), - signatureExpirationLedger: credentials.signatureExpirationLedger(), - invocation: entry.rootInvocation(), - }) - ); + const preimage = buildSignaturePreimage(deps.networkPassphrase, entry, expirationLedger); const payload = hash(preimage.toXDR()); const signature = tempKeypair.sign(payload); diff --git a/src/kit/webauthn-ops.ts b/src/kit/webauthn-ops.ts index 07ccdce..c066474 100644 --- a/src/kit/webauthn-ops.ts +++ b/src/kit/webauthn-ops.ts @@ -22,6 +22,8 @@ import { buildAuthDigest, buildSignaturePayload, buildWebAuthnSignatureBytes, + getAddressCredentials, + normalizeSignatureExpirationLedger, readAuthPayload, upsertAuthPayloadSigner, writeAuthPayload, @@ -127,8 +129,17 @@ export async function signAuthEntry( } ): Promise { const normalizedEntry = xdr.SorobanAuthorizationEntry.fromXDR(entry.toXDR()); - const credentials = normalizedEntry.credentials().address(); - const expiration = options?.expiration ?? await deps.calculateExpiration(); + const credentialType = normalizedEntry.credentials().switch().name as string; + if (credentialType === "sorobanCredentialsAddressWithDelegates") { + throw new Error( + "ADDRESS_WITH_DELEGATES auth entries are not supported by WebAuthn signing yet" + ); + } + + const credentials = getAddressCredentials(normalizedEntry.credentials()); + const expiration = normalizeSignatureExpirationLedger( + options?.expiration ?? await deps.calculateExpiration() + ); credentials.signatureExpirationLedger(expiration); const authPayload = readAuthPayload(credentials.signature()); diff --git a/src/managers/multi-signer-manager.ts b/src/managers/multi-signer-manager.ts index b288047..97a860f 100644 --- a/src/managers/multi-signer-manager.ts +++ b/src/managers/multi-signer-manager.ts @@ -36,7 +36,12 @@ import { import { buildAuthDigest, buildAddressSignatureScVal, + buildSignaturePreimage, buildSignaturePayload, + createAddressCredentials, + getAddressCredentials, + getAuthEntryAddress, + normalizeSignatureExpirationLedger, readAuthPayload, upsertAuthPayloadSigner, writeAuthPayload, @@ -142,15 +147,20 @@ export class MultiSignerManager { expiration: number ): Promise { const signedEntry = xdr.SorobanAuthorizationEntry.fromXDR(entry.toXDR()); - signedEntry.credentials().address().signatureExpirationLedger(expiration); - - const preimage = xdr.HashIdPreimage.envelopeTypeSorobanAuthorization( - new xdr.HashIdPreimageSorobanAuthorization({ - networkId: hash(Buffer.from(this.deps.networkPassphrase)), - nonce: signedEntry.credentials().address().nonce(), - signatureExpirationLedger: expiration, - invocation: signedEntry.rootInvocation(), - }) + const normalizedExpiration = normalizeSignatureExpirationLedger(expiration); + const credentialType = signedEntry.credentials().switch().name as string; + if (credentialType === "sorobanCredentialsAddressWithDelegates") { + throw new Error( + "ADDRESS_WITH_DELEGATES auth entries are not supported by wallet signing yet" + ); + } + + const credentials = getAddressCredentials(signedEntry.credentials()); + credentials.signatureExpirationLedger(normalizedExpiration); + const preimage = buildSignaturePreimage( + this.deps.networkPassphrase, + signedEntry, + normalizedExpiration ); const { signedAuthEntry } = await this.deps.externalSigners.signAuthEntry( @@ -158,7 +168,7 @@ export class MultiSignerManager { authAddress ); - signedEntry.credentials().address().signature( + credentials.signature( buildAddressSignatureScVal( Address.fromString(authAddress).toScAddress().accountId().ed25519(), Buffer.from(signedAuthEntry, "base64") @@ -207,13 +217,25 @@ export class MultiSignerManager { for (const [authEntryIndex, entry] of authEntries.entries()) { const credentials = entry.credentials(); + const credentialType = credentials.switch().name as string; + + if (credentialType === "sorobanCredentialsAddressWithDelegates") { + return { + success: false, + hash: "", + error: "ADDRESS_WITH_DELEGATES auth entries are not supported by multi-signer signing yet", + }; + } - if (credentials.switch().name !== "sorobanCredentialsAddress") { + if ( + credentialType !== "sorobanCredentialsAddress" && + credentialType !== "sorobanCredentialsAddressV2" + ) { signedAuthEntries.push(entry); continue; } - const authAddress = Address.fromScAddress(credentials.address().address()).toString(); + const authAddress = getAuthEntryAddress(entry); if (authAddress !== contractId) { const walletSigner = walletSigners.find((signer) => signer.walletAddress === authAddress); @@ -233,7 +255,8 @@ export class MultiSignerManager { } let signedEntry = xdr.SorobanAuthorizationEntry.fromXDR(entry.toXDR()); - signedEntry.credentials().address().signatureExpirationLedger(expiration); + const signedCredentials = getAddressCredentials(signedEntry.credentials()); + signedCredentials.signatureExpirationLedger(expiration); const selectedContractSigners = selectedSigners .map(({ signer }) => signer) .filter((signer): signer is ContractSigner => signer !== undefined); @@ -273,7 +296,7 @@ export class MultiSignerManager { } } - const authPayload = readAuthPayload(signedEntry.credentials().address().signature()); + const authPayload = readAuthPayload(signedCredentials.signature()); if (authPayload.context_rule_ids.length === 0) { authPayload.context_rule_ids = resolvedContextRuleIds; } @@ -282,7 +305,7 @@ export class MultiSignerManager { if (!walletSigner.walletAddress) continue; upsertAuthPayloadSigner(authPayload, walletSigner.signer as ContractSigner, Buffer.alloc(0)); } - signedEntry.credentials().address().signature(writeAuthPayload(authPayload)); + signedCredentials.signature(writeAuthPayload(authPayload)); signedAuthEntries.push(signedEntry); if (walletSigners.length === 0) { @@ -331,7 +354,7 @@ export class MultiSignerManager { signedAuthEntries.push( new xdr.SorobanAuthorizationEntry({ - credentials: xdr.SorobanCredentials.sorobanCredentialsAddress( + credentials: createAddressCredentials( new xdr.SorobanAddressCredentials({ address: Address.fromString(walletSigner.walletAddress).toScAddress(), nonce: delegatedNonce, From 72406178c9f1a2b186a45a0f2a7be48f17e3c4c8 Mon Sep 17 00:00:00 2001 From: kalepail Date: Mon, 8 Jun 2026 14:33:49 -0400 Subject: [PATCH 2/4] test stellar sdk v16 rc auth support --- demo/package.json | 3 +- demo/src/components/ContextRuleBuilder.tsx | 1 + demo/src/main.tsx | 2 +- demo/vite.config.ts | 3 +- package.json | 2 +- pnpm-lock.yaml | 175 +++++++++++++-------- src/kit/auth-payload.test.ts | 91 ++++++++--- src/kit/auth-payload.ts | 17 ++ 8 files changed, 202 insertions(+), 92 deletions(-) diff --git a/demo/package.json b/demo/package.json index 6c1807f..9894c37 100644 --- a/demo/package.json +++ b/demo/package.json @@ -10,8 +10,7 @@ }, "dependencies": { "@creit-tech/stellar-wallets-kit": "npm:@jsr/creit-tech__stellar-wallets-kit@^2.1.0", - "@stellar/stellar-base": "^15.0.0", - "@stellar/stellar-sdk": "^15.0.1", + "@stellar/stellar-sdk": "16.0.0-rc.1", "buffer": "^6.0.3", "react": "^19.2.4", "react-dom": "^19.2.4", diff --git a/demo/src/components/ContextRuleBuilder.tsx b/demo/src/components/ContextRuleBuilder.tsx index 9993e3a..bda6bdc 100644 --- a/demo/src/components/ContextRuleBuilder.tsx +++ b/demo/src/components/ContextRuleBuilder.tsx @@ -1,4 +1,5 @@ import { useState, useCallback, useEffect, useMemo } from "react"; +import type { Buffer } from "buffer"; import type { SmartAccountKit, StoredCredential, AssembledTransaction } from "smart-account-kit"; import { createDelegatedSigner, diff --git a/demo/src/main.tsx b/demo/src/main.tsx index 3830d8b..e5374e6 100644 --- a/demo/src/main.tsx +++ b/demo/src/main.tsx @@ -5,7 +5,7 @@ import "./styles.css"; // Polyfill Buffer for browser (required by stellar-sdk) import { Buffer } from "buffer"; -globalThis.Buffer = Buffer; +(globalThis as typeof globalThis & { Buffer: typeof Buffer }).Buffer = Buffer; ReactDOM.createRoot(document.getElementById("root")!).render( diff --git a/demo/vite.config.ts b/demo/vite.config.ts index 1ddcb2d..c13fd11 100644 --- a/demo/vite.config.ts +++ b/demo/vite.config.ts @@ -16,14 +16,13 @@ export default defineConfig({ // Ensure symlinks are resolved to prevent duplicate module instances preserveSymlinks: false, // Force Vite to use a single instance of these packages - dedupe: ["@stellar/stellar-sdk", "@stellar/stellar-base"], + dedupe: ["@stellar/stellar-sdk"], }, optimizeDeps: { include: [ "buffer", "@stellar/stellar-sdk", "@stellar/stellar-sdk/rpc", - "@stellar/stellar-base", ], esbuildOptions: { define: { diff --git a/package.json b/package.json index 5939ee6..67957ca 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ }, "dependencies": { "@simplewebauthn/browser": "^13.3.0", - "@stellar/stellar-sdk": ">=15.1.0", + "@stellar/stellar-sdk": "16.0.0-rc.1", "base64url": "^3.0.1", "smart-account-kit-bindings": "workspace:*" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6a7e09e..c18fe73 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,7 +5,7 @@ settings: excludeLinksFromLockfile: false overrides: - '@stellar/stellar-sdk': '>=15.1.0' + '@stellar/stellar-sdk': 16.0.0-rc.1 importers: @@ -15,8 +15,8 @@ importers: specifier: ^13.3.0 version: 13.3.0 '@stellar/stellar-sdk': - specifier: '>=15.1.0' - version: 15.1.0 + specifier: 16.0.0-rc.1 + version: 16.0.0-rc.1 base64url: specifier: ^3.0.1 version: 3.0.1 @@ -26,7 +26,7 @@ importers: devDependencies: '@creit-tech/stellar-wallets-kit': specifier: jsr:2.1.0 - version: '@jsr/creit-tech__stellar-wallets-kit@2.1.0(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2))(@stellar/stellar-sdk@15.1.0)(@trezor/connect@9.7.2(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@6.0.2)(utf-8-validate@5.0.10)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@types/react@19.2.14)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(near-api-js@5.1.1)(react@19.2.4)(tslib@2.8.1)(typescript@6.0.2)(utf-8-validate@5.0.10)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)' + version: '@jsr/creit-tech__stellar-wallets-kit@2.1.0(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2))(@stellar/stellar-sdk@16.0.0-rc.1)(@trezor/connect@9.7.2(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@6.0.2)(utf-8-validate@5.0.10)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@types/react@19.2.14)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(near-api-js@5.1.1)(react@19.2.4)(tslib@2.8.1)(typescript@6.0.2)(utf-8-validate@5.0.10)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)' '@types/node': specifier: ^25.5.2 version: 25.5.2 @@ -41,13 +41,10 @@ importers: dependencies: '@creit-tech/stellar-wallets-kit': specifier: npm:@jsr/creit-tech__stellar-wallets-kit@^2.1.0 - version: '@jsr/creit-tech__stellar-wallets-kit@2.1.0(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2))(@stellar/stellar-sdk@15.1.0)(@trezor/connect@9.7.2(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@6.0.2)(utf-8-validate@5.0.10)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@types/react@19.2.14)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(near-api-js@5.1.1)(react@19.2.4)(tslib@2.8.1)(typescript@6.0.2)(utf-8-validate@5.0.10)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)' - '@stellar/stellar-base': - specifier: ^15.0.0 - version: 15.0.0 + version: '@jsr/creit-tech__stellar-wallets-kit@2.1.0(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2))(@stellar/stellar-sdk@16.0.0-rc.1)(@trezor/connect@9.7.2(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@6.0.2)(utf-8-validate@5.0.10)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@types/react@19.2.14)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(near-api-js@5.1.1)(react@19.2.4)(tslib@2.8.1)(typescript@6.0.2)(utf-8-validate@5.0.10)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)' '@stellar/stellar-sdk': - specifier: '>=15.1.0' - version: 15.1.0 + specifier: 16.0.0-rc.1 + version: 16.0.0-rc.1 buffer: specifier: ^6.0.3 version: 6.0.3 @@ -86,8 +83,8 @@ importers: specifier: ^13.3.0 version: 13.3.0 '@stellar/stellar-sdk': - specifier: '>=15.1.0' - version: 15.1.0 + specifier: 16.0.0-rc.1 + version: 16.0.0-rc.1 smart-account-kit: specifier: workspace:^ version: link:../.. @@ -137,8 +134,8 @@ importers: packages/smart-account-kit-bindings: dependencies: '@stellar/stellar-sdk': - specifier: '>=15.1.0' - version: 15.1.0 + specifier: 16.0.0-rc.1 + version: 16.0.0-rc.1 buffer: specifier: 6.0.3 version: 6.0.3 @@ -703,6 +700,9 @@ packages: resolution: {integrity: sha512-vs1Az2OOTBiP4q0pwjW5aF0xp9n4MxVrmkFBxc6EKZc6ddYx5gaZiAsZoq0uRRXWbi3AT/sBqn05eRPtn1JCPw==} engines: {node: '>= 20.19.0'} + '@noble/ed25519@3.1.0': + resolution: {integrity: sha512-pfcObRY3CtvwfaG9Mt5XqZdKmAQppl37tHUeuBhDUbiwJBCVY4/A4lbMvb1xKhMDx96AqAqZpMWuBX1HulhX4g==} + '@noble/hashes@1.3.3': resolution: {integrity: sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==} engines: {node: '>= 16'} @@ -727,6 +727,10 @@ packages: resolution: {integrity: sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw==} engines: {node: '>= 20.19.0'} + '@noble/hashes@2.2.0': + resolution: {integrity: sha512-IYqDGiTXab6FniAgnSdZwgWbomxpy9FtYvLKs7wCUs2a8RkITG+DFGO1DM9cr+E3/RgADRpFjrKVaJ1z6sjtEg==} + engines: {node: '>= 20.19.0'} + '@openzeppelin/relayer-plugin-channels@0.20.0': resolution: {integrity: sha512-buZ0Xcir1mPcevMBU3vzbq4v77YUsikWX+E1k31YxdE6p97GEn40RnxNzow/eLNVnS3WNwYZ1SuEZgsQE7KHAg==} engines: {node: '>=22.18.0', npm: use pnpm, pnpm: '>=9', yarn: use pnpm} @@ -1594,13 +1598,9 @@ packages: resolution: {integrity: sha512-mI6Kjh9hGWDA1APawQTtCbR7702dNT/8Te1uuRFPqqdoAKBk3WpXOQI3ZSZO+5olW7BSHpmVG5KBPZpIpQxIvw==} engines: {node: '>=20.0.0'} - '@stellar/stellar-base@15.0.0': - resolution: {integrity: sha512-XQhxUr9BYiEcFcgc4oWcCMR9QJCny/GmmGsuwPKf/ieIcOeb5149KLHYx9mJCA0ea8QbucR2/GzV58QbXOTxQA==} - engines: {node: '>=20.0.0'} - - '@stellar/stellar-sdk@15.1.0': - resolution: {integrity: sha512-GsJUcWx2yboVzYdhTe/LHS3V1wVLSHkUkglC5bBoYWGJt31vzIhbSGno60NP9CdCTNkLJdnrsLJ63oA58Zvh5A==} - engines: {node: '>=20.0.0'} + '@stellar/stellar-sdk@16.0.0-rc.1': + resolution: {integrity: sha512-mkOQUsFgepFIxRFJLgjkLAkYQDBdNKgLpMM5yIWQcCUoXavb0gO1Dlw/hPqVg2KBKUKaXs2ljVLuB4x6bSWR0g==} + engines: {node: '>=22.0.0'} hasBin: true '@swc/helpers@0.5.17': @@ -1649,7 +1649,7 @@ packages: '@trezor/connect-plugin-stellar@9.2.6': resolution: {integrity: sha512-RA0Q4GHaf1mFxgSX183yyH+5tWEgS1j+sfe9KiUyIn/VnpXeUnaCpQuKMomAjGXQ5oNuvikTOdHYOqsvuEdOyw==} peerDependencies: - '@stellar/stellar-sdk': '>=15.1.0' + '@stellar/stellar-sdk': 16.0.0-rc.1 '@trezor/connect': 9.x.x tslib: ^2.6.2 @@ -1993,6 +1993,10 @@ packages: zod: optional: true + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + agent-base@7.1.4: resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} @@ -2042,8 +2046,8 @@ packages: axios@1.14.0: resolution: {integrity: sha512-3Y8yrqLSwjuzpXuZ0oIYZ/XGgLwUIBU3uLvbcpb0pidD9ctpShJd43KSlEEkVQg6DS0G9NKyzOvBfUtDKEyHvQ==} - axios@1.15.0: - resolution: {integrity: sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q==} + axios@1.16.1: + resolution: {integrity: sha512-caYkukvroVPO8KrzuJEb50Hm07KwfBZPEC3VeFHTsqWHvKTsy54hjJz9BS/cdaypROE2rH6xvm9mHX4fgWkr3A==} base-x@3.0.11: resolution: {integrity: sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==} @@ -2072,6 +2076,9 @@ packages: big.js@6.2.2: resolution: {integrity: sha512-y/ie+Faknx7sZA5MfGA2xKlu0GDv8RWrXGsmlteyJQ2lvoKv9GBK/fpRMc2qlSoBAgNxrixICFCBefIq8WCQpQ==} + bignumber.js@11.1.3: + resolution: {integrity: sha512-+esZiNSo6VgFokTsYX6mYqNJfFd/IczzZCd4Z7cR8e+AQWhvIcj6nqQ1h9814D9u/TApU0jjTVmfWL0Pd1ZBdA==} + bignumber.js@9.3.1: resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} @@ -2395,9 +2402,13 @@ packages: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} - eventsource@2.0.2: - resolution: {integrity: sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==} - engines: {node: '>=12.0.0'} + eventsource-parser@3.1.0: + resolution: {integrity: sha512-kJezFj9YFAMLeORyi7aCLxLbD5/qWMQnoMVlVPyHIll7lgRJCc3JVln9Vgl9nwQi0YkMnhdGTMNn7CkRRAptMg==} + engines: {node: '>=18.0.0'} + + eventsource@4.1.0: + resolution: {integrity: sha512-2GuF51iuHX6A9xdTccMTsNb7VO0lHZihApxhvQzJB5A03DvHDd2FQepodbMaztPBmBcE/ox7o2gqaxGhYB9LhQ==} + engines: {node: '>=20.0.0'} evp_bytestokey@1.0.3: resolution: {integrity: sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==} @@ -2450,6 +2461,15 @@ packages: debug: optional: true + follow-redirects@1.16.0: + resolution: {integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + for-each@0.3.5: resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} engines: {node: '>= 0.4'} @@ -2527,6 +2547,10 @@ packages: resolution: {integrity: sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==} engines: {node: '>= 0.6'} + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + humanize-ms@1.2.1: resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} @@ -3122,6 +3146,10 @@ packages: resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + smol-toml@1.6.1: + resolution: {integrity: sha512-dWUG8F5sIIARXih1DTaQAX4SsiTXhInKf1buxdY9DIg4ZYPZK5nGM1VRIYmEbDbsHt7USo99xSLFu5Q1IqTmsg==} + engines: {node: '>= 18'} + socks-proxy-agent@8.0.5: resolution: {integrity: sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==} engines: {node: '>= 14'} @@ -3218,9 +3246,6 @@ packages: resolution: {integrity: sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==} engines: {node: '>=0.6'} - toml@3.0.0: - resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==} - tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} @@ -3261,6 +3286,10 @@ packages: ufo@1.6.1: resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} + uint8array-extras@1.5.0: + resolution: {integrity: sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==} + engines: {node: '>=18'} + uint8array-tools@0.0.8: resolution: {integrity: sha512-xS6+s8e0Xbx++5/0L+yyexukU7pz//Yg6IHg3BKhXotg1JcYtgxVcUctQ0HxLByiJzpAkNFawz1Nz5Xadzo82g==} engines: {node: '>=14.0.0'} @@ -3346,9 +3375,6 @@ packages: uploadthing: optional: true - urijs@1.19.11: - resolution: {integrity: sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==} - usb@2.16.0: resolution: {integrity: sha512-jD88fvzDViMDH5KmmNJgzMBDj/95bDTt6+kBNaNxP4G98xUTnDMiLUY2CYmToba6JAFhM9VkcaQuxCNRLGR7zg==} engines: {node: '>=12.22.0 <13.0 || >=14.17.0'} @@ -3953,7 +3979,7 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 - '@jsr/creit-tech__stellar-wallets-kit@2.1.0(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2))(@stellar/stellar-sdk@15.1.0)(@trezor/connect@9.7.2(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@6.0.2)(utf-8-validate@5.0.10)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@types/react@19.2.14)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(near-api-js@5.1.1)(react@19.2.4)(tslib@2.8.1)(typescript@6.0.2)(utf-8-validate@5.0.10)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)': + '@jsr/creit-tech__stellar-wallets-kit@2.1.0(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2))(@stellar/stellar-sdk@16.0.0-rc.1)(@trezor/connect@9.7.2(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@6.0.2)(utf-8-validate@5.0.10)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@types/react@19.2.14)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(near-api-js@5.1.1)(react@19.2.4)(tslib@2.8.1)(typescript@6.0.2)(utf-8-validate@5.0.10)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)': dependencies: '@albedo-link/intent': 0.12.0 '@creit.tech/xbull-wallet-connect': 0.4.0 @@ -3967,7 +3993,7 @@ snapshots: '@reown/appkit': 1.8.19(@types/react@19.2.14)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.4)(typescript@6.0.2)(utf-8-validate@5.0.10)(zod@3.25.76) '@stellar/freighter-api': 6.0.0 '@stellar/stellar-base': 14.0.1 - '@trezor/connect-plugin-stellar': 9.2.6(@stellar/stellar-sdk@15.1.0)(@trezor/connect@9.7.2(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@6.0.2)(utf-8-validate@5.0.10)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(tslib@2.8.1) + '@trezor/connect-plugin-stellar': 9.2.6(@stellar/stellar-sdk@16.0.0-rc.1)(@trezor/connect@9.7.2(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@6.0.2)(utf-8-validate@5.0.10)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(tslib@2.8.1) '@trezor/connect-web': 9.7.2(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@6.0.2)(utf-8-validate@5.0.10)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@twind/core': 1.1.3(typescript@6.0.2) '@twind/preset-autoprefix': 1.0.7(@twind/core@1.1.3(typescript@6.0.2))(typescript@6.0.2) @@ -4202,6 +4228,8 @@ snapshots: dependencies: '@noble/hashes': 2.0.1 + '@noble/ed25519@3.1.0': {} + '@noble/hashes@1.3.3': {} '@noble/hashes@1.4.0': @@ -4215,14 +4243,17 @@ snapshots: '@noble/hashes@2.0.1': {} + '@noble/hashes@2.2.0': {} + '@openzeppelin/relayer-plugin-channels@0.20.0': dependencies: '@actions/exec': 1.1.1 '@openzeppelin/relayer-sdk': 1.10.0 - '@stellar/stellar-sdk': 15.1.0 + '@stellar/stellar-sdk': 16.0.0-rc.1 axios: 1.14.0 transitivePeerDependencies: - debug + - supports-color '@openzeppelin/relayer-sdk@1.10.0': dependencies: @@ -5555,28 +5586,23 @@ snapshots: buffer: 6.0.3 sha.js: 2.4.12 - '@stellar/stellar-base@15.0.0': + '@stellar/stellar-sdk@16.0.0-rc.1': dependencies: - '@noble/curves': 1.9.7 + '@noble/ed25519': 3.1.0 + '@noble/hashes': 2.2.0 '@stellar/js-xdr': 4.0.0 + axios: 1.16.1 base32.js: 0.1.0 - bignumber.js: 9.3.1 + bignumber.js: 11.1.3 buffer: 6.0.3 - sha.js: 2.4.12 - - '@stellar/stellar-sdk@15.1.0': - dependencies: - '@stellar/stellar-base': 15.0.0 - axios: 1.15.0 - bignumber.js: 9.3.1 commander: 14.0.3 - eventsource: 2.0.2 + eventsource: 4.1.0 feaxios: 0.0.23 - randombytes: 2.1.0 - toml: 3.0.0 - urijs: 1.19.11 + smol-toml: 1.6.1 + uint8array-extras: 1.5.0 transitivePeerDependencies: - debug + - supports-color '@swc/helpers@0.5.17': dependencies: @@ -5607,7 +5633,7 @@ snapshots: '@trezor/blockchain-link-utils@1.5.1(bufferutil@4.0.9)(tslib@2.8.1)(utf-8-validate@5.0.10)': dependencies: '@mobily/ts-belt': 3.13.1 - '@stellar/stellar-sdk': 15.1.0 + '@stellar/stellar-sdk': 16.0.0-rc.1 '@trezor/env-utils': 1.5.0(tslib@2.8.1) '@trezor/protobuf': 1.5.1(tslib@2.8.1) '@trezor/utils': 9.5.0(tslib@2.8.1) @@ -5619,12 +5645,13 @@ snapshots: - expo-constants - expo-localization - react-native + - supports-color - utf-8-validate '@trezor/blockchain-link-utils@1.5.2(bufferutil@4.0.9)(tslib@2.8.1)(utf-8-validate@5.0.10)': dependencies: '@mobily/ts-belt': 3.13.1 - '@stellar/stellar-sdk': 15.1.0 + '@stellar/stellar-sdk': 16.0.0-rc.1 '@trezor/env-utils': 1.5.0(tslib@2.8.1) '@trezor/protobuf': 1.5.2(tslib@2.8.1) '@trezor/utils': 9.5.0(tslib@2.8.1) @@ -5636,6 +5663,7 @@ snapshots: - expo-constants - expo-localization - react-native + - supports-color - utf-8-validate '@trezor/blockchain-link@2.6.1(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@6.0.2)(utf-8-validate@5.0.10)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': @@ -5646,7 +5674,7 @@ snapshots: '@solana-program/token-2022': 0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2)) '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2) - '@stellar/stellar-sdk': 15.1.0 + '@stellar/stellar-sdk': 16.0.0-rc.1 '@trezor/blockchain-link-types': 1.5.0(tslib@2.8.1) '@trezor/blockchain-link-utils': 1.5.1(bufferutil@4.0.9)(tslib@2.8.1)(utf-8-validate@5.0.10) '@trezor/env-utils': 1.5.0(tslib@2.8.1) @@ -5692,9 +5720,9 @@ snapshots: - expo-localization - react-native - '@trezor/connect-plugin-stellar@9.2.6(@stellar/stellar-sdk@15.1.0)(@trezor/connect@9.7.2(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@6.0.2)(utf-8-validate@5.0.10)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(tslib@2.8.1)': + '@trezor/connect-plugin-stellar@9.2.6(@stellar/stellar-sdk@16.0.0-rc.1)(@trezor/connect@9.7.2(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@6.0.2)(utf-8-validate@5.0.10)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(tslib@2.8.1)': dependencies: - '@stellar/stellar-sdk': 15.1.0 + '@stellar/stellar-sdk': 16.0.0-rc.1 '@trezor/connect': 9.7.2(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.2))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@6.0.2)(utf-8-validate@5.0.10)(ws@8.20.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@trezor/utils': 9.5.0(tslib@2.8.1) tslib: 2.8.1 @@ -6518,6 +6546,12 @@ snapshots: typescript: 6.0.2 zod: 3.25.76 + agent-base@6.0.2: + dependencies: + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + agent-base@7.1.4: {} agentkeepalive@4.6.0: @@ -6574,13 +6608,15 @@ snapshots: transitivePeerDependencies: - debug - axios@1.15.0: + axios@1.16.1: dependencies: - follow-redirects: 1.15.11 + follow-redirects: 1.16.0 form-data: 4.0.5 + https-proxy-agent: 5.0.1 proxy-from-env: 2.1.0 transitivePeerDependencies: - debug + - supports-color base-x@3.0.11: dependencies: @@ -6600,6 +6636,8 @@ snapshots: big.js@6.2.2: {} + bignumber.js@11.1.3: {} + bignumber.js@9.3.1: {} bindings@1.5.0: @@ -6980,7 +7018,11 @@ snapshots: events@3.3.0: {} - eventsource@2.0.2: {} + eventsource-parser@3.1.0: {} + + eventsource@4.1.0: + dependencies: + eventsource-parser: 3.1.0 evp_bytestokey@1.0.3: dependencies: @@ -7016,6 +7058,8 @@ snapshots: follow-redirects@1.15.11: {} + follow-redirects@1.16.0: {} + for-each@0.3.5: dependencies: is-callable: 1.2.7 @@ -7119,6 +7163,13 @@ snapshots: statuses: 1.5.0 toidentifier: 1.0.0 + https-proxy-agent@5.0.1: + dependencies: + agent-base: 6.0.2 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + humanize-ms@1.2.1: dependencies: ms: 2.1.3 @@ -7799,6 +7850,8 @@ snapshots: smart-buffer@4.2.0: {} + smol-toml@1.6.1: {} + socks-proxy-agent@8.0.5: dependencies: agent-base: 7.1.4 @@ -7894,8 +7947,6 @@ snapshots: toidentifier@1.0.0: {} - toml@3.0.0: {} - tr46@0.0.3: {} ts-mixer@6.0.4: {} @@ -7928,6 +7979,8 @@ snapshots: ufo@1.6.1: {} + uint8array-extras@1.5.0: {} + uint8array-tools@0.0.8: {} uint8arrays@3.1.1: @@ -7960,8 +8013,6 @@ snapshots: optionalDependencies: idb-keyval: 6.2.2 - urijs@1.19.11: {} - usb@2.16.0: dependencies: '@types/w3c-web-usb': 1.0.13 diff --git a/src/kit/auth-payload.test.ts b/src/kit/auth-payload.test.ts index cbad12b..d88dbe1 100644 --- a/src/kit/auth-payload.test.ts +++ b/src/kit/auth-payload.test.ts @@ -1,9 +1,17 @@ -import { Address, Keypair, hash, xdr } from "@stellar/stellar-sdk"; +import { + Address, + Keypair, + buildAuthorizationEntryPreimage, + buildWithDelegatesEntry, + hash, + xdr, +} from "@stellar/stellar-sdk"; import { describe, expect, it } from "vitest"; import type { AuthPayload, Signer } from "smart-account-kit-bindings"; import { buildAuthDigest, buildAddressSignatureScVal, + buildSignaturePreimage, buildSignaturePayload, createAddressCredentials, getAddressCredentials, @@ -127,12 +135,16 @@ describe("auth-payload", () => { expect(Address.fromScAddress(credentials.address()).toString()).toBe(account); }); - it("requires explicit opt-in for ADDRESS_V2 credentials", () => { + it("creates ADDRESS_V2 credentials only with explicit opt-in", () => { const credentials = getAddressCredentials(makeAuthEntry(makeAccount(5)).credentials()); - - expect(() => createAddressCredentials(credentials, { version: "address_v2" })).toThrow( - "ADDRESS_V2 credentials require an SDK with Protocol 27 credential support" - ); + const legacyCredentials = createAddressCredentials(credentials); + const addressV2Credentials = createAddressCredentials(credentials, { + version: "address_v2", + }); + + expect(legacyCredentials.switch().name).toBe("sorobanCredentialsAddress"); + expect(addressV2Credentials.switch().name).toBe("sorobanCredentialsAddressV2"); + expect(getAddressCredentials(addressV2Credentials).nonce().toString()).toBe("7"); }); it("rejects unsupported address credential versions", () => { @@ -143,26 +155,57 @@ describe("auth-payload", () => { ).toThrow("Unsupported Soroban address credential version: bogus"); }); - it("does not sign address-bound credentials without P27 preimage support", () => { - const credentials = getAddressCredentials(makeAuthEntry(makeAccount(7)).credentials()); - const fakeAddressV2Entry = { - credentials: () => ({ - switch: () => ({ name: "sorobanCredentialsAddressV2" }), - addressV2: () => credentials, + it("matches the SDK auth preimage helper for legacy ADDRESS credentials", () => { + const networkPassphrase = "Test SDF Network ; September 2015"; + const entry = makeAuthEntry(makeAccount(7)); + const expectedEntry = xdr.SorobanAuthorizationEntry.fromXDR(entry.toXDR()); + const preimage = buildSignaturePreimage(networkPassphrase, entry, 123); + const expected = buildAuthorizationEntryPreimage(expectedEntry, 123, networkPassphrase); + + expect(preimage.toXDR()).toEqual(expected.toXDR()); + expect(preimage.switch().name).toBe("envelopeTypeSorobanAuthorization"); + expect(getAddressCredentials(entry.credentials()).signatureExpirationLedger()).toBe(123); + }); + + it("matches the SDK auth preimage helper for ADDRESS_V2 credentials", () => { + const networkPassphrase = "Test SDF Network ; September 2015"; + const baseEntry = makeAuthEntry(makeAccount(8)); + const entry = new xdr.SorobanAuthorizationEntry({ + credentials: createAddressCredentials(getAddressCredentials(baseEntry.credentials()), { + version: "address_v2", }), - rootInvocation: () => makeAuthEntry(makeAccount(8)).rootInvocation(), - } as unknown as xdr.SorobanAuthorizationEntry; + rootInvocation: baseEntry.rootInvocation(), + }); + const expectedEntry = xdr.SorobanAuthorizationEntry.fromXDR(entry.toXDR()); + const preimage = buildSignaturePreimage(networkPassphrase, entry, 123); + const expected = buildAuthorizationEntryPreimage(expectedEntry, 123, networkPassphrase); + + expect(preimage.toXDR()).toEqual(expected.toXDR()); + expect(preimage.switch().name).toBe("envelopeTypeSorobanAuthorizationWithAddress"); + expect(buildSignaturePayload(networkPassphrase, entry, 123)).toHaveLength(32); + expect(getAddressCredentials(entry.credentials()).signatureExpirationLedger()).toBe(123); + }); - expect(() => - buildSignaturePayload("Test SDF Network ; September 2015", fakeAddressV2Entry, 123) - ).toThrow( - "Address-bound Soroban auth credentials require an SDK with Protocol 27 auth preimage support" + it("matches the SDK auth preimage helper for ADDRESS_WITH_DELEGATES credentials", () => { + const networkPassphrase = "Test SDF Network ; September 2015"; + const delegatedEntry = buildWithDelegatesEntry({ + entry: makeAuthEntry(makeAccount(14)), + validUntilLedgerSeq: 123, + delegates: [{ address: makeAccount(15) }], + }); + const expectedEntry = xdr.SorobanAuthorizationEntry.fromXDR(delegatedEntry.toXDR()); + const preimage = buildSignaturePreimage(networkPassphrase, delegatedEntry, 123); + const expected = buildAuthorizationEntryPreimage(expectedEntry, 123, networkPassphrase); + + expect(delegatedEntry.credentials().switch().name).toBe( + "sorobanCredentialsAddressWithDelegates" ); - expect(credentials.signatureExpirationLedger()).toBe(1); + expect(preimage.toXDR()).toEqual(expected.toXDR()); + expect(preimage.switch().name).toBe("envelopeTypeSorobanAuthorizationWithAddress"); }); it("keeps the submitted expiration in sync with the signed payload", () => { - const entry = makeAuthEntry(makeAccount(9)); + const entry = makeAuthEntry(makeAccount(16)); const payload = buildSignaturePayload("Test SDF Network ; September 2015", entry, 123); expect(payload).toHaveLength(32); @@ -170,7 +213,7 @@ describe("auth-payload", () => { }); it("rounds fractional signature expirations up before XDR serialization", () => { - const entry = makeAuthEntry(makeAccount(10)); + const entry = makeAuthEntry(makeAccount(17)); const payload = buildSignaturePayload("Test SDF Network ; September 2015", entry, 123.2); expect(payload).toHaveLength(32); @@ -178,7 +221,7 @@ describe("auth-payload", () => { }); it("rejects non-finite signature expirations without mutating the entry", () => { - const entry = makeAuthEntry(makeAccount(11)); + const entry = makeAuthEntry(makeAccount(18)); expect(() => buildSignaturePayload("Test SDF Network ; September 2015", entry, Number.NaN) @@ -187,8 +230,8 @@ describe("auth-payload", () => { }); it("rejects out-of-range signature expirations without mutating the entry", () => { - const negativeEntry = makeAuthEntry(makeAccount(12)); - const oversizedEntry = makeAuthEntry(makeAccount(13)); + const negativeEntry = makeAuthEntry(makeAccount(19)); + const oversizedEntry = makeAuthEntry(makeAccount(20)); expect(() => buildSignaturePayload("Test SDF Network ; September 2015", negativeEntry, -1) diff --git a/src/kit/auth-payload.ts b/src/kit/auth-payload.ts index be706c7..af6809e 100644 --- a/src/kit/auth-payload.ts +++ b/src/kit/auth-payload.ts @@ -1,3 +1,4 @@ +import * as StellarSdk from "@stellar/stellar-sdk"; import { Address, hash, xdr } from "@stellar/stellar-sdk"; import type { AuthPayload, @@ -21,6 +22,22 @@ export function buildSignaturePreimage( ): xdr.HashIdPreimage { const credentials = getAddressCredentials(entry.credentials()); const normalizedExpiration = normalizeSignatureExpirationLedger(expiration); + const sdkAuth = StellarSdk as unknown as { + buildAuthorizationEntryPreimage?: ( + entry: xdr.SorobanAuthorizationEntry, + validUntilLedgerSeq: number, + networkPassphrase: string + ) => xdr.HashIdPreimage; + }; + + if (sdkAuth.buildAuthorizationEntryPreimage) { + credentials.signatureExpirationLedger(normalizedExpiration); + return sdkAuth.buildAuthorizationEntryPreimage( + entry, + normalizedExpiration, + networkPassphrase + ); + } const hashIdPreimage = xdr.HashIdPreimage as unknown as { envelopeTypeSorobanAuthorizationWithAddress?: (value: unknown) => xdr.HashIdPreimage; From 4875d5de662494c4b7fc92daee4ced99131c6803 Mon Sep 17 00:00:00 2001 From: kalepail Date: Mon, 8 Jun 2026 14:42:46 -0400 Subject: [PATCH 3/4] polish stellar sdk rc readiness --- demo/src/components/ContextRuleBuilder.tsx | 4 +++- demo/src/styles.css | 2 +- package.json | 2 +- packages/smart-account-kit-bindings/package.json | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/demo/src/components/ContextRuleBuilder.tsx b/demo/src/components/ContextRuleBuilder.tsx index bda6bdc..517483e 100644 --- a/demo/src/components/ContextRuleBuilder.tsx +++ b/demo/src/components/ContextRuleBuilder.tsx @@ -1333,7 +1333,9 @@ export function ContextRuleBuilder({ {selectedPolicies.map((sp, index) => (
- {sp.policy.type} + + {sp.policy.type} + {sp.policy.name}