From 80f0b1d056077e068c3db1a34de6be2715c1a5d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ca=CC=81ssio=20Marcos=20Goulart?= Date: Thu, 26 Feb 2026 12:28:21 -0800 Subject: [PATCH 1/3] Upgrade stellar-sdk and node --- .../integration.anchorPlatformTest.yml | 2 +- .../workflows/integration.recoveryTest.yml | 2 +- .github/workflows/npmPublishSdk.yml | 2 +- .github/workflows/npmPublishSdkBeta.yml | 2 +- .github/workflows/npmPublishSdkKM.yml | 2 +- .github/workflows/npmPublishSdkKMBeta.yml | 2 +- .github/workflows/npmPublishSdkSoroban.yml | 2 +- .../workflows/npmPublishSdkSorobanBeta.yml | 2 +- .github/workflows/playwrightTests.yml | 2 +- .github/workflows/runTests.yml | 2 +- .../typescript-wallet-sdk-km/package.json | 4 +- .../test/keyManager.test.ts | 11 +- .../package.json | 4 +- .../src/Helpers/getInvocationDetails.ts | 8 +- .../src/Helpers/getTokenInvocationArgs.ts | 8 +- .../src/Helpers/scValByType.ts | 4 +- @stellar/typescript-wallet-sdk/package.json | 4 +- .../typescript-wallet-sdk/webpack.config.js | 3 + README.md | 2 +- babel.config.js | 7 +- yarn.lock | 231 +++++++++++++----- 21 files changed, 205 insertions(+), 101 deletions(-) diff --git a/.github/workflows/integration.anchorPlatformTest.yml b/.github/workflows/integration.anchorPlatformTest.yml index d07a95b0..e66439f6 100644 --- a/.github/workflows/integration.anchorPlatformTest.yml +++ b/.github/workflows/integration.anchorPlatformTest.yml @@ -8,6 +8,6 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: - node-version: 18 + node-version: 20 - run: yarn install - run: yarn test:anchorplatform:ci diff --git a/.github/workflows/integration.recoveryTest.yml b/.github/workflows/integration.recoveryTest.yml index 778508c9..bc18ae83 100644 --- a/.github/workflows/integration.recoveryTest.yml +++ b/.github/workflows/integration.recoveryTest.yml @@ -12,7 +12,7 @@ jobs: @stellar/typescript-wallet-sdk/test/docker/docker-compose.yml up -d - uses: actions/setup-node@v2 with: - node-version: 18 + node-version: 20 - run: yarn install - run: yarn build - run: yarn test:recovery:ci diff --git a/.github/workflows/npmPublishSdk.yml b/.github/workflows/npmPublishSdk.yml index c73f4ef7..f340a542 100644 --- a/.github/workflows/npmPublishSdk.yml +++ b/.github/workflows/npmPublishSdk.yml @@ -8,7 +8,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: - node-version: 18 + node-version: 20 registry-url: https://registry.npmjs.org/ - run: yarn install - run: yarn build diff --git a/.github/workflows/npmPublishSdkBeta.yml b/.github/workflows/npmPublishSdkBeta.yml index 66a96971..cee3e5b6 100644 --- a/.github/workflows/npmPublishSdkBeta.yml +++ b/.github/workflows/npmPublishSdkBeta.yml @@ -11,7 +11,7 @@ jobs: uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: - node-version: 18 + node-version: 20 registry-url: https://registry.npmjs.org/ - run: yarn install - run: yarn build diff --git a/.github/workflows/npmPublishSdkKM.yml b/.github/workflows/npmPublishSdkKM.yml index 9a8e3d55..afec91f2 100644 --- a/.github/workflows/npmPublishSdkKM.yml +++ b/.github/workflows/npmPublishSdkKM.yml @@ -8,7 +8,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: - node-version: 18 + node-version: 20 registry-url: https://registry.npmjs.org/ - run: yarn install - run: yarn build diff --git a/.github/workflows/npmPublishSdkKMBeta.yml b/.github/workflows/npmPublishSdkKMBeta.yml index 83072708..d2436519 100644 --- a/.github/workflows/npmPublishSdkKMBeta.yml +++ b/.github/workflows/npmPublishSdkKMBeta.yml @@ -11,7 +11,7 @@ jobs: uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: - node-version: 18 + node-version: 20 registry-url: https://registry.npmjs.org/ - run: yarn install - run: yarn build diff --git a/.github/workflows/npmPublishSdkSoroban.yml b/.github/workflows/npmPublishSdkSoroban.yml index 7f97ffb1..c4b2f573 100644 --- a/.github/workflows/npmPublishSdkSoroban.yml +++ b/.github/workflows/npmPublishSdkSoroban.yml @@ -8,7 +8,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: - node-version: 18 + node-version: 20 registry-url: https://registry.npmjs.org/ - run: yarn install - run: yarn build diff --git a/.github/workflows/npmPublishSdkSorobanBeta.yml b/.github/workflows/npmPublishSdkSorobanBeta.yml index 4bd0521b..bdf0784c 100644 --- a/.github/workflows/npmPublishSdkSorobanBeta.yml +++ b/.github/workflows/npmPublishSdkSorobanBeta.yml @@ -11,7 +11,7 @@ jobs: uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: - node-version: 18 + node-version: 20 registry-url: https://registry.npmjs.org/ - run: yarn install - run: yarn build diff --git a/.github/workflows/playwrightTests.yml b/.github/workflows/playwrightTests.yml index f84fa398..9c09b543 100644 --- a/.github/workflows/playwrightTests.yml +++ b/.github/workflows/playwrightTests.yml @@ -11,7 +11,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: - node-version: 18 + node-version: 20 - run: yarn install - run: yarn build - run: yarn test:e2e:ci diff --git a/.github/workflows/runTests.yml b/.github/workflows/runTests.yml index 7cea01d8..2b2fc4ca 100644 --- a/.github/workflows/runTests.yml +++ b/.github/workflows/runTests.yml @@ -8,7 +8,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: - node-version: 18 + node-version: 20 - run: yarn install - run: yarn build - run: yarn test:ci diff --git a/@stellar/typescript-wallet-sdk-km/package.json b/@stellar/typescript-wallet-sdk-km/package.json index 78aec7c9..a0bc4d84 100644 --- a/@stellar/typescript-wallet-sdk-km/package.json +++ b/@stellar/typescript-wallet-sdk-km/package.json @@ -2,7 +2,7 @@ "name": "@stellar/typescript-wallet-sdk-km", "version": "1.10.0", "engines": { - "node": ">=18" + "node": ">=20" }, "browser": "./lib/bundle_browser.js", "main": "./lib/bundle.js", @@ -38,7 +38,7 @@ "@stablelib/base64": "^2.0.0", "@stablelib/utf8": "^2.0.0", "@stellar/freighter-api": "^2.0.0", - "@stellar/stellar-sdk": "13.0.0-beta.1", + "@stellar/stellar-sdk": "14.5.0", "@trezor/connect-plugin-stellar": "^9.0.2", "bignumber.js": "^9.1.2", "scrypt-async": "^2.0.1", diff --git a/@stellar/typescript-wallet-sdk-km/test/keyManager.test.ts b/@stellar/typescript-wallet-sdk-km/test/keyManager.test.ts index 91f5a916..28eff5b4 100644 --- a/@stellar/typescript-wallet-sdk-km/test/keyManager.test.ts +++ b/@stellar/typescript-wallet-sdk-km/test/keyManager.test.ts @@ -918,8 +918,7 @@ describe("fetchAuthToken", () => { expect("This test failed: transaction didn't cause error").toBe(null); } catch (e) { expect(e.toString()).toMatch( - `InvalidChallengeError: The transaction` + - ` sequence number should be zero`, + `The transaction sequence number should be zero`, ); } }); @@ -1116,7 +1115,7 @@ describe("fetchAuthToken", () => { expect("This test failed: transaction didn't cause error").toBe(null); } catch (e) { expect(e.toString()).toMatch( - `InvalidChallengeError: Transaction not signed by server`, + `Transaction not signed by server`, ); } }); @@ -1311,8 +1310,7 @@ describe("fetchAuthToken", () => { expect("This test failed: transaction didn't cause error").toBe(null); } catch (e) { expect(e.toString()).toMatch( - `InvalidChallengeError: 'web_auth_domain' operation ` + - `value does not match www.stellar.org`, + `'web_auth_domain' operation value does not match www.stellar.org`, ); } }); @@ -1413,8 +1411,7 @@ describe("fetchAuthToken", () => { expect("This test failed: transaction didn't cause error").toBe(null); } catch (e) { expect(e.toString()).toMatch( - `InvalidChallengeError: The transaction source account` + - ` is not equal to the server's account`, + `The transaction source account is not equal to the server's account`, ); } }); diff --git a/@stellar/typescript-wallet-sdk-soroban/package.json b/@stellar/typescript-wallet-sdk-soroban/package.json index be469a14..ee35bb14 100644 --- a/@stellar/typescript-wallet-sdk-soroban/package.json +++ b/@stellar/typescript-wallet-sdk-soroban/package.json @@ -2,7 +2,7 @@ "name": "@stellar/typescript-wallet-sdk-soroban", "version": "1.10.0", "engines": { - "node": ">=18" + "node": ">=20" }, "browser": "./lib/bundle_browser.js", "main": "./lib/bundle.js", @@ -28,7 +28,7 @@ "webpack-cli": "^5.1.4" }, "dependencies": { - "@stellar/stellar-sdk": "13.0.0-beta.1" + "@stellar/stellar-sdk": "14.5.0" }, "scripts": { "prepare": "husky install", diff --git a/@stellar/typescript-wallet-sdk-soroban/src/Helpers/getInvocationDetails.ts b/@stellar/typescript-wallet-sdk-soroban/src/Helpers/getInvocationDetails.ts index 422e68ed..fd4fe6c6 100644 --- a/@stellar/typescript-wallet-sdk-soroban/src/Helpers/getInvocationDetails.ts +++ b/@stellar/typescript-wallet-sdk-soroban/src/Helpers/getInvocationDetails.ts @@ -1,4 +1,4 @@ -import { Address, Asset, StrKey, xdr } from "@stellar/stellar-sdk"; +import { Address, Asset, xdr } from "@stellar/stellar-sdk"; import { InvocationArgs } from "Types"; @@ -33,9 +33,9 @@ export const getInvocationArgs = ( // sorobanAuthorizedFunctionTypeContractFn case 0: { const _invocation = fn.contractFn(); - const contractId = StrKey.encodeContract( - _invocation.contractAddress().contractId(), - ); + const contractId = Address.fromScAddress( + _invocation.contractAddress(), + ).toString(); const fnName = _invocation.functionName().toString(); const args = _invocation.args(); return { fnName, contractId, args, type: "invoke" }; diff --git a/@stellar/typescript-wallet-sdk-soroban/src/Helpers/getTokenInvocationArgs.ts b/@stellar/typescript-wallet-sdk-soroban/src/Helpers/getTokenInvocationArgs.ts index 356109cb..2b3b5cf5 100644 --- a/@stellar/typescript-wallet-sdk-soroban/src/Helpers/getTokenInvocationArgs.ts +++ b/@stellar/typescript-wallet-sdk-soroban/src/Helpers/getTokenInvocationArgs.ts @@ -1,4 +1,4 @@ -import { Operation, StrKey, scValToNative, xdr } from "@stellar/stellar-sdk"; +import { Address, Operation, StrKey, scValToNative, xdr } from "@stellar/stellar-sdk"; import { ArgsForTokenInvocation, @@ -62,9 +62,9 @@ export const getTokenInvocationArgs = ( return null; } - const contractId = StrKey.encodeContract( - invokedContract.contractAddress().contractId(), - ); + const contractId = Address.fromScAddress( + invokedContract.contractAddress(), + ).toString(); const fnName = invokedContract .functionName() .toString() as SorobanTokenInterface; diff --git a/@stellar/typescript-wallet-sdk-soroban/src/Helpers/scValByType.ts b/@stellar/typescript-wallet-sdk-soroban/src/Helpers/scValByType.ts index 742a8ccb..db588466 100644 --- a/@stellar/typescript-wallet-sdk-soroban/src/Helpers/scValByType.ts +++ b/@stellar/typescript-wallet-sdk-soroban/src/Helpers/scValByType.ts @@ -1,4 +1,4 @@ -import { StrKey, scValToNative, xdr } from "@stellar/stellar-sdk"; +import { Address, StrKey, scValToNative, xdr } from "@stellar/stellar-sdk"; /* eslint-disable jsdoc/require-returns-type */ /** @@ -30,7 +30,7 @@ export const scValByType = (scVal: xdr.ScVal) => { if (addressType.name === "scAddressTypeAccount") { return StrKey.encodeEd25519PublicKey(address.accountId().ed25519()); } - return StrKey.encodeContract(address.contractId()); + return Address.fromScAddress(address).toString(); } case xdr.ScValType.scvBool(): { diff --git a/@stellar/typescript-wallet-sdk/package.json b/@stellar/typescript-wallet-sdk/package.json index bd893bc4..1198fc3e 100644 --- a/@stellar/typescript-wallet-sdk/package.json +++ b/@stellar/typescript-wallet-sdk/package.json @@ -2,7 +2,7 @@ "name": "@stellar/typescript-wallet-sdk", "version": "1.10.0", "engines": { - "node": ">=18" + "node": ">=20" }, "browser": "./lib/bundle_browser.js", "main": "./lib/bundle.js", @@ -47,7 +47,7 @@ "dependencies": { "@stablelib/base64": "^2.0.0", "@stablelib/utf8": "^2.0.0", - "@stellar/stellar-sdk": "13.0.0-beta.1", + "@stellar/stellar-sdk": "14.5.0", "axios": "^1.4.0", "base64url": "^3.0.1", "https-browserify": "^1.0.0", diff --git a/@stellar/typescript-wallet-sdk/webpack.config.js b/@stellar/typescript-wallet-sdk/webpack.config.js index 1067ba9d..6c91504c 100644 --- a/@stellar/typescript-wallet-sdk/webpack.config.js +++ b/@stellar/typescript-wallet-sdk/webpack.config.js @@ -39,6 +39,9 @@ module.exports = (env = { NODE: false }) => { globalObject: "this", filename: `bundle${isBrowser ? "_browser" : ""}.js`, path: path.resolve(__dirname, "lib"), + environment: { + bigIntLiteral: true, + }, }, target: isBrowser ? "web" : "node", plugins: isBrowser diff --git a/README.md b/README.md index 47ee8abe..cc3f78eb 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ wallet sdk, and two modules for extending functionality: You will need -- Node (>=18): https://nodejs.org/en/download/ +- Node (>=20): https://nodejs.org/en/download/ - Yarn (v1.22.5 or newer): https://classic.yarnpkg.com/en/docs/install ## Install and Build the Project diff --git a/babel.config.js b/babel.config.js index 701e967f..5498b4fa 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1 +1,6 @@ -module.exports = { presets: ["@babel/preset-typescript", "@babel/preset-env"] }; +module.exports = { + presets: [ + "@babel/preset-typescript", + ["@babel/preset-env", { targets: { node: "20" } }], + ], +}; diff --git a/yarn.lock b/yarn.lock index c6be77ea..9393ec5e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2441,6 +2441,18 @@ resolved "https://registry.yarnpkg.com/@ledgerhq/logs/-/logs-6.12.0.tgz#ad903528bf3687a44da435d7b2479d724d374f5d" integrity sha512-ExDoj1QV5eC6TEbMdLUMMk9cfvNKhhv5gXol4SmULRVCx/3iyCPhJ74nsb3S0Vb+/f+XujBEj3vQn5+cwS0fNA== +"@noble/curves@^1.9.6": + version "1.9.7" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.9.7.tgz#79d04b4758a43e4bca2cbdc62e7771352fa6b951" + integrity sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw== + dependencies: + "@noble/hashes" "1.8.0" + +"@noble/hashes@1.8.0": + version "1.8.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.8.0.tgz#cee43d801fcef9644b11b8194857695acd5f815a" + integrity sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A== + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -2546,30 +2558,29 @@ resolved "https://registry.yarnpkg.com/@stellar/prettier-config/-/prettier-config-1.0.1.tgz#498a66dc13c66859e3787dabdf958233ddbe9253" integrity sha512-w9OPycQp1XGfmHC2VUHe5shpZjNFRlmsRBaK7IHvOvVpglzV2QNJsVFh8RdLREWA0mzF59AWvQbyUCCJLPfdWw== -"@stellar/stellar-base@13.0.0-beta.1": - version "13.0.0-beta.1" - resolved "https://registry.yarnpkg.com/@stellar/stellar-base/-/stellar-base-13.0.0-beta.1.tgz#e703865c835106bd04b8a9f1e106ed65f6e249f4" - integrity sha512-S5c2FyKwUOc28/3sDoOfPIcdzcbUyfiYRmcUlscZrEX/VVzV12216XRkdWy2MYa8KQNK60MpR7wrGp2MamvVGg== +"@stellar/stellar-base@^14.0.4": + version "14.0.4" + resolved "https://registry.yarnpkg.com/@stellar/stellar-base/-/stellar-base-14.0.4.tgz#530511679588e8440277ded071e3a46a387c9fff" + integrity sha512-UbNW6zbdOBXJwLAV2mMak0bIC9nw3IZVlQXkv2w2dk1jgCbJjy3oRVC943zeGE5JAm0Z9PHxrIjmkpGhayY7kw== dependencies: + "@noble/curves" "^1.9.6" "@stellar/js-xdr" "^3.1.2" base32.js "^0.1.0" - bignumber.js "^9.1.2" + bignumber.js "^9.3.1" buffer "^6.0.3" - sha.js "^2.3.6" - tweetnacl "^1.0.3" - optionalDependencies: - sodium-native "^4.1.1" + sha.js "^2.4.12" -"@stellar/stellar-sdk@13.0.0-beta.1": - version "13.0.0-beta.1" - resolved "https://registry.yarnpkg.com/@stellar/stellar-sdk/-/stellar-sdk-13.0.0-beta.1.tgz#9a995575b806bea3a383b2d9fe4b1fde065caeb4" - integrity sha512-yJN2HzibhZFJsdLRU83bkUwb9dq1sZRRiQptTJyunVv0hQsF+tTldrP3hHst3LROv/2GWTn20tmAqnp0hkzOhg== +"@stellar/stellar-sdk@14.5.0": + version "14.5.0" + resolved "https://registry.yarnpkg.com/@stellar/stellar-sdk/-/stellar-sdk-14.5.0.tgz#250015e67c2d99e94b010d05cbacecb9e49dd6da" + integrity sha512-Uzjq+An/hUA+Q5ERAYPtT0+MMiwWnYYWMwozmZMjxjdL2MmSjucBDF8Q04db6K/ekU4B5cHuOfsdlrfaxQYblw== dependencies: - "@stellar/stellar-base" "13.0.0-beta.1" - axios "^1.7.7" - bignumber.js "^9.1.2" + "@stellar/stellar-base" "^14.0.4" + axios "^1.13.3" + bignumber.js "^9.3.1" + commander "^14.0.2" eventsource "^2.0.2" - feaxios "^0.0.20" + feaxios "^0.0.23" randombytes "^2.1.0" toml "^3.0.0" urijs "^1.19.1" @@ -3263,16 +3274,14 @@ available-typed-arrays@^1.0.5: resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== -axios@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.4.0.tgz#38a7bf1224cd308de271146038b551d725f0be1f" - integrity sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA== +available-typed-arrays@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz#a5cc375d6a03c2efc87a553f3e0b1522def14846" + integrity sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ== dependencies: - follow-redirects "^1.15.0" - form-data "^4.0.0" - proxy-from-env "^1.1.0" + possible-typed-array-names "^1.0.0" -axios@^1.7.7: +axios@^1.13.3: version "1.13.5" resolved "https://registry.yarnpkg.com/axios/-/axios-1.13.5.tgz#5e464688fa127e11a660a2c49441c009f6567a43" integrity sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q== @@ -3281,6 +3290,15 @@ axios@^1.7.7: form-data "^4.0.5" proxy-from-env "^1.1.0" +axios@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.4.0.tgz#38a7bf1224cd308de271146038b551d725f0be1f" + integrity sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA== + dependencies: + follow-redirects "^1.15.0" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + babel-jest@^29.4.1, babel-jest@^29.4.3: version "29.4.3" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.4.3.tgz#478b84d430972b277ad67dd631be94abea676792" @@ -3425,26 +3443,6 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -bare-addon-resolve@^1.3.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/bare-addon-resolve/-/bare-addon-resolve-1.10.0.tgz#21fa56b9fb398ca46202cbc713c653f25daf4264" - integrity sha512-sSd0jieRJlDaODOzj0oe0RjFVC1QI0ZIjGIdPkbrTXsdVVtENg14c+lHHAhHwmWCZ2nQlMhy8jA3Y5LYPc/isA== - dependencies: - bare-module-resolve "^1.10.0" - bare-semver "^1.0.0" - -bare-module-resolve@^1.10.0: - version "1.12.1" - resolved "https://registry.yarnpkg.com/bare-module-resolve/-/bare-module-resolve-1.12.1.tgz#4847c1c91a6fce124b45bc36f97caa6bf6658d42" - integrity sha512-hbmAPyFpEq8FoZMd5sFO3u6MC5feluWoGE8YKlA8fCrl6mNtx68Wjg4DTiDJcqRJaovTvOYKfYngoBUnbaT7eg== - dependencies: - bare-semver "^1.0.0" - -bare-semver@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bare-semver/-/bare-semver-1.0.2.tgz#3cfc47ed5d3e809b369daec534ce916b70b83b8c" - integrity sha512-ESVaN2nzWhcI5tf3Zzcq9aqCZ676VWzqw07eEZ0qxAcEOAFYBa0pWq8sK34OQeHLY3JsfKXZS9mDyzyxGjeLzA== - base32.js@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/base32.js/-/base32.js-0.1.0.tgz#b582dec693c2f11e893cf064ee6ac5b6131a2202" @@ -3465,6 +3463,11 @@ bignumber.js@^9.1.2: resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c" integrity sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug== +bignumber.js@^9.3.1: + version "9.3.1" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.3.1.tgz#759c5aaddf2ffdc4f154f7b493e1c8770f88c4d7" + integrity sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ== + bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9: version "4.12.0" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" @@ -3647,7 +3650,7 @@ bytes@3.1.2: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== -call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: +call-bind-apply-helpers@^1.0.0, call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6" integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ== @@ -3663,6 +3666,24 @@ call-bind@^1.0.0, call-bind@^1.0.2: function-bind "^1.1.1" get-intrinsic "^1.0.2" +call-bind@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.8.tgz#0736a9660f537e3388826f440d5ec45f744eaa4c" + integrity sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww== + dependencies: + call-bind-apply-helpers "^1.0.0" + es-define-property "^1.0.0" + get-intrinsic "^1.2.4" + set-function-length "^1.2.2" + +call-bound@^1.0.3, call-bound@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/call-bound/-/call-bound-1.0.4.tgz#238de935d2a2a692928c538c7ccfa91067fd062a" + integrity sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg== + dependencies: + call-bind-apply-helpers "^1.0.2" + get-intrinsic "^1.3.0" + callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -3827,6 +3848,11 @@ commander@^10.0.1: resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== +commander@^14.0.2: + version "14.0.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-14.0.3.tgz#425d79b48f9af82fcd9e4fc1ea8af6c5ec07bbc2" + integrity sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw== + commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" @@ -4025,6 +4051,15 @@ deepmerge@^4.2.2: resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.0.tgz#65491893ec47756d44719ae520e0e2609233b59b" integrity sha512-z2wJZXrmeHdvYJp/Ux55wIjqo81G5Bp4c+oELTW+7ar6SogWHajt5a9gO3s3IDaGSAXjDk0vlQKN3rms8ab3og== +define-data-property@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" + integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + gopd "^1.0.1" + define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.0.tgz#52988570670c9eacedd8064f4a990f2405849bd5" @@ -4258,7 +4293,7 @@ es-abstract@^1.20.4, es-abstract@^1.22.1: unbox-primitive "^1.0.2" which-typed-array "^1.1.10" -es-define-property@^1.0.1: +es-define-property@^1.0.0, es-define-property@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa" integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g== @@ -4647,10 +4682,10 @@ fb-watchman@^2.0.0: dependencies: bser "2.1.1" -feaxios@^0.0.20: - version "0.0.20" - resolved "https://registry.yarnpkg.com/feaxios/-/feaxios-0.0.20.tgz#04e976beb7345401fedeba764f0e9e1c4d01afd4" - integrity sha512-g3hm2YDNffNxA3Re3Hd8ahbpmDee9Fv1Pb1C/NoWsjY7mtD8nyNeJytUzn+DK0Hyl9o6HppeWOrtnqgmhOYfWA== +feaxios@^0.0.23: + version "0.0.23" + resolved "https://registry.yarnpkg.com/feaxios/-/feaxios-0.0.23.tgz#76f37a2666232377ce75354e46dd85cbceeb1758" + integrity sha512-eghR0A21fvbkcQBgZuMfQhrXxJzC0GNUGC9fXhBge33D+mFDTwl0aJ35zoQQn575BhyjQitRc5N4f+L4cP708g== dependencies: is-retry-allowed "^3.0.0" @@ -4732,6 +4767,13 @@ for-each@^0.3.3: dependencies: is-callable "^1.1.3" +for-each@^0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.5.tgz#d650688027826920feeb0af747ee7b9421a41d47" + integrity sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg== + dependencies: + is-callable "^1.2.7" + form-data@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" @@ -4817,7 +4859,7 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@ has-proto "^1.0.1" has-symbols "^1.0.3" -get-intrinsic@^1.2.6: +get-intrinsic@^1.2.4, get-intrinsic@^1.2.6, get-intrinsic@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz#743f0e3b6964a93a5491ed1bffaae054d7f98d01" integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ== @@ -4977,6 +5019,13 @@ has-property-descriptors@^1.0.0: dependencies: get-intrinsic "^1.1.1" +has-property-descriptors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" + integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== + dependencies: + es-define-property "^1.0.0" + has-proto@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" @@ -5358,6 +5407,13 @@ is-typed-array@^1.1.10, is-typed-array@^1.1.3: gopd "^1.0.1" has-tostringtag "^1.0.0" +is-typed-array@^1.1.14: + version "1.1.15" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.15.tgz#4bfb4a45b61cee83a5a46fba778e4e8d59c0ce0b" + integrity sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ== + dependencies: + which-typed-array "^1.1.16" + is-typed-array@^1.1.9: version "1.1.12" resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" @@ -6960,6 +7016,11 @@ playwright@^1.43.1: optionalDependencies: fsevents "2.3.2" +possible-typed-array-names@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz#93e3582bc0e5426586d9d07b79ee40fc841de4ae" + integrity sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg== + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" @@ -7230,13 +7291,6 @@ regjsparser@^0.9.1: dependencies: jsesc "~0.5.0" -require-addon@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/require-addon/-/require-addon-1.2.0.tgz#b6a969805b82f5ed8b2ecf29453b090ca9933c89" - integrity sha512-VNPDZlYgIYQwWp9jMTzljx+k0ZtatKlcvOhktZ/anNPI3dQ9NXk7cq2U4iJ1wd9IrytRnYhyEocFWbkdPb+MYA== - dependencies: - bare-addon-resolve "^1.3.0" - require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -7472,6 +7526,18 @@ serve-static@1.15.0: parseurl "~1.3.3" send "0.18.0" +set-function-length@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" + integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== + dependencies: + define-data-property "^1.1.4" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + gopd "^1.0.1" + has-property-descriptors "^1.0.2" + setprototypeof@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" @@ -7485,6 +7551,15 @@ sha.js@^2.3.6, sha.js@^2.4.0, sha.js@^2.4.8: inherits "^2.0.1" safe-buffer "^5.0.1" +sha.js@^2.4.12: + version "2.4.12" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.12.tgz#eb8b568bf383dfd1867a32c3f2b74eb52bdbf23f" + integrity sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w== + dependencies: + inherits "^2.0.4" + safe-buffer "^5.2.1" + to-buffer "^1.2.0" + shallow-clone@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" @@ -7582,13 +7657,6 @@ slice-ansi@^5.0.0: ansi-styles "^6.0.0" is-fullwidth-code-point "^4.0.0" -sodium-native@^4.1.1: - version "4.3.3" - resolved "https://registry.yarnpkg.com/sodium-native/-/sodium-native-4.3.3.tgz#fae4866b52366f5e6cc1b7ae8c8a71673d50c7df" - integrity sha512-OnxSlN3uyY8D0EsLHpmm2HOFmKddQVvEMmsakCrXUzSd8kjjbzL413t4ZNF3n0UxSwNgwTyUvkmZHTfuCeiYSw== - dependencies: - require-addon "^1.1.0" - source-map-support@0.5.13: version "0.5.13" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" @@ -7898,6 +7966,15 @@ tmpl@1.0.5: resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== +to-buffer@^1.2.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.2.2.tgz#ffe59ef7522ada0a2d1cb5dfe03bb8abc3cdc133" + integrity sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw== + dependencies: + isarray "^2.0.5" + safe-buffer "^5.2.1" + typed-array-buffer "^1.0.3" + to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" @@ -8071,6 +8148,15 @@ typed-array-buffer@^1.0.0: get-intrinsic "^1.2.1" is-typed-array "^1.1.10" +typed-array-buffer@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz#a72395450a4869ec033fd549371b47af3a2ee536" + integrity sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw== + dependencies: + call-bound "^1.0.3" + es-errors "^1.3.0" + is-typed-array "^1.1.14" + typed-array-byte-length@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz#d787a24a995711611fb2b87a4052799517b230d0" @@ -8409,6 +8495,19 @@ which-typed-array@^1.1.10, which-typed-array@^1.1.11: gopd "^1.0.1" has-tostringtag "^1.0.0" +which-typed-array@^1.1.16: + version "1.1.20" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.20.tgz#3fdb7adfafe0ea69157b1509f3a1cd892bd1d122" + integrity sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg== + dependencies: + available-typed-arrays "^1.0.7" + call-bind "^1.0.8" + call-bound "^1.0.4" + for-each "^0.3.5" + get-proto "^1.0.1" + gopd "^1.2.0" + has-tostringtag "^1.0.2" + which-typed-array@^1.1.2: version "1.1.9" resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.9.tgz#307cf898025848cf995e795e8423c7f337efbde6" From 3762634942ab0eb6ac9c416bc3f9c266127b4383 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ca=CC=81ssio=20Marcos=20Goulart?= Date: Thu, 26 Feb 2026 12:57:57 -0800 Subject: [PATCH 2/3] Make Sep-10 Signing Key required --- .../src/walletSdk/Anchor/index.ts | 4 + .../src/walletSdk/Auth/index.ts | 164 +--------- .../src/walletSdk/Exceptions/index.ts | 9 + .../src/walletSdk/Recovery/index.ts | 2 +- .../src/walletSdk/Types/recovery.ts | 2 +- .../typescript-wallet-sdk/test/auth.test.ts | 306 +----------------- .../test/integration/recovery.test.ts | 2 + 7 files changed, 32 insertions(+), 457 deletions(-) diff --git a/@stellar/typescript-wallet-sdk/src/walletSdk/Anchor/index.ts b/@stellar/typescript-wallet-sdk/src/walletSdk/Anchor/index.ts index 4bc64a28..99d6bd3e 100644 --- a/@stellar/typescript-wallet-sdk/src/walletSdk/Anchor/index.ts +++ b/@stellar/typescript-wallet-sdk/src/walletSdk/Anchor/index.ts @@ -7,6 +7,7 @@ import { Customer, Sep12 } from "../Customer"; import { ServerRequestFailedError, KYCServerNotFoundError, + MissingSigningKeyError, } from "../Exceptions"; import { Sep6, Transfer } from "./Sep6"; import { Interactive, Sep24 } from "./Sep24"; @@ -104,6 +105,9 @@ export class Anchor { */ async sep10(): Promise { const tomlInfo = await this.sep1(); + if (!tomlInfo.signingKey) { + throw new MissingSigningKeyError(); + } return new Sep10({ cfg: this.cfg, webAuthEndpoint: tomlInfo.webAuthEndpoint, diff --git a/@stellar/typescript-wallet-sdk/src/walletSdk/Auth/index.ts b/@stellar/typescript-wallet-sdk/src/walletSdk/Auth/index.ts index a1a25ca0..1201d530 100644 --- a/@stellar/typescript-wallet-sdk/src/walletSdk/Auth/index.ts +++ b/@stellar/typescript-wallet-sdk/src/walletSdk/Auth/index.ts @@ -1,10 +1,5 @@ import { AxiosInstance } from "axios"; -import { - TransactionBuilder, - Transaction, - FeeBumpTransaction, - WebAuth, -} from "@stellar/stellar-sdk"; +import { TransactionBuilder, Transaction, WebAuth } from "@stellar/stellar-sdk"; import { decode } from "jws"; import { Config } from "../"; @@ -38,7 +33,7 @@ type Sep10Params = { webAuthEndpoint: string; homeDomain: string; httpClient: AxiosInstance; - serverSigningKey?: string; + serverSigningKey: string; }; /** @@ -57,7 +52,7 @@ export class Sep10 { private webAuthEndpoint: string; private homeDomain: string; private httpClient: AxiosInstance; - private serverSigningKey?: string; + private serverSigningKey: string; /** * Creates a new instance of the Sep10 class. @@ -176,22 +171,13 @@ export class Sep10 { try { const webAuthDomain = new URL(this.webAuthEndpoint).hostname; - if (this.serverSigningKey) { - WebAuth.readChallengeTx( - challengeResponse.transaction, - this.serverSigningKey, - networkPassphrase, - this.homeDomain, - webAuthDomain, - ); - } else { - readChallengeTx( - challengeResponse.transaction, - networkPassphrase, - this.homeDomain, - webAuthDomain, - ); - } + WebAuth.readChallengeTx( + challengeResponse.transaction, + this.serverSigningKey, + networkPassphrase, + this.homeDomain, + webAuthDomain, + ); } catch (e) { throw new ChallengeValidationFailedError( e instanceof Error ? e : new Error(String(e)), @@ -255,136 +241,6 @@ export const validateToken = (token: string) => { } }; -/* - * Validates a SEP-10 challenge transaction without requiring the server's - * signing key. This performs all structural validations from the SEP-10 spec - * (sequence number, operation types, timebounds, home domain, web_auth_domain, - * nonce format) but skips the server account and signature checks. - * - * Used as a fallback when the anchor's stellar.toml does not publish a - * SIGNING_KEY, providing strong protection against malformed or malicious - * challenge transactions. - * - * @internal - * @see {@link https://github.com/stellar/js-stellar-sdk/blob/v13.0.0-beta.1/src/webauth/utils.ts#L188 | WebAuth.readChallengeTx} - */ -const readChallengeTx = ( - challengeTx: string, - networkPassphrase: string, - homeDomain: string, - webAuthDomain: string, -): { tx: Transaction; clientAccountID: string } => { - let transaction: Transaction; - try { - transaction = new Transaction(challengeTx, networkPassphrase); - } catch { - try { - // eslint-disable-next-line no-new - new FeeBumpTransaction(challengeTx, networkPassphrase); - } catch { - throw new Error( - "Invalid challenge: unable to deserialize challengeTx transaction string", - ); - } - throw new Error( - "Invalid challenge: expected a Transaction but received a FeeBumpTransaction", - ); - } - - // verify sequence number - const sequence = Number.parseInt(transaction.sequence, 10); - if (sequence !== 0) { - throw new Error("The transaction sequence number should be zero"); - } - - // verify operations - if (transaction.operations.length < 1) { - throw new Error("The transaction should contain at least one operation"); - } - - const [operation, ...subsequentOperations] = transaction.operations; - - if (!operation.source) { - throw new Error( - "The transaction's operation should contain a source account", - ); - } - const clientAccountID: string = operation.source; - - // verify memo - if (transaction.memo.type !== "none") { - if (clientAccountID.startsWith("M")) { - throw new Error( - "The transaction has a memo but the client account ID is a muxed account", - ); - } - if (transaction.memo.type !== "id") { - throw new Error("The transaction's memo must be of type `id`"); - } - } - - if (operation.type !== "manageData") { - throw new Error("The transaction's operation type should be 'manageData'"); - } - - // verify timebounds - if (!transaction.timeBounds) { - throw new Error("The transaction requires timebounds"); - } - - if (Number.parseInt(transaction.timeBounds.maxTime, 10) === 0) { - throw new Error("The transaction requires non-infinite timebounds"); - } - - const now = Math.floor(Date.now() / 1000); - const gracePeriod = 60 * 5; - const minTime = Number.parseInt(transaction.timeBounds.minTime, 10) || 0; - const maxTime = Number.parseInt(transaction.timeBounds.maxTime, 10) || 0; - if (now < minTime - gracePeriod || now > maxTime + gracePeriod) { - throw new Error("The transaction has expired"); - } - - // verify nonce value - if (operation.value === undefined || !operation.value) { - throw new Error("The transaction's operation value should not be null"); - } - - if (Buffer.from(operation.value.toString(), "base64").length !== 48) { - throw new Error( - "The transaction's operation value should be a 64 bytes base64 random string", - ); - } - - // verify home domain - if (`${homeDomain} auth` !== operation.name) { - throw new Error( - "Invalid homeDomains: the transaction's operation key name " + - "does not match the expected home domain", - ); - } - - // verify subsequent operations are all manageData - for (const op of subsequentOperations) { - if (op.type !== "manageData") { - throw new Error( - "The transaction has operations that are not of type 'manageData'", - ); - } - if (op.name === "web_auth_domain") { - if (op.value === undefined) { - throw new Error("'web_auth_domain' operation value should not be null"); - } - if (op.value.compare(Buffer.from(webAuthDomain)) !== 0) { - throw new Error( - `'web_auth_domain' operation value does not match ${webAuthDomain}`, - ); - } - } - } - - return { tx: transaction, clientAccountID }; -}; - const createAuthSignToken = async ( account: AccountKeypair, claims: AuthHeaderClaims, diff --git a/@stellar/typescript-wallet-sdk/src/walletSdk/Exceptions/index.ts b/@stellar/typescript-wallet-sdk/src/walletSdk/Exceptions/index.ts index 0931a214..b8cca237 100644 --- a/@stellar/typescript-wallet-sdk/src/walletSdk/Exceptions/index.ts +++ b/@stellar/typescript-wallet-sdk/src/walletSdk/Exceptions/index.ts @@ -280,6 +280,15 @@ export class Sep38PriceOnlyOneAmountError extends Error { } } +export class MissingSigningKeyError extends Error { + constructor() { + super( + "Anchor's stellar.toml does not contain a SIGNING_KEY, which is required for SEP-10 authentication", + ); + Object.setPrototypeOf(this, MissingSigningKeyError.prototype); + } +} + export class ChallengeValidationFailedError extends Error { constructor(cause: Error) { super(`SEP-10 challenge validation failed: ${cause.message}`); diff --git a/@stellar/typescript-wallet-sdk/src/walletSdk/Recovery/index.ts b/@stellar/typescript-wallet-sdk/src/walletSdk/Recovery/index.ts index dfbf61b6..93d9752d 100644 --- a/@stellar/typescript-wallet-sdk/src/walletSdk/Recovery/index.ts +++ b/@stellar/typescript-wallet-sdk/src/walletSdk/Recovery/index.ts @@ -76,7 +76,7 @@ export class Recovery extends AccountRecover { webAuthEndpoint: server.authEndpoint, homeDomain: server.homeDomain, httpClient: this.httpClient, - ...(server.signingKey && { serverSigningKey: server.signingKey }), + serverSigningKey: server.signingKey, }); } diff --git a/@stellar/typescript-wallet-sdk/src/walletSdk/Types/recovery.ts b/@stellar/typescript-wallet-sdk/src/walletSdk/Types/recovery.ts index d967d027..41032df2 100644 --- a/@stellar/typescript-wallet-sdk/src/walletSdk/Types/recovery.ts +++ b/@stellar/typescript-wallet-sdk/src/walletSdk/Types/recovery.ts @@ -63,7 +63,7 @@ export type RecoveryServer = { endpoint: string; authEndpoint: string; homeDomain: string; - signingKey?: string; + signingKey: string; walletSigner?: WalletSigner; clientDomain?: string; }; diff --git a/@stellar/typescript-wallet-sdk/test/auth.test.ts b/@stellar/typescript-wallet-sdk/test/auth.test.ts index f3cc5f00..f41076ea 100644 --- a/@stellar/typescript-wallet-sdk/test/auth.test.ts +++ b/@stellar/typescript-wallet-sdk/test/auth.test.ts @@ -11,7 +11,6 @@ import { TransactionBuilder as SdkTransactionBuilder, Operation, BASE_FEE, - xdr as StellarXdr, } from "@stellar/stellar-sdk"; import { randomBytes } from "crypto"; import axios from "axios"; @@ -30,6 +29,7 @@ import { ExpiredTokenError, ChallengeValidationFailedError, NetworkPassphraseMismatchError, + MissingSigningKeyError, } from "../src/walletSdk/Exceptions"; const createToken = (payload: Record): string => { @@ -261,7 +261,7 @@ describe("Sep10 challenge validation", () => { token, responseNetworkPassphrase = networkPassphrase, }: { - serverSigningKey?: string; + serverSigningKey: string; challengeXdr: string; token: string; responseNetworkPassphrase?: string; @@ -282,7 +282,7 @@ describe("Sep10 challenge validation", () => { webAuthEndpoint, homeDomain, httpClient, - ...(serverSigningKey ? { serverSigningKey } : {}), + serverSigningKey, }); return { sep10, postStub }; @@ -618,301 +618,6 @@ describe("Sep10 challenge validation", () => { }); }); - // ============================================================ - // WITHOUT serverSigningKey — uses local readChallengeTx - // ============================================================ - describe("without serverSigningKey (local readChallengeTx)", () => { - const authenticateWithoutKey = ( - challengeXdr: string, - clientKeypair: Keypair, - ) => { - const accountKp = SigningKeypair.fromSecret(clientKeypair.secret()); - const token = createJwt(clientKeypair); - const { sep10, postStub } = setupSep10({ - challengeXdr, - token, - }); - return { sep10, accountKp, postStub }; - }; - - it("should accept a valid challenge", async () => { - const { xdr, clientKeypair } = buildChallenge(); - const { sep10, accountKp } = authenticateWithoutKey(xdr, clientKeypair); - const authToken = await sep10.authenticate({ accountKp }); - expect(authToken.account).toBe(clientKeypair.publicKey()); - }); - - it("should reject invalid XDR", async () => { - const clientKeypair = Keypair.random(); - const { sep10, accountKp, postStub } = authenticateWithoutKey( - "not-valid-xdr", - clientKeypair, - ); - await expect(sep10.authenticate({ accountKp })).rejects.toThrow( - ChallengeValidationFailedError, - ); - expect(postStub.notCalled).toBe(true); - }); - - it("should reject a FeeBumpTransaction", async () => { - const { xdr: innerXdr, serverKeypair, clientKeypair } = buildChallenge(); - const innerTx = new Transaction(innerXdr, networkPassphrase); - const feeBump = SdkTransactionBuilder.buildFeeBumpTransaction( - serverKeypair, - BASE_FEE, - innerTx, - networkPassphrase, - ); - feeBump.sign(serverKeypair); - - const { sep10, accountKp, postStub } = authenticateWithoutKey( - feeBump.toXDR(), - clientKeypair, - ); - await expect(sep10.authenticate({ accountKp })).rejects.toThrow( - ChallengeValidationFailedError, - ); - expect(postStub.notCalled).toBe(true); - }); - - it("should reject non-zero sequence number", async () => { - const { xdr, clientKeypair } = buildChallenge({ sequence: "99" }); - const { sep10, accountKp, postStub } = authenticateWithoutKey( - xdr, - clientKeypair, - ); - await expect(sep10.authenticate({ accountKp })).rejects.toThrow( - ChallengeValidationFailedError, - ); - expect(postStub.notCalled).toBe(true); - }); - - it("should reject a challenge with no operations", async () => { - const serverKeypair = Keypair.random(); - const clientKeypair = Keypair.random(); - const serverAccount = new Account(serverKeypair.publicKey(), "-1"); - const tx = new SdkTransactionBuilder(serverAccount, { - fee: BASE_FEE, - networkPassphrase, - }) - .setTimeout(300) - .build(); - tx.sign(serverKeypair); - - const { sep10, accountKp, postStub } = authenticateWithoutKey( - tx.toXDR(), - clientKeypair, - ); - await expect(sep10.authenticate({ accountKp })).rejects.toThrow( - ChallengeValidationFailedError, - ); - expect(postStub.notCalled).toBe(true); - }); - - it("should reject first operation without source account", async () => { - const { xdr, clientKeypair } = buildChallenge({ - omitFirstOpSource: true, - }); - const { sep10, accountKp, postStub } = authenticateWithoutKey( - xdr, - clientKeypair, - ); - await expect(sep10.authenticate({ accountKp })).rejects.toThrow( - ChallengeValidationFailedError, - ); - expect(postStub.notCalled).toBe(true); - }); - - it("should reject memo with muxed client account", async () => { - const clientKeypair = Keypair.random(); - const baseAccount = new Account(clientKeypair.publicKey(), "0"); - const muxed = new MuxedAccount(baseAccount, "123"); - - const { xdr } = buildChallenge({ - clientKeypair, - clientSource: muxed.accountId(), - memo: Memo.id("456"), - }); - const { sep10, accountKp, postStub } = authenticateWithoutKey( - xdr, - clientKeypair, - ); - await expect(sep10.authenticate({ accountKp })).rejects.toThrow( - ChallengeValidationFailedError, - ); - expect(postStub.notCalled).toBe(true); - }); - - it("should reject non-id memo type", async () => { - const { xdr, clientKeypair } = buildChallenge({ - memo: Memo.text("test"), - }); - const { sep10, accountKp, postStub } = authenticateWithoutKey( - xdr, - clientKeypair, - ); - await expect(sep10.authenticate({ accountKp })).rejects.toThrow( - ChallengeValidationFailedError, - ); - expect(postStub.notCalled).toBe(true); - }); - - it("should reject first operation that is not manageData", async () => { - const { xdr, clientKeypair } = buildChallenge({ - firstOpType: "payment", - }); - const { sep10, accountKp, postStub } = authenticateWithoutKey( - xdr, - clientKeypair, - ); - await expect(sep10.authenticate({ accountKp })).rejects.toThrow( - ChallengeValidationFailedError, - ); - expect(postStub.notCalled).toBe(true); - }); - - it("should reject infinite timebounds (maxTime=0)", async () => { - const { xdr, clientKeypair } = buildChallenge({ - useExplicitTimebounds: true, - minTime: 0, - maxTime: 0, - }); - const { sep10, accountKp, postStub } = authenticateWithoutKey( - xdr, - clientKeypair, - ); - await expect(sep10.authenticate({ accountKp })).rejects.toThrow( - ChallengeValidationFailedError, - ); - expect(postStub.notCalled).toBe(true); - }); - - it("should reject expired timebounds", async () => { - const now = Math.floor(Date.now() / 1000); - const { xdr, clientKeypair } = buildChallenge({ - useExplicitTimebounds: true, - minTime: now - 7200, - maxTime: now - 3600, - }); - const { sep10, accountKp, postStub } = authenticateWithoutKey( - xdr, - clientKeypair, - ); - await expect(sep10.authenticate({ accountKp })).rejects.toThrow( - ChallengeValidationFailedError, - ); - expect(postStub.notCalled).toBe(true); - }); - - it("should reject missing nonce value", async () => { - const { xdr, clientKeypair } = buildChallenge({ omitNonce: true }); - const { sep10, accountKp, postStub } = authenticateWithoutKey( - xdr, - clientKeypair, - ); - await expect(sep10.authenticate({ accountKp })).rejects.toThrow( - ChallengeValidationFailedError, - ); - expect(postStub.notCalled).toBe(true); - }); - - it("should reject wrong nonce length", async () => { - const { xdr, clientKeypair } = buildChallenge({ - nonce: randomBytes(16).toString("base64"), - }); - const { sep10, accountKp, postStub } = authenticateWithoutKey( - xdr, - clientKeypair, - ); - await expect(sep10.authenticate({ accountKp })).rejects.toThrow( - ChallengeValidationFailedError, - ); - expect(postStub.notCalled).toBe(true); - }); - - it("should reject wrong home domain", async () => { - const { xdr, clientKeypair } = buildChallenge({ - challengeHomeDomain: "evil.example.com", - }); - const { sep10, accountKp, postStub } = authenticateWithoutKey( - xdr, - clientKeypair, - ); - await expect(sep10.authenticate({ accountKp })).rejects.toThrow( - ChallengeValidationFailedError, - ); - expect(postStub.notCalled).toBe(true); - }); - - it("should reject subsequent non-manageData operation", async () => { - const serverKeypair = Keypair.random(); - const { xdr, clientKeypair } = buildChallenge({ - serverKeypair, - additionalOps: [ - Operation.payment({ - destination: serverKeypair.publicKey(), - asset: Asset.native(), - amount: "1", - }), - ], - }); - const { sep10, accountKp, postStub } = authenticateWithoutKey( - xdr, - clientKeypair, - ); - await expect(sep10.authenticate({ accountKp })).rejects.toThrow( - ChallengeValidationFailedError, - ); - expect(postStub.notCalled).toBe(true); - }); - - it("should reject null web_auth_domain value", async () => { - const { xdr, clientKeypair } = buildChallenge({ - webAuthDomainValue: null, - }); - const { sep10, accountKp, postStub } = authenticateWithoutKey( - xdr, - clientKeypair, - ); - await expect(sep10.authenticate({ accountKp })).rejects.toThrow( - ChallengeValidationFailedError, - ); - expect(postStub.notCalled).toBe(true); - }); - - it("should reject mismatched web_auth_domain", async () => { - const { xdr, clientKeypair } = buildChallenge({ - webAuthDomainValue: "evil.example.com", - }); - const { sep10, accountKp, postStub } = authenticateWithoutKey( - xdr, - clientKeypair, - ); - await expect(sep10.authenticate({ accountKp })).rejects.toThrow( - ChallengeValidationFailedError, - ); - expect(postStub.notCalled).toBe(true); - }); - - it("should reject a challenge with missing timebounds", async () => { - const { xdr: txXdr, clientKeypair } = buildChallenge(); - - // Strip timebounds by setting preconditions to PRECOND_NONE in the XDR - const envelope = StellarXdr.TransactionEnvelope.fromXDR(txXdr, "base64"); - envelope.v1().tx().cond(StellarXdr.Preconditions.precondNone()); - const noTimeboundsXdr = envelope.toXDR().toString("base64"); - - const { sep10, accountKp, postStub } = authenticateWithoutKey( - noTimeboundsXdr, - clientKeypair, - ); - await expect(sep10.authenticate({ accountKp })).rejects.toThrow( - ChallengeValidationFailedError, - ); - expect(postStub.notCalled).toBe(true); - }); - }); - describe("network passphrase mismatch", () => { it("should reject when server returns a different network passphrase", async () => { const { xdr, serverKeypair, clientKeypair } = buildChallenge(); @@ -983,7 +688,7 @@ describe("Anchor.sep10() signing key handling", () => { sinon.restore(); }); - it("should succeed when TOML has no SIGNING_KEY", async () => { + it("should throw MissingSigningKeyError when TOML has no SIGNING_KEY", async () => { sinon.stub(StellarToml.Resolver, "resolve").resolves({ WEB_AUTH_ENDPOINT: "https://testanchor.stellar.org/auth", DOCUMENTATION: {}, @@ -1001,8 +706,7 @@ describe("Anchor.sep10() signing key handling", () => { language: "en", }); - const sep10 = await anchor.sep10(); - expect(sep10).toBeDefined(); + await expect(anchor.sep10()).rejects.toThrow(MissingSigningKeyError); }); it("should succeed when TOML has SIGNING_KEY", async () => { diff --git a/@stellar/typescript-wallet-sdk/test/integration/recovery.test.ts b/@stellar/typescript-wallet-sdk/test/integration/recovery.test.ts index 94db64f5..f4276341 100644 --- a/@stellar/typescript-wallet-sdk/test/integration/recovery.test.ts +++ b/@stellar/typescript-wallet-sdk/test/integration/recovery.test.ts @@ -22,6 +22,7 @@ describe("Recovery Integration Tests", () => { endpoint: "http://localhost:8000", authEndpoint: "http://localhost:8001", homeDomain: "test-domain", + signingKey: "GA43H67KTOSLFDM5LPUSJGIJSPWV6WVQN6FUYQWZKWJE5EMHXWE5EGK5", }; const server2Key: RecoveryServerKey = "server2"; @@ -29,6 +30,7 @@ describe("Recovery Integration Tests", () => { endpoint: "http://localhost:8002", authEndpoint: "http://localhost:8003", homeDomain: "test-domain", + signingKey: "GAZ2ITFWBXNT4SXSDEPM43IN72FQXOUCVXEXSHYX3VT2WZUI4E6UBSI2", }; const servers: RecoveryServerMap = { From bb1fd4f67839c2a29528afbd7e8b332152c209f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ca=CC=81ssio=20Marcos=20Goulart?= Date: Thu, 26 Feb 2026 13:20:44 -0800 Subject: [PATCH 3/3] Fix anchor platform tests --- .../test/integration/anchorplatform.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/@stellar/typescript-wallet-sdk/test/integration/anchorplatform.test.ts b/@stellar/typescript-wallet-sdk/test/integration/anchorplatform.test.ts index 72a6556a..779a08d3 100644 --- a/@stellar/typescript-wallet-sdk/test/integration/anchorplatform.test.ts +++ b/@stellar/typescript-wallet-sdk/test/integration/anchorplatform.test.ts @@ -6,14 +6,14 @@ let wallet; let stellar; let anchor; let accountKp; -const anchorUrl = "https://anchor-sep-server-dev.stellar.org/"; +const anchorUrl = "anchor-sep-server-dev.stellar.org"; describe("Anchor Platform Integration Tests", () => { beforeAll(async () => { // Setup wallet = Wallet.TestNet(); stellar = wallet.stellar(); - anchor = wallet.anchor({ homeDomain: anchorUrl, allowHttp: true }); + anchor = wallet.anchor({ homeDomain: anchorUrl }); accountKp = stellar.account().createKeypair(); await stellar.fundTestnetAccount(accountKp.publicKey); }, 30000);