From ce610f32835b11c951296c79ec40db0a944f2015 Mon Sep 17 00:00:00 2001 From: hayes-mysten <135670682+hayes-mysten@users.noreply.github.com> Date: Tue, 21 Oct 2025 10:52:24 -0700 Subject: [PATCH 01/13] Remove default client used for verifying zklogin signatures (#625) Co-authored-by: Michael Hayes --- .changeset/fruity-cats-grab.md | 5 +++ .../content/typescript/migrations/sui-2.0.mdx | 28 ++++++++++++++++ packages/typescript/src/multisig/publickey.ts | 6 ++-- packages/typescript/src/verify/verify.ts | 12 +++---- packages/typescript/src/zklogin/index.ts | 6 +--- packages/typescript/src/zklogin/publickey.ts | 33 ++++++++----------- 6 files changed, 57 insertions(+), 33 deletions(-) create mode 100644 .changeset/fruity-cats-grab.md create mode 100644 packages/docs/content/typescript/migrations/sui-2.0.mdx diff --git a/.changeset/fruity-cats-grab.md b/.changeset/fruity-cats-grab.md new file mode 100644 index 000000000..db0677ccb --- /dev/null +++ b/.changeset/fruity-cats-grab.md @@ -0,0 +1,5 @@ +--- +'@mysten/sui': major +--- + +Remove default client used for verifying zklogin signatures diff --git a/packages/docs/content/typescript/migrations/sui-2.0.mdx b/packages/docs/content/typescript/migrations/sui-2.0.mdx new file mode 100644 index 000000000..762e2bd31 --- /dev/null +++ b/packages/docs/content/typescript/migrations/sui-2.0.mdx @@ -0,0 +1,28 @@ +--- +title: Migrate to version 2.0 +--- + +# Migrating to @mysten/sui@2.0 + +## ZkLogin Signature verification + +In previous versions of the SDK, methods that verified ZkLogin signatures created a GraphQL client +that used the GraphQL alpha to verify mainnet ZkLogin signatures. This default is being removed, as +it was dependent on the GraphQL alpha endpoint, which is no longer available, and did not work for +non-mainnet signatures. + +You will now need to pass a client (GraphQL, GRPC, or JSON RPC) to any methods that verify ZkLogin +signatures. + +```ts +const client: SuiGraphQLClient | SuiGrpcClient | SuiJsonRpcClient; + +verifyPersonalMessageSignature(message, signature, { client }); +verifyTransactionSignature(txBytes, signature, { client }); +parseSignature(signatureBytes, { client }); + +// For ZkLoginPublicIdentifier, the client is passed in when it it created +zkLoginPublicIdentifier = toZkLoginPublicIdentifier(seed, iss, { client, legacy: true }); +zkLoginPublicIdentifier.verifyPersonalMessage(message, signature); +zkLoginPublicIdentifier.verifyTransaction(transaction, signature); +``` diff --git a/packages/typescript/src/multisig/publickey.ts b/packages/typescript/src/multisig/publickey.ts index 1f66cab95..2f1ea76d9 100644 --- a/packages/typescript/src/multisig/publickey.ts +++ b/packages/typescript/src/multisig/publickey.ts @@ -17,9 +17,9 @@ import { parseSerializedSignature } from '../cryptography/signature.js'; import { normalizeSuiAddress } from '../utils/sui-types.js'; // eslint-disable-next-line import/no-cycle import { publicKeyFromRawBytes } from '../verify/index.js'; -import type { ZkLoginCompatibleClient } from '../zklogin/publickey.js'; import { toZkLoginPublicIdentifier } from '../zklogin/publickey.js'; import { MultiSigSigner } from './signer.js'; +import type { ClientWithCoreApi } from '../experimental/core.js'; type CompressedSignature = | { ED25519: Uint8Array } @@ -78,7 +78,7 @@ export class MultiSigPublicKey extends PublicKey { * MultiSig public key as buffer or base-64 encoded string */ value: string | Uint8Array | MultiSigPublicKeyStruct, - options: { client?: ZkLoginCompatibleClient } = {}, + options: { client?: ClientWithCoreApi } = {}, ) { super(); @@ -317,7 +317,7 @@ export class MultiSigPublicKey extends PublicKey { */ export function parsePartialSignatures( multisig: MultiSigStruct, - options: { client?: ZkLoginCompatibleClient } = {}, + options: { client?: ClientWithCoreApi } = {}, ): ParsedPartialMultiSigSignature[] { const res: ParsedPartialMultiSigSignature[] = new Array(multisig.sigs.length); for (let i = 0; i < multisig.sigs.length; i++) { diff --git a/packages/typescript/src/verify/verify.ts b/packages/typescript/src/verify/verify.ts index a8a274d11..9c799ef3e 100644 --- a/packages/typescript/src/verify/verify.ts +++ b/packages/typescript/src/verify/verify.ts @@ -11,8 +11,8 @@ import { Secp256k1PublicKey } from '../keypairs/secp256k1/publickey.js'; import { Secp256r1PublicKey } from '../keypairs/secp256r1/publickey.js'; // eslint-disable-next-line import/no-cycle import { MultiSigPublicKey } from '../multisig/publickey.js'; -import type { ZkLoginCompatibleClient } from '../zklogin/publickey.js'; import { ZkLoginPublicIdentifier } from '../zklogin/publickey.js'; +import type { ClientWithCoreApi } from '../experimental/core.js'; export async function verifySignature( bytes: Uint8Array, @@ -37,7 +37,7 @@ export async function verifySignature( export async function verifyPersonalMessageSignature( message: Uint8Array, signature: string, - options: { client?: ZkLoginCompatibleClient; address?: string } = {}, + options: { client?: ClientWithCoreApi; address?: string } = {}, ): Promise { const parsedSignature = parseSignature(signature, options); @@ -60,7 +60,7 @@ export async function verifyPersonalMessageSignature( export async function verifyTransactionSignature( transaction: Uint8Array, signature: string, - options: { client?: ZkLoginCompatibleClient; address?: string } = {}, + options: { client?: ClientWithCoreApi; address?: string } = {}, ): Promise { const parsedSignature = parseSignature(signature, options); @@ -80,7 +80,7 @@ export async function verifyTransactionSignature( return parsedSignature.publicKey; } -function parseSignature(signature: string, options: { client?: ZkLoginCompatibleClient } = {}) { +function parseSignature(signature: string, options: { client?: ClientWithCoreApi } = {}) { const parsedSignature = parseSerializedSignature(signature); if (parsedSignature.signatureScheme === 'MultiSig') { @@ -104,7 +104,7 @@ function parseSignature(signature: string, options: { client?: ZkLoginCompatible export function publicKeyFromRawBytes( signatureScheme: SignatureScheme, bytes: Uint8Array, - options: { client?: ZkLoginCompatibleClient; address?: string } = {}, + options: { client?: ClientWithCoreApi; address?: string } = {}, ): PublicKey { let publicKey: PublicKey; switch (signatureScheme) { @@ -139,7 +139,7 @@ export function publicKeyFromRawBytes( export function publicKeyFromSuiBytes( publicKey: string | Uint8Array, - options: { client?: ZkLoginCompatibleClient; address?: string } = {}, + options: { client?: ClientWithCoreApi; address?: string } = {}, ) { const bytes = typeof publicKey === 'string' ? fromBase64(publicKey) : publicKey; diff --git a/packages/typescript/src/zklogin/index.ts b/packages/typescript/src/zklogin/index.ts index 9c24b83a0..5a132782b 100644 --- a/packages/typescript/src/zklogin/index.ts +++ b/packages/typescript/src/zklogin/index.ts @@ -11,11 +11,7 @@ export { } from './utils.js'; export { computeZkLoginAddressFromSeed, computeZkLoginAddress, jwtToAddress } from './address.js'; export type { ComputeZkLoginAddressOptions } from './address.js'; -export { - toZkLoginPublicIdentifier, - ZkLoginPublicIdentifier, - type ZkLoginCompatibleClient, -} from './publickey.js'; +export { toZkLoginPublicIdentifier, ZkLoginPublicIdentifier } from './publickey.js'; export type { ZkLoginSignatureInputs } from './bcs.js'; export { poseidonHash } from './poseidon.js'; export { generateNonce, generateRandomness } from './nonce.js'; diff --git a/packages/typescript/src/zklogin/publickey.ts b/packages/typescript/src/zklogin/publickey.ts index 43d92a08f..6b53f1abc 100644 --- a/packages/typescript/src/zklogin/publickey.ts +++ b/packages/typescript/src/zklogin/publickey.ts @@ -8,34 +8,26 @@ import { bytesToHex } from '@noble/hashes/utils'; import { PublicKey } from '../cryptography/publickey.js'; import type { PublicKeyInitData } from '../cryptography/publickey.js'; import { SIGNATURE_SCHEME_TO_FLAG } from '../cryptography/signature-scheme.js'; -import { SuiGraphQLClient } from '../graphql/client.js'; import { normalizeSuiAddress, SUI_ADDRESS_LENGTH } from '../utils/sui-types.js'; import type { ZkLoginSignatureInputs } from './bcs.js'; import { extractClaimValue } from './jwt-utils.js'; import { parseZkLoginSignature } from './signature.js'; import { normalizeZkLoginIssuer, toBigEndianBytes, toPaddedBigEndianBytes } from './utils.js'; -import type { ClientWithExtensions, Experimental_SuiClientTypes } from '../experimental/types.js'; - -export interface ZkLoginCompatibleClient - extends ClientWithExtensions<{ - core: { - verifyZkLoginSignature: Experimental_SuiClientTypes.TransportMethods['verifyZkLoginSignature']; - }; - }> {} +import type { ClientWithCoreApi } from '../experimental/core.js'; /** * A zkLogin public identifier */ export class ZkLoginPublicIdentifier extends PublicKey { #data: Uint8Array; - #client?: ZkLoginCompatibleClient; + #client?: ClientWithCoreApi; #legacyAddress: boolean; /** * Create a new ZkLoginPublicIdentifier object * @param value zkLogin public identifier as buffer or base-64 encoded string */ - constructor(value: PublicKeyInitData, { client }: { client?: ZkLoginCompatibleClient } = {}) { + constructor(value: PublicKeyInitData, { client }: { client?: ClientWithCoreApi } = {}) { super(); this.#client = client; @@ -60,7 +52,7 @@ export class ZkLoginPublicIdentifier extends PublicKey { client, address, legacyAddress, - }: { client?: ZkLoginCompatibleClient; address?: string; legacyAddress?: boolean } = {}, + }: { client?: ClientWithCoreApi; address?: string; legacyAddress?: boolean } = {}, ) { let publicKey: ZkLoginPublicIdentifier; @@ -207,7 +199,7 @@ export class ZkLoginPublicIdentifier extends PublicKey { export function toZkLoginPublicIdentifier( addressSeed: bigint, iss: string, - options?: { client?: ZkLoginCompatibleClient; legacyAddress?: boolean }, + options?: { client?: ClientWithCoreApi; legacyAddress?: boolean }, ): ZkLoginPublicIdentifier { // Consists of iss_bytes_len || iss_bytes || padded_32_byte_address_seed. const addressSeedBytesBigEndian = options?.legacyAddress @@ -239,16 +231,19 @@ async function graphqlVerifyZkLoginSignature({ bytes, signature, intentScope, - client = new SuiGraphQLClient({ - url: 'https://graphql.mainnet.sui.io/graphql', - }), + client, }: { address: string; bytes: string; signature: string; intentScope: 'PersonalMessage' | 'TransactionData'; - client?: ZkLoginCompatibleClient; + client?: ClientWithCoreApi; }) { + if (!client) { + throw new Error( + 'A Sui Client (GRPC, GraphQL, or JSON RPC) is required to verify zkLogin signatures', + ); + } const resp = await client.core.verifyZkLoginSignature({ bytes, signature, @@ -270,7 +265,7 @@ export function parseSerializedZkLoginSignature(signature: Uint8Array | string) const { inputs, maxEpoch, userSignature } = parseZkLoginSignature(signatureBytes); const { issBase64Details, addressSeed } = inputs; const iss = extractClaimValue(issBase64Details, 'iss'); - const publicIdentifer = toZkLoginPublicIdentifier(BigInt(addressSeed), iss); + const publicIdentifier = toZkLoginPublicIdentifier(BigInt(addressSeed), iss); return { serializedSignature: toBase64(bytes), signatureScheme: 'ZkLogin' as const, @@ -282,6 +277,6 @@ export function parseSerializedZkLoginSignature(signature: Uint8Array | string) addressSeed: BigInt(addressSeed), }, signature: bytes, - publicKey: publicIdentifer.toRawBytes(), + publicKey: publicIdentifier.toRawBytes(), }; } From dd0225305bb67f658a88f90804ad6adcab7beec3 Mon Sep 17 00:00:00 2001 From: hayes-mysten <135670682+hayes-mysten@users.noreply.github.com> Date: Tue, 21 Oct 2025 11:44:01 -0700 Subject: [PATCH 02/13] require legacy address arg (#627) make legacyAddress parameter required Co-authored-by: Michael Hayes --- .changeset/little-chefs-shake.md | 5 ++++ .../content/typescript/migrations/sui-2.0.mdx | 29 ++++++++++++++++++- packages/typescript/src/multisig/publickey.ts | 7 ++--- packages/typescript/src/zklogin/address.ts | 21 ++++++++++---- packages/typescript/src/zklogin/publickey.ts | 12 ++++---- packages/typescript/test/e2e/multisig.test.ts | 1 + .../test/unit/cryptography/multisig.test.ts | 2 ++ .../test/unit/zklogin/address.test.ts | 10 ++++--- 8 files changed, 68 insertions(+), 19 deletions(-) create mode 100644 .changeset/little-chefs-shake.md diff --git a/.changeset/little-chefs-shake.md b/.changeset/little-chefs-shake.md new file mode 100644 index 000000000..fb15e6381 --- /dev/null +++ b/.changeset/little-chefs-shake.md @@ -0,0 +1,5 @@ +--- +'@mysten/sui': major +--- + +Make legacyAddress parameter in all methods to reduce confusion and inconsistency around default values diff --git a/packages/docs/content/typescript/migrations/sui-2.0.mdx b/packages/docs/content/typescript/migrations/sui-2.0.mdx index 762e2bd31..553b8be57 100644 --- a/packages/docs/content/typescript/migrations/sui-2.0.mdx +++ b/packages/docs/content/typescript/migrations/sui-2.0.mdx @@ -4,6 +4,33 @@ title: Migrate to version 2.0 # Migrating to @mysten/sui@2.0 +## ZkLogin `legacyAddress` parameter is now required + +The `legacyAddress` parameter is now **required** for all zkLogin address computation functions. In +v1.x, this parameter had default values that varied by function, which could lead to confusion. You +must now explicitly specify whether you want to use legacy address encoding. + +Update all calls to zkLogin functions to include the `legacyAddress` parameter. **To preserve +existing behavior**, use the following migrations: + +```diff +// computeZkLoginAddressFromSeed (previous default: true) +- computeZkLoginAddressFromSeed(seed, iss) ++ computeZkLoginAddressFromSeed(seed, iss, true) + +// jwtToAddress (previous default: false) +- jwtToAddress(jwt, userSalt) ++ jwtToAddress(jwt, userSalt, false) + +// computeZkLoginAddress (previous default: false) +- computeZkLoginAddress({ claimName, claimValue, iss, aud, userSalt }) ++ computeZkLoginAddress({ claimName, claimValue, iss, aud, userSalt, legacyAddress: false }) + +// toZkLoginPublicIdentifier (no previous default, was optional) +- toZkLoginPublicIdentifier(addressSeed, iss) ++ toZkLoginPublicIdentifier(addressSeed, iss, { legacyAddress: false }) +``` + ## ZkLogin Signature verification In previous versions of the SDK, methods that verified ZkLogin signatures created a GraphQL client @@ -22,7 +49,7 @@ verifyTransactionSignature(txBytes, signature, { client }); parseSignature(signatureBytes, { client }); // For ZkLoginPublicIdentifier, the client is passed in when it it created -zkLoginPublicIdentifier = toZkLoginPublicIdentifier(seed, iss, { client, legacy: true }); +zkLoginPublicIdentifier = toZkLoginPublicIdentifier(seed, iss, { client, legacyAddress: false }); zkLoginPublicIdentifier.verifyPersonalMessage(message, signature); zkLoginPublicIdentifier.verifyTransaction(transaction, signature); ``` diff --git a/packages/typescript/src/multisig/publickey.ts b/packages/typescript/src/multisig/publickey.ts index 2f1ea76d9..8ec952ceb 100644 --- a/packages/typescript/src/multisig/publickey.ts +++ b/packages/typescript/src/multisig/publickey.ts @@ -268,10 +268,9 @@ export class MultiSigPublicKey extends PublicKey { let publicKey; if (parsed.signatureScheme === 'ZkLogin') { - publicKey = toZkLoginPublicIdentifier( - parsed.zkLogin?.addressSeed, - parsed.zkLogin?.iss, - ).toRawBytes(); + publicKey = toZkLoginPublicIdentifier(parsed.zkLogin?.addressSeed, parsed.zkLogin?.iss, { + legacyAddress: false, + }).toRawBytes(); } else { publicKey = parsed.publicKey; } diff --git a/packages/typescript/src/zklogin/address.ts b/packages/typescript/src/zklogin/address.ts index e13e41b88..6302b442c 100644 --- a/packages/typescript/src/zklogin/address.ts +++ b/packages/typescript/src/zklogin/address.ts @@ -17,9 +17,12 @@ import { export function computeZkLoginAddressFromSeed( addressSeed: bigint, iss: string, - /** TODO: This default should be changed in the next major release */ - legacyAddress = true, + legacyAddress: boolean, ) { + // Explicitly check for people not using typescript and ignoring the major version migration guide + if (legacyAddress === undefined) { + throw new Error('legacyAddress parameter must be specified'); + } const addressSeedBytesBigEndian = legacyAddress ? toBigEndianBytes(addressSeed, 32) : toPaddedBigEndianBytes(addressSeed, 32); @@ -61,7 +64,11 @@ export function lengthChecks(jwt: string) { } } -export function jwtToAddress(jwt: string, userSalt: string | bigint, legacyAddress = false) { +export function jwtToAddress(jwt: string, userSalt: string | bigint, legacyAddress: boolean) { + // Explicitly check for people not using typescript and ignoring the major version migration guide + if (legacyAddress === undefined) { + throw new Error('legacyAddress parameter must be specified'); + } lengthChecks(jwt); const decodedJWT = decodeJwt(jwt); @@ -82,7 +89,7 @@ export interface ComputeZkLoginAddressOptions { userSalt: string | bigint; iss: string; aud: string; - legacyAddress?: boolean; + legacyAddress: boolean; } export function computeZkLoginAddress({ @@ -91,8 +98,12 @@ export function computeZkLoginAddress({ iss, aud, userSalt, - legacyAddress = false, + legacyAddress, }: ComputeZkLoginAddressOptions) { + // Explicitly check for people not using typescript and ignoring the major version migration guide + if (legacyAddress === undefined) { + throw new Error('legacyAddress parameter must be specified'); + } return computeZkLoginAddressFromSeed( genAddressSeed(userSalt, claimName, claimValue, aud), iss, diff --git a/packages/typescript/src/zklogin/publickey.ts b/packages/typescript/src/zklogin/publickey.ts index 6b53f1abc..951e07a5b 100644 --- a/packages/typescript/src/zklogin/publickey.ts +++ b/packages/typescript/src/zklogin/publickey.ts @@ -42,7 +42,7 @@ export class ZkLoginPublicIdentifier extends PublicKey { this.#legacyAddress = this.#data.length !== this.#data[0] + 1 + 32; if (this.#legacyAddress) { - this.#data = normalizeZkLoginPublicKeyBytes(this.#data); + this.#data = normalizeZkLoginPublicKeyBytes(this.#data, false); } } @@ -199,10 +199,10 @@ export class ZkLoginPublicIdentifier extends PublicKey { export function toZkLoginPublicIdentifier( addressSeed: bigint, iss: string, - options?: { client?: ClientWithCoreApi; legacyAddress?: boolean }, + options: { client?: ClientWithCoreApi; legacyAddress: boolean }, ): ZkLoginPublicIdentifier { // Consists of iss_bytes_len || iss_bytes || padded_32_byte_address_seed. - const addressSeedBytesBigEndian = options?.legacyAddress + const addressSeedBytesBigEndian = options.legacyAddress ? toBigEndianBytes(addressSeed, 32) : toPaddedBigEndianBytes(addressSeed, 32); @@ -214,7 +214,7 @@ export function toZkLoginPublicIdentifier( return new ZkLoginPublicIdentifier(tmp, options); } -function normalizeZkLoginPublicKeyBytes(bytes: Uint8Array, legacyAddress = false) { +function normalizeZkLoginPublicKeyBytes(bytes: Uint8Array, legacyAddress: boolean) { const issByteLength = bytes[0] + 1; const addressSeed = BigInt(`0x${toHex(bytes.slice(issByteLength))}`); const seedBytes = legacyAddress @@ -265,7 +265,9 @@ export function parseSerializedZkLoginSignature(signature: Uint8Array | string) const { inputs, maxEpoch, userSignature } = parseZkLoginSignature(signatureBytes); const { issBase64Details, addressSeed } = inputs; const iss = extractClaimValue(issBase64Details, 'iss'); - const publicIdentifier = toZkLoginPublicIdentifier(BigInt(addressSeed), iss); + const publicIdentifier = toZkLoginPublicIdentifier(BigInt(addressSeed), iss, { + legacyAddress: false, + }); return { serializedSignature: toBase64(bytes), signatureScheme: 'ZkLogin' as const, diff --git a/packages/typescript/test/e2e/multisig.test.ts b/packages/typescript/test/e2e/multisig.test.ts index 788a67bb1..cd70be2a9 100644 --- a/packages/typescript/test/e2e/multisig.test.ts +++ b/packages/typescript/test/e2e/multisig.test.ts @@ -21,6 +21,7 @@ describe('MultiSig with zklogin signature', () => { const pkZklogin = toZkLoginPublicIdentifier( BigInt('2455937816256448139232531453880118833510874847675649348355284726183344259587'), 'https://id.twitch.tv/oauth2', + { legacyAddress: false }, ); // set up ephemeral keypair, consistent with default zklogin proof. const parsed = decodeSuiPrivateKey( diff --git a/packages/typescript/test/unit/cryptography/multisig.test.ts b/packages/typescript/test/unit/cryptography/multisig.test.ts index b8d0b2448..c70dac8f6 100644 --- a/packages/typescript/test/unit/cryptography/multisig.test.ts +++ b/packages/typescript/test/unit/cryptography/multisig.test.ts @@ -396,10 +396,12 @@ describe('Multisig address creation:', () => { pk4 = toZkLoginPublicIdentifier( BigInt('20794788559620669596206457022966176986688727876128223628113916380927502737911'), 'https://id.twitch.tv/oauth2', + { legacyAddress: false }, ); pk5 = toZkLoginPublicIdentifier( BigInt('380704556853533152350240698167704405529973457670972223618755249929828551006'), 'https://id.twitch.tv/oauth2', + { legacyAddress: false }, ); const secret_key_ed25519 = new Uint8Array([ diff --git a/packages/typescript/test/unit/zklogin/address.test.ts b/packages/typescript/test/unit/zklogin/address.test.ts index a7cb56163..8c3eed246 100644 --- a/packages/typescript/test/unit/zklogin/address.test.ts +++ b/packages/typescript/test/unit/zklogin/address.test.ts @@ -18,6 +18,7 @@ describe('zkLogin address', () => { computeZkLoginAddressFromSeed( BigInt('13322897930163218532266430409510394316985274769125667290600321564259466511711'), 'https://accounts.google.com', + true, ), ).toBe('0xf7badc2b245c7f74d7509a4aa357ecf80a29e7713fb4c44b0e7541ec43885ee1'); }); @@ -27,6 +28,7 @@ describe('zkLogin address', () => { computeZkLoginAddressFromSeed( BigInt('380704556853533152350240698167704405529973457670972223618755249929828551006'), 'https://accounts.google.com', + true, ), ).toBe('0xbd8b8ed42d90aebc71518385d8a899af14cef8b5a171c380434dd6f5bbfe7bf3'); }); @@ -36,7 +38,7 @@ describe('zkLogin address', () => { '380704556853533152350240698167704405529973457670972223618755249929828551006', ); const iss = 'https://accounts.google.com'; - expect(computeZkLoginAddressFromSeed(seed, iss)).toEqual( + expect(computeZkLoginAddressFromSeed(seed, iss, true)).toEqual( toZkLoginPublicIdentifier(seed, iss, { legacyAddress: true }).toSuiAddress(), ); }); @@ -47,7 +49,7 @@ describe('zkLogin address', () => { ); const iss = 'https://accounts.google.com'; expect(computeZkLoginAddressFromSeed(seed, iss, false)).toEqual( - toZkLoginPublicIdentifier(seed, iss).toSuiAddress(), + toZkLoginPublicIdentifier(seed, iss, { legacyAddress: false }).toSuiAddress(), ); }); @@ -55,7 +57,7 @@ describe('zkLogin address', () => { const jwt = 'eyJraWQiOiJzdWkta2V5LWlkIiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiI4YzJkN2Q2Ni04N2FmLTQxZmEtYjZmYy02M2U4YmI3MWZhYjQiLCJhdWQiOiJ0ZXN0IiwibmJmIjoxNjk3NDY1NDQ1LCJpc3MiOiJodHRwczovL29hdXRoLnN1aS5pbyIsImV4cCI6MTY5NzU1MTg0NSwibm9uY2UiOiJoVFBwZ0Y3WEFLYlczN3JFVVM2cEVWWnFtb0kifQ.'; const userSalt = '248191903847969014646285995941615069143'; - const address = jwtToAddress(jwt, userSalt); + const address = jwtToAddress(jwt, userSalt, false); expect(address).toBe('0x22cebcf68a9d75d508d50d553dd6bae378ef51177a3a6325b749e57e3ba237d6'); }); @@ -83,7 +85,7 @@ describe('zkLogin address', () => { const jwt2 = 'eyJhbGciOiJSUzI1NiIsImtpZCI6InN1aS1rZXktaWQiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJhY2NvdW50cy5nb29nbGUuY29tIiwic3ViIjoiMTIzNDU2Nzg5MCIsImF1ZCI6IjEyMzQ1Njc4OTAuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJleHAiOjE2OTc1NTE4NDUsImlhdCI6MTY5NzQ2NTQ0NX0.'; - expect(jwtToAddress(jwt1, '0')).toBe(jwtToAddress(jwt2, '0')); + expect(jwtToAddress(jwt1, '0', false)).toBe(jwtToAddress(jwt2, '0', false)); }); test('lengthChecks: if header is too long, should throw an error', () => { From 6e20f9a02f5bc2b83fe37af7d597e724c5ec5432 Mon Sep 17 00:00:00 2001 From: hayes-mysten <135670682+hayes-mysten@users.noreply.github.com> Date: Tue, 21 Oct 2025 15:55:19 -0700 Subject: [PATCH 03/13] make network required (#628) Co-authored-by: Michael Hayes --- .changeset/fair-laws-jog.md | 5 +++++ .changeset/honest-cows-shave.md | 5 +++++ .../test/components/SuiClientProvider.test.tsx | 8 +++++++- .../hooks/useSignAndExecuteTransaction.test.tsx | 6 +++--- .../dapp-kit/test/hooks/useSuiClient.test.tsx | 2 +- .../hooks/useSuiClientInfiniteQuery.test.tsx | 2 +- .../test/hooks/useSuiClientMutation.test.tsx | 2 +- .../test/hooks/useSuiClientQueries.test.tsx | 2 +- .../test/hooks/useSuiClientQuery.test.tsx | 2 +- packages/dapp-kit/test/test-utils.tsx | 2 +- packages/deepbook/src/client.ts | 5 ++++- .../content/kiosk/kiosk-client/introduction.mdx | 2 +- .../typescript/cryptography/keypairs.mdx | 2 +- packages/docs/content/typescript/executors.mdx | 4 ++-- packages/docs/content/typescript/hello-sui.mdx | 2 +- .../content/typescript/migrations/sui-2.0.mdx | 16 ++++++++++++++++ packages/docs/content/typescript/sui-client.mdx | 2 +- packages/docs/examples/wallet-components.tsx | 2 +- packages/docs/examples/wallet-hooks.tsx | 2 +- .../demo-dapp/src/networkConfig.ts | 3 +++ packages/seal/test/unit/integration.test.ts | 2 +- packages/seal/test/unit/key-server.test.ts | 2 +- packages/seal/test/unit/session-key.test.ts | 2 +- packages/signers/README.md | 2 +- packages/suins/test/pre-built.ts | 2 +- packages/typescript/README.md | 4 ++-- packages/typescript/src/graphql/client.ts | 4 ++-- packages/typescript/src/jsonRpc/client.ts | 4 ++-- packages/typescript/test/e2e/graphql.test.ts | 1 + .../test/e2e/named-packages-plugin.test.ts | 5 ++++- packages/typescript/test/e2e/utils/setup.ts | 2 ++ .../test/e2e/verify-signatures.test.ts | 2 +- .../test/e2e/zklogin-signature.test.ts | 2 ++ .../test/auto-approvals/manager.test.ts | 2 +- .../demo-dapp/src/networkConfig.ts | 3 +++ packages/walrus/src/client.ts | 13 +++---------- packages/walrus/src/types.ts | 17 +++-------------- packages/zksend/src/index.test.ts | 1 + packages/zksend/src/links/builder.ts | 4 ++-- packages/zksend/src/links/claim.ts | 2 +- .../zksend/src/links/get-sent-transactions.ts | 2 +- packages/zksend/src/links/list-created-links.ts | 1 + 42 files changed, 94 insertions(+), 61 deletions(-) create mode 100644 .changeset/fair-laws-jog.md create mode 100644 .changeset/honest-cows-shave.md diff --git a/.changeset/fair-laws-jog.md b/.changeset/fair-laws-jog.md new file mode 100644 index 000000000..78536de5a --- /dev/null +++ b/.changeset/fair-laws-jog.md @@ -0,0 +1,5 @@ +--- +'@mysten/walrus': minor +--- + +WalrusClient can no longer be created with only an rpc url, pass in a Client instead diff --git a/.changeset/honest-cows-shave.md b/.changeset/honest-cows-shave.md new file mode 100644 index 000000000..d430645a9 --- /dev/null +++ b/.changeset/honest-cows-shave.md @@ -0,0 +1,5 @@ +--- +'@mysten/sui': major +--- + +`network` is now a required option on SuiGraphQLClient and SuiJsonRpcClient diff --git a/packages/dapp-kit/test/components/SuiClientProvider.test.tsx b/packages/dapp-kit/test/components/SuiClientProvider.test.tsx index 1763c8fc3..3745341ef 100644 --- a/packages/dapp-kit/test/components/SuiClientProvider.test.tsx +++ b/packages/dapp-kit/test/components/SuiClientProvider.test.tsx @@ -35,7 +35,7 @@ describe('SuiClientProvider', () => { }); it('can accept pre-configured SuiClients', () => { - const suiClient = new SuiClient({ url: 'http://localhost:8080' }); + const suiClient = new SuiClient({ url: 'http://localhost:8080', network: 'localnet' }); const ChildComponent = () => { const client = useSuiClient(); expect(client).toBeInstanceOf(SuiClient); @@ -74,10 +74,12 @@ describe('SuiClientProvider', () => { networks={{ a: { url: 'http://localhost:8080', + network: 'localnet', custom: setSelectedNetwork, }, b: { url: 'http://localhost:8080', + network: 'localnet', custom: setSelectedNetwork, }, }} @@ -127,10 +129,12 @@ describe('SuiClientProvider', () => { networks={{ a: { url: 'http://localhost:8080', + network: 'localnet', custom: setSelectedNetwork, }, b: { url: 'http://localhost:8080', + network: 'localnet', custom: setSelectedNetwork, }, }} @@ -180,10 +184,12 @@ describe('SuiClientProvider', () => { networks={{ a: { url: 'http://localhost:8080', + network: 'localnet', custom: setSelectedNetwork, }, b: { url: 'http://localhost:8080', + network: 'localnet', custom: setSelectedNetwork, }, }} diff --git a/packages/dapp-kit/test/hooks/useSignAndExecuteTransaction.test.tsx b/packages/dapp-kit/test/hooks/useSignAndExecuteTransaction.test.tsx index fcd6b7a2c..7e2df1d4e 100644 --- a/packages/dapp-kit/test/hooks/useSignAndExecuteTransaction.test.tsx +++ b/packages/dapp-kit/test/hooks/useSignAndExecuteTransaction.test.tsx @@ -62,7 +62,7 @@ describe('useSignAndExecuteTransaction', () => { features: suiFeatures, }); - const suiClient = new SuiClient({ url: getFullnodeUrl('localnet') }); + const suiClient = new SuiClient({ url: getFullnodeUrl('localnet'), network: 'localnet' }); const mockSignTransactionFeature = mockWallet.features['sui:signTransaction']; const signTransaction = mockSignTransactionFeature!.signTransaction as Mock; @@ -143,7 +143,7 @@ describe('useSignAndExecuteTransaction', () => { const reportEffects = reportEffectsFeature!.reportTransactionEffects as Mock; reportEffects.mockImplementation(async () => {}); - const suiClient = new SuiClient({ url: getFullnodeUrl('localnet') }); + const suiClient = new SuiClient({ url: getFullnodeUrl('localnet'), network: 'localnet' }); const executeTransaction = vi.spyOn(suiClient, 'executeTransactionBlock'); executeTransaction.mockResolvedValueOnce({ digest: '123', @@ -188,7 +188,7 @@ describe('useSignAndExecuteTransaction', () => { features: suiFeatures, }); - const suiClient = new SuiClient({ url: getFullnodeUrl('localnet') }); + const suiClient = new SuiClient({ url: getFullnodeUrl('localnet'), network: 'localnet' }); const mockSignMessageFeature = mockWallet.features['sui:signTransaction']; const signTransaction = mockSignMessageFeature!.signTransaction as Mock; diff --git a/packages/dapp-kit/test/hooks/useSuiClient.test.tsx b/packages/dapp-kit/test/hooks/useSuiClient.test.tsx index 64c39d616..3ecafde54 100644 --- a/packages/dapp-kit/test/hooks/useSuiClient.test.tsx +++ b/packages/dapp-kit/test/hooks/useSuiClient.test.tsx @@ -14,7 +14,7 @@ describe('useSuiClient', () => { }); test('returns a SuiClient', () => { - const suiClient = new SuiClient({ url: getFullnodeUrl('localnet') }); + const suiClient = new SuiClient({ url: getFullnodeUrl('localnet'), network: 'localnet' }); const wrapper = createSuiClientContextWrapper(suiClient); const { result } = renderHook(() => useSuiClient(), { wrapper }); diff --git a/packages/dapp-kit/test/hooks/useSuiClientInfiniteQuery.test.tsx b/packages/dapp-kit/test/hooks/useSuiClientInfiniteQuery.test.tsx index 687d13424..4652175c4 100644 --- a/packages/dapp-kit/test/hooks/useSuiClientInfiniteQuery.test.tsx +++ b/packages/dapp-kit/test/hooks/useSuiClientInfiniteQuery.test.tsx @@ -8,7 +8,7 @@ import { createWalletProviderContextWrapper } from '../test-utils.js'; describe('useSuiClientInfiniteQuery', () => { it('should fetch data', async () => { - const suiClient = new SuiClient({ url: getFullnodeUrl('mainnet') }); + const suiClient = new SuiClient({ url: getFullnodeUrl('mainnet'), network: 'mainnet' }); const wrapper = createWalletProviderContextWrapper({}, suiClient); const queryTransactionBlocks = vi.spyOn(suiClient, 'queryTransactionBlocks'); diff --git a/packages/dapp-kit/test/hooks/useSuiClientMutation.test.tsx b/packages/dapp-kit/test/hooks/useSuiClientMutation.test.tsx index e9293af14..580601862 100644 --- a/packages/dapp-kit/test/hooks/useSuiClientMutation.test.tsx +++ b/packages/dapp-kit/test/hooks/useSuiClientMutation.test.tsx @@ -8,7 +8,7 @@ import { createWalletProviderContextWrapper } from '../test-utils.js'; describe('useSuiClientMutation', () => { it('should fetch data', async () => { - const suiClient = new SuiClient({ url: getFullnodeUrl('mainnet') }); + const suiClient = new SuiClient({ url: getFullnodeUrl('mainnet'), network: 'mainnet' }); const wrapper = createWalletProviderContextWrapper({}, suiClient); const queryTransactionBlocks = vi.spyOn(suiClient, 'queryTransactionBlocks'); diff --git a/packages/dapp-kit/test/hooks/useSuiClientQueries.test.tsx b/packages/dapp-kit/test/hooks/useSuiClientQueries.test.tsx index 2dbfacc31..ee07c8c99 100644 --- a/packages/dapp-kit/test/hooks/useSuiClientQueries.test.tsx +++ b/packages/dapp-kit/test/hooks/useSuiClientQueries.test.tsx @@ -21,7 +21,7 @@ const MOCK_QUERY_TRANSACTION_BLOCK_RESULT_DATA = { }; describe('useSuiClientQueries', () => { - const suiClient = new SuiClient({ url: getFullnodeUrl('mainnet') }); + const suiClient = new SuiClient({ url: getFullnodeUrl('mainnet'), network: 'mainnet' }); const wrapper = createWalletProviderContextWrapper({}, suiClient); test('should fetch data', async () => { const getAllBalances = vi.spyOn(suiClient, 'getAllBalances'); diff --git a/packages/dapp-kit/test/hooks/useSuiClientQuery.test.tsx b/packages/dapp-kit/test/hooks/useSuiClientQuery.test.tsx index 457d41920..a8b056a9c 100644 --- a/packages/dapp-kit/test/hooks/useSuiClientQuery.test.tsx +++ b/packages/dapp-kit/test/hooks/useSuiClientQuery.test.tsx @@ -8,7 +8,7 @@ import { createWalletProviderContextWrapper } from '../test-utils.js'; describe('useSuiClientQuery', () => { it('should fetch data', async () => { - const suiClient = new SuiClient({ url: getFullnodeUrl('mainnet') }); + const suiClient = new SuiClient({ url: getFullnodeUrl('mainnet'), network: 'mainnet' }); const wrapper = createWalletProviderContextWrapper({}, suiClient); const queryTransactionBlocks = vi.spyOn(suiClient, 'queryTransactionBlocks'); diff --git a/packages/dapp-kit/test/test-utils.tsx b/packages/dapp-kit/test/test-utils.tsx index 997b5cc26..b8c8ea598 100644 --- a/packages/dapp-kit/test/test-utils.tsx +++ b/packages/dapp-kit/test/test-utils.tsx @@ -20,7 +20,7 @@ export function createSuiClientContextWrapper(client: SuiClient) { export function createWalletProviderContextWrapper( providerProps: Omit, 'children'> = {}, - suiClient: SuiClient = new SuiClient({ url: getFullnodeUrl('localnet') }), + suiClient: SuiClient = new SuiClient({ url: getFullnodeUrl('localnet'), network: 'localnet' }), ) { const queryClient = new QueryClient(); return function WalletProviderContextWrapper({ children }: { children: React.ReactNode }) { diff --git a/packages/deepbook/src/client.ts b/packages/deepbook/src/client.ts index ab4993997..c1626fe3e 100644 --- a/packages/deepbook/src/client.ts +++ b/packages/deepbook/src/client.ts @@ -44,7 +44,10 @@ export class DeepBookClient { * @param currentAddress (optional) address of the current user (default: DUMMY_ADDRESS) */ constructor( - public suiClient: SuiClient = new SuiClient({ url: getFullnodeUrl('testnet') }), + public suiClient: SuiClient = new SuiClient({ + url: getFullnodeUrl('testnet'), + network: 'testnet', + }), public accountCap: string | undefined = undefined, public currentAddress: string = DUMMY_ADDRESS, private clientOrderId: number = 0, diff --git a/packages/docs/content/kiosk/kiosk-client/introduction.mdx b/packages/docs/content/kiosk/kiosk-client/introduction.mdx index e9e2b9f62..1f6b5452d 100644 --- a/packages/docs/content/kiosk/kiosk-client/introduction.mdx +++ b/packages/docs/content/kiosk/kiosk-client/introduction.mdx @@ -21,7 +21,7 @@ import { getFullnodeUrl, SuiClient } from '@mysten/sui/client'; // We need a Sui Client. You can re-use the SuiClient of your project // (it's not recommended to create a new one). -const client = new SuiClient({ url: getFullnodeUrl('testnet') }); +const client = new SuiClient({ url: getFullnodeUrl('testnet'), network: 'testnet' }); // Now we can use it to create a kiosk Client. const kioskClient = new KioskClient({ diff --git a/packages/docs/content/typescript/cryptography/keypairs.mdx b/packages/docs/content/typescript/cryptography/keypairs.mdx index 9de140ba9..f0005af6b 100644 --- a/packages/docs/content/typescript/cryptography/keypairs.mdx +++ b/packages/docs/content/typescript/cryptography/keypairs.mdx @@ -122,7 +122,7 @@ import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519'; import { verifyTransactionSignature } from '@mysten/sui/verify'; // see Network Interactions with SuiClient for more info on creating clients -const client = new SuiClient({ url: getFullnodeUrl('testnet') }); +const client = new SuiClient({ url: getFullnodeUrl('testnet'), network: 'testnet' }); const tx = new Transaction(); // ... add some transactions... const bytes = await tx.build({ client }); diff --git a/packages/docs/content/typescript/executors.mdx b/packages/docs/content/typescript/executors.mdx index c2d6c4fe0..de92f4194 100644 --- a/packages/docs/content/typescript/executors.mdx +++ b/packages/docs/content/typescript/executors.mdx @@ -36,7 +36,7 @@ transactions to finish before sending the next one. import { getFullnodeUrl, SuiClient } from '@mysten/sui/client'; import { SerialTransactionExecutor } from '@mysten/sui/transactions'; -const client = new SuiClient({ url: getFullnodeUrl('devnet') }); +const client = new SuiClient({ url: getFullnodeUrl('devnet'), network: 'devnet' }); const executor = new SerialTransactionExecutor({ client, @@ -106,7 +106,7 @@ way that avoids conflicts between transactions using the same object ids. import { getFullnodeUrl, SuiClient } from '@mysten/sui/client'; import { ParallelTransactionExecutor } from '@mysten/sui/transactions'; -const client = new SuiClient({ url: getFullnodeUrl('devnet') }); +const client = new SuiClient({ url: getFullnodeUrl('devnet'), network: 'devnet' }); const executor = new ParallelTransactionExecutor({ client, diff --git a/packages/docs/content/typescript/hello-sui.mdx b/packages/docs/content/typescript/hello-sui.mdx index f584b4642..62c998cfd 100644 --- a/packages/docs/content/typescript/hello-sui.mdx +++ b/packages/docs/content/typescript/hello-sui.mdx @@ -60,7 +60,7 @@ import { MIST_PER_SUI } from '@mysten/sui/utils'; const MY_ADDRESS = ''; // create a new SuiClient object pointing to the network you want to use -const suiClient = new SuiClient({ url: getFullnodeUrl('devnet') }); +const suiClient = new SuiClient({ url: getFullnodeUrl('devnet'), network: 'devnet' }); // Convert MIST to Sui const balance = (balance) => { diff --git a/packages/docs/content/typescript/migrations/sui-2.0.mdx b/packages/docs/content/typescript/migrations/sui-2.0.mdx index 553b8be57..5ca103db8 100644 --- a/packages/docs/content/typescript/migrations/sui-2.0.mdx +++ b/packages/docs/content/typescript/migrations/sui-2.0.mdx @@ -53,3 +53,19 @@ zkLoginPublicIdentifier = toZkLoginPublicIdentifier(seed, iss, { client, legacyA zkLoginPublicIdentifier.verifyPersonalMessage(message, signature); zkLoginPublicIdentifier.verifyTransaction(transaction, signature); ``` + +## Network is now required for GraphQL and JSON RPC clients + +When creating a new `SuiGraphQLClient` or `SuiJsonRpcClient`, you must now provide a `network` +parameter. + +```ts +const client = new SuiGraphQLClient({ + url: 'https://...', + network: 'mainnet', // or 'testnet', 'devnet', etc. +}); +const client = new SuiJsonRpcClient({ + url: 'https://...', + network: 'mainnet', // or 'testnet', 'devnet', etc. +}); +``` diff --git a/packages/docs/content/typescript/sui-client.mdx b/packages/docs/content/typescript/sui-client.mdx index bf06b6809..173a27eee 100644 --- a/packages/docs/content/typescript/sui-client.mdx +++ b/packages/docs/content/typescript/sui-client.mdx @@ -29,6 +29,7 @@ import { SuiJsonRpcClient } from '@mysten/sui/jsonRpc'; // create a client connected to devnet const client = new SuiJsonRpcClient({ url: 'https://fullnode.devnet.sui.io:443', + network: 'devnet', }); // get coins owned by an address @@ -72,7 +73,6 @@ import { SuiJsonRpcClient } from '@mysten/sui/jsonRpc'; const client = new SuiJsonRpcClient({ url: 'https://fullnode.devnet.sui.io:443', }); - // asynchronously call suix_getCommitteeInfo const committeeInfo = await client.call('suix_getCommitteeInfo', []); ``` diff --git a/packages/docs/examples/wallet-components.tsx b/packages/docs/examples/wallet-components.tsx index fb76c0dae..a5c3a5571 100644 --- a/packages/docs/examples/wallet-components.tsx +++ b/packages/docs/examples/wallet-components.tsx @@ -50,7 +50,7 @@ export const UncontrolledConnectModalExample = withProviders(() => { function withProviders(Component: React.FunctionComponent) { const queryClient = new QueryClient(); const networks = { - mainnet: { url: getFullnodeUrl('mainnet') }, + mainnet: { url: getFullnodeUrl('mainnet'), network: 'mainnet' as const }, }; return () => { diff --git a/packages/docs/examples/wallet-hooks.tsx b/packages/docs/examples/wallet-hooks.tsx index 17eb53ded..a11c42ac6 100644 --- a/packages/docs/examples/wallet-hooks.tsx +++ b/packages/docs/examples/wallet-hooks.tsx @@ -309,7 +309,7 @@ function withProviders( // Work around server-side pre-rendering const queryClient = new QueryClient(); const networks = { - mainnet: { url: getFullnodeUrl('mainnet') }, + mainnet: { url: getFullnodeUrl('mainnet'), network: 'mainnet' as const }, }; return () => { diff --git a/packages/enoki-connect/demo-dapp/src/networkConfig.ts b/packages/enoki-connect/demo-dapp/src/networkConfig.ts index f81095781..c75734e6e 100644 --- a/packages/enoki-connect/demo-dapp/src/networkConfig.ts +++ b/packages/enoki-connect/demo-dapp/src/networkConfig.ts @@ -6,12 +6,15 @@ import { createNetworkConfig } from "@mysten/dapp-kit"; const { networkConfig, useNetworkVariable, useNetworkVariables } = createNetworkConfig({ devnet: { + network: "devnet", url: getFullnodeUrl("devnet"), }, testnet: { + network: "testnet", url: getFullnodeUrl("testnet"), }, mainnet: { + network: "mainnet", url: getFullnodeUrl("mainnet"), }, }); diff --git a/packages/seal/test/unit/integration.test.ts b/packages/seal/test/unit/integration.test.ts index d55887e6b..ef0c6eb7a 100644 --- a/packages/seal/test/unit/integration.test.ts +++ b/packages/seal/test/unit/integration.test.ts @@ -122,7 +122,7 @@ describe('Integration test', () => { 'suiprivkey1qqgzvw5zc2zmga0uyp4rzcgk42pzzw6387zqhahr82pp95yz0scscffh2d8', ); suiAddress = keypair.getPublicKey().toSuiAddress(); - suiClient = new SuiClient({ url: getFullnodeUrl('testnet') }); + suiClient = new SuiClient({ url: getFullnodeUrl('testnet'), network: 'testnet' }); TESTNET_PACKAGE_ID = '0x8afa5d31dbaa0a8fb07082692940ca3d56b5e856c5126cb5a3693f0a4de63b82'; // Object ids pointing to ci key servers' urls serverObjectId = '0x3cf2a38f061ede3239c1629cb80a9be0e0676b1c15d34c94d104d4ba9d99076f'; diff --git a/packages/seal/test/unit/key-server.test.ts b/packages/seal/test/unit/key-server.test.ts index 6f8e90019..2a0ddcfac 100644 --- a/packages/seal/test/unit/key-server.test.ts +++ b/packages/seal/test/unit/key-server.test.ts @@ -76,7 +76,7 @@ describe('key-server tests', () => { // Mock fetch with exact response from the real service const keyServers = await retrieveKeyServers({ objectIds: [id], - client: new SuiClient({ url: getFullnodeUrl('testnet') }), + client: new SuiClient({ url: getFullnodeUrl('testnet'), network: 'testnet' }), }); vi.clearAllMocks(); const headers = new Headers(); diff --git a/packages/seal/test/unit/session-key.test.ts b/packages/seal/test/unit/session-key.test.ts index f11f467eb..06698e89e 100644 --- a/packages/seal/test/unit/session-key.test.ts +++ b/packages/seal/test/unit/session-key.test.ts @@ -11,7 +11,7 @@ describe('Session key tests', () => { const TESTNET_PACKAGE_ID = '0x9709d4ee371488c2bc09f508e98e881bd1d5335e0805d7e6a99edd54a7027954'; it('import and export session key', async () => { const kp = Ed25519Keypair.generate(); - const suiClient = new SuiClient({ url: getFullnodeUrl('testnet') }); + const suiClient = new SuiClient({ url: getFullnodeUrl('testnet'), network: 'testnet' }); const sessionKey = await SessionKey.create({ address: kp.getPublicKey().toSuiAddress(), packageId: TESTNET_PACKAGE_ID, diff --git a/packages/signers/README.md b/packages/signers/README.md index 1faa0ec1a..d25b5199a 100644 --- a/packages/signers/README.md +++ b/packages/signers/README.md @@ -179,7 +179,7 @@ import { Transaction } from '@mysten/sui/transactions'; const transport = await Transport.open(undefined); const ledgerClient = new SuiLedgerClient(transport); -const suiClient = new SuiClient({ url: getFullnodeUrl('testnet') }); +const suiClient = new SuiClient({ url: getFullnodeUrl('testnet'), network: 'testnet' }); const signer = await LedgerSigner.fromDerivationPath( "m/44'/784'/0'/0'/0'", diff --git a/packages/suins/test/pre-built.ts b/packages/suins/test/pre-built.ts index 1cac6d3e1..b42396301 100644 --- a/packages/suins/test/pre-built.ts +++ b/packages/suins/test/pre-built.ts @@ -8,7 +8,7 @@ import { expect } from 'vitest'; import { ALLOWED_METADATA, SuinsClient, SuinsTransaction } from '../src/index.js'; export const e2eLiveNetworkDryRunFlow = async (network: 'mainnet' | 'testnet') => { - const client = new SuiClient({ url: getFullnodeUrl(network) }); + const client = new SuiClient({ url: getFullnodeUrl(network), network }); const sender = normalizeSuiAddress('0x2'); const suinsClient = new SuinsClient({ diff --git a/packages/typescript/README.md b/packages/typescript/README.md index 1a588c8dc..9a3562250 100644 --- a/packages/typescript/README.md +++ b/packages/typescript/README.md @@ -83,7 +83,7 @@ read-only operations. The default URLs to connect with the RPC server are: import { getFullnodeUrl, SuiClient } from '@mysten/sui/client'; // create a client connected to devnet -const client = new SuiClient({ url: getFullnodeUrl('devnet') }); +const client = new SuiClient({ url: getFullnodeUrl('devnet'), network: 'devnet' }); // get coins owned by an address await client.getCoins({ @@ -99,7 +99,7 @@ local network with a local validator, a fullnode, and a faucet server. Refer to import { getFullnodeUrl, SuiClient } from '@mysten/sui/client'; // create a client connected to devnet -const client = new SuiClient({ url: getFullnodeUrl('localnet') }); +const client = new SuiClient({ url: getFullnodeUrl('localnet'), network: 'localnet' }); // get coins owned by an address await client.getCoins({ diff --git a/packages/typescript/src/graphql/client.ts b/packages/typescript/src/graphql/client.ts index 81e116af9..c0de9993d 100644 --- a/packages/typescript/src/graphql/client.ts +++ b/packages/typescript/src/graphql/client.ts @@ -51,7 +51,7 @@ export interface SuiGraphQLClientOptions; queries?: Queries; - network?: Experimental_SuiClientTypes.Network; + network: Experimental_SuiClientTypes.Network; mvr?: Experimental_SuiClientTypes.MvrOptions; } @@ -72,7 +72,7 @@ export class SuiGraphQLClient< fetch: fetchFn = fetch, headers = {}, queries = {} as Queries, - network = 'unknown', + network, mvr, }: SuiGraphQLClientOptions) { super({ diff --git a/packages/typescript/src/jsonRpc/client.ts b/packages/typescript/src/jsonRpc/client.ts index acec8fa86..0869e1044 100644 --- a/packages/typescript/src/jsonRpc/client.ts +++ b/packages/typescript/src/jsonRpc/client.ts @@ -117,7 +117,7 @@ export interface OrderArguments { * You must provide either a `url` or a `transport` */ export type SuiJsonRpcClientOptions = NetworkOrTransport & { - network?: Experimental_SuiClientTypes.Network; + network: Experimental_SuiClientTypes.Network; mvr?: Experimental_SuiClientTypes.MvrOptions; }; @@ -154,7 +154,7 @@ export class SuiJsonRpcClient extends Experimental_BaseClient { * @param options configuration options for the API Client */ constructor(options: SuiJsonRpcClientOptions) { - super({ network: options.network ?? 'unknown' }); + super({ network: options.network }); this.transport = options.transport ?? new JsonRpcHTTPTransport({ url: options.url }); this.core = new JSONRpcCoreClient({ jsonRpcClient: this, diff --git a/packages/typescript/test/e2e/graphql.test.ts b/packages/typescript/test/e2e/graphql.test.ts index 0475dca1b..fbd1b2168 100644 --- a/packages/typescript/test/e2e/graphql.test.ts +++ b/packages/typescript/test/e2e/graphql.test.ts @@ -34,6 +34,7 @@ const queries = { const client = new SuiGraphQLClient({ url: DEFAULT_GRAPHQL_URL, + network: 'localnet', queries, }); diff --git a/packages/typescript/test/e2e/named-packages-plugin.test.ts b/packages/typescript/test/e2e/named-packages-plugin.test.ts index eed61947c..8f5e8f9b6 100644 --- a/packages/typescript/test/e2e/named-packages-plugin.test.ts +++ b/packages/typescript/test/e2e/named-packages-plugin.test.ts @@ -98,7 +98,9 @@ describe.concurrent('Name Resolution Plugin', () => { }); const json = JSON.parse( - await transaction.toJSON({ client: new SuiClient({ url: getFullnodeUrl('testnet') }) }), + await transaction.toJSON({ + client: new SuiClient({ url: getFullnodeUrl('testnet'), network: 'testnet' }), + }), ); expect(json.commands[0].MoveCall.package).toBe(normalizeSuiAddress('0x1')); @@ -348,6 +350,7 @@ const dryRun = async ( ) => { const client = new SuiClient({ url: getFullnodeUrl(network), + network, mvr: withOverrides ? { overrides: localMvrOverrides, diff --git a/packages/typescript/test/e2e/utils/setup.ts b/packages/typescript/test/e2e/utils/setup.ts index 49e1ac46f..a60258731 100644 --- a/packages/typescript/test/e2e/utils/setup.ts +++ b/packages/typescript/test/e2e/utils/setup.ts @@ -87,6 +87,7 @@ export class TestToolbox { constructor(keypair: Ed25519Keypair, url: string = DEFAULT_FULLNODE_URL, configPath: string) { this.keypair = keypair; this.client = new SuiClient({ + network: 'localnet', transport: new SuiHTTPTransport({ url, WebSocketConstructor: WebSocket as never, @@ -128,6 +129,7 @@ export class TestToolbox { export function getClient(url = DEFAULT_FULLNODE_URL): SuiClient { return new SuiClient({ + network: 'localnet', transport: new SuiHTTPTransport({ url, WebSocketConstructor: WebSocket as never, diff --git a/packages/typescript/test/e2e/verify-signatures.test.ts b/packages/typescript/test/e2e/verify-signatures.test.ts index 413b3c1a2..74ae77caf 100644 --- a/packages/typescript/test/e2e/verify-signatures.test.ts +++ b/packages/typescript/test/e2e/verify-signatures.test.ts @@ -173,7 +173,7 @@ describe('Verify Signatures', () => { }); describe('zkLogin signatures', () => { - const client = new SuiGraphQLClient({ url: DEFAULT_GRAPHQL_URL }); + const client = new SuiGraphQLClient({ url: DEFAULT_GRAPHQL_URL, network: 'localnet' }); // this test assumes the localnet epoch is smaller than 3. it will fail if localnet has ran for too long and passed epoch 3. // test case generated from `sui keytool zk-login-insecure-sign-personal-message --data "hello" --max-epoch 3` const bytes = fromBase64('aGVsbG8='); // the base64 encoding of "hello" diff --git a/packages/typescript/test/e2e/zklogin-signature.test.ts b/packages/typescript/test/e2e/zklogin-signature.test.ts index 2760f0082..15451c0eb 100644 --- a/packages/typescript/test/e2e/zklogin-signature.test.ts +++ b/packages/typescript/test/e2e/zklogin-signature.test.ts @@ -82,6 +82,7 @@ describe('zkLogin signature', () => { const parsed = parseSerializedZkLoginSignature(testSignature); const client = new SuiGraphQLClient({ url: DEFAULT_GRAPHQL_URL, + network: 'localnet', }); const pk = new ZkLoginPublicIdentifier(parsed.publicKey, { client, @@ -117,6 +118,7 @@ describe('zkLogin signature', () => { const pk = new ZkLoginPublicIdentifier(parsed.publicKey, { client: new SuiGraphQLClient({ url: DEFAULT_GRAPHQL_URL, + network: 'localnet', }), }); diff --git a/packages/wallet-sdk/test/auto-approvals/manager.test.ts b/packages/wallet-sdk/test/auto-approvals/manager.test.ts index 1e311a569..d78adf10c 100644 --- a/packages/wallet-sdk/test/auto-approvals/manager.test.ts +++ b/packages/wallet-sdk/test/auto-approvals/manager.test.ts @@ -29,7 +29,7 @@ const policy: AutoApprovalPolicy = { describe('AutoApprovalManager', () => { test.skip('placeholder example', async () => { const keypair = new Ed25519Keypair(); - const client = new SuiClient({ url: getFullnodeUrl('testnet') }); + const client = new SuiClient({ url: getFullnodeUrl('testnet'), network: 'testnet' }); const tx = new Transaction(); tx.add(operationType('test-operation')); diff --git a/packages/walletconnect-wallet/demo-dapp/src/networkConfig.ts b/packages/walletconnect-wallet/demo-dapp/src/networkConfig.ts index f81095781..c75734e6e 100644 --- a/packages/walletconnect-wallet/demo-dapp/src/networkConfig.ts +++ b/packages/walletconnect-wallet/demo-dapp/src/networkConfig.ts @@ -6,12 +6,15 @@ import { createNetworkConfig } from "@mysten/dapp-kit"; const { networkConfig, useNetworkVariable, useNetworkVariables } = createNetworkConfig({ devnet: { + network: "devnet", url: getFullnodeUrl("devnet"), }, testnet: { + network: "testnet", url: getFullnodeUrl("testnet"), }, mainnet: { + network: "mainnet", url: getFullnodeUrl("mainnet"), }, }); diff --git a/packages/walrus/src/client.ts b/packages/walrus/src/client.ts index 6e98aec8a..49d049cbd 100644 --- a/packages/walrus/src/client.ts +++ b/packages/walrus/src/client.ts @@ -3,7 +3,6 @@ import type { InferBcsType } from '@mysten/bcs'; import { bcs } from '@mysten/bcs'; -import { SuiClient } from '@mysten/sui/client'; import type { Signer } from '@mysten/sui/cryptography'; import type { ClientCache, ClientWithCoreApi } from '@mysten/sui/experimental'; import type { TransactionObjectArgument, TransactionResult } from '@mysten/sui/transactions'; @@ -128,14 +127,13 @@ import { retry } from './utils/retry.js'; export function walrus({ packageConfig, - network, name = 'walrus' as Name, ...options }: WalrusOptions = {}) { return { name, register: (client: ClientWithCoreApi) => { - const walrusNetwork = network || client.network; + const walrusNetwork = client.network; if (walrusNetwork !== 'mainnet' && walrusNetwork !== 'testnet') { throw new WalrusClientError('Walrus client only supports mainnet and testnet'); @@ -197,11 +195,7 @@ export class WalrusClient { this.#uploadRelayClient = new UploadRelayClient(this.#uploadRelayConfig); } - this.#suiClient = - config.suiClient ?? - new SuiClient({ - url: config.suiRpcUrl, - }); + this.#suiClient = config.suiClient; this.#storageNodeClient = new StorageNodeClient(config.storageNodeClientOptions); this.#objectLoader = new SuiObjectDataLoader(this.#suiClient); @@ -211,13 +205,12 @@ export class WalrusClient { /** @deprecated use `walrus()` instead */ static experimental_asClientExtension({ packageConfig, - network, ...options }: WalrusClientExtensionOptions = {}) { return { name: 'walrus' as const, register: (client: ClientWithCoreApi) => { - const walrusNetwork = network || client.network; + const walrusNetwork = client.network; if (walrusNetwork !== 'mainnet' && walrusNetwork !== 'testnet') { throw new WalrusClientError('Walrus client only supports mainnet and testnet'); diff --git a/packages/walrus/src/types.ts b/packages/walrus/src/types.ts index 735e217c9..be74f20a2 100644 --- a/packages/walrus/src/types.ts +++ b/packages/walrus/src/types.ts @@ -31,16 +31,6 @@ export interface WalrusPackageConfig { exchangeIds?: string[]; } -type SuiClientOrRpcUrl = - | { - suiClient: ClientWithCoreApi; - suiRpcUrl?: never; - } - | { - suiRpcUrl: string; - suiClient?: never; - }; - type WalrusNetworkOrPackageConfig = | { network: 'mainnet' | 'testnet'; @@ -89,18 +79,17 @@ interface BaseWalrusClientConfig { * This is used to configure the Walrus client to use a specific storage node client options, network, and Sui client or RPC URL. */ export type WalrusClientConfig = BaseWalrusClientConfig & - WalrusNetworkOrPackageConfig & - SuiClientOrRpcUrl; + WalrusNetworkOrPackageConfig & { + suiClient: ClientWithCoreApi; + }; export type WalrusOptions = BaseWalrusClientConfig & { packageConfig?: WalrusPackageConfig; - network?: 'mainnet' | 'testnet'; name?: Name; }; export type WalrusClientExtensionOptions = BaseWalrusClientConfig & { packageConfig?: WalrusPackageConfig; - network?: 'mainnet' | 'testnet'; }; export type WalrusClientRequestOptions = Pick; diff --git a/packages/zksend/src/index.test.ts b/packages/zksend/src/index.test.ts index c3f5d56fc..e89b35ee7 100644 --- a/packages/zksend/src/index.test.ts +++ b/packages/zksend/src/index.test.ts @@ -23,6 +23,7 @@ export const DEMO_BEAR_CONFIG = { const client = new SuiClient({ url: getFullnodeUrl('testnet'), + network: 'testnet', }); // address: 0x8ab2b2a5cfa538db19062b79622abe28f3171c8b8048c5957b01846d57574630 diff --git a/packages/zksend/src/links/builder.ts b/packages/zksend/src/links/builder.ts index e14071437..f0f4d47b8 100644 --- a/packages/zksend/src/links/builder.ts +++ b/packages/zksend/src/links/builder.ts @@ -61,7 +61,7 @@ export class ZkSendLinkBuilder { path = DEFAULT_ZK_SEND_LINK_OPTIONS.path, keypair = new Ed25519Keypair(), network = DEFAULT_ZK_SEND_LINK_OPTIONS.network, - client = new SuiClient({ url: getFullnodeUrl(network) }), + client = new SuiClient({ url: getFullnodeUrl(network), network }), sender, contract = getContractIds(network), }: ZkSendLinkBuilderOptions) { @@ -302,7 +302,7 @@ export class ZkSendLinkBuilder { static async createLinks({ links, network = 'mainnet', - client = new SuiClient({ url: getFullnodeUrl(network) }), + client = new SuiClient({ url: getFullnodeUrl(network), network }), transaction = new Transaction(), contract: contractIds = getContractIds(network), }: { diff --git a/packages/zksend/src/links/claim.ts b/packages/zksend/src/links/claim.ts index 96c465cf9..8f79f539c 100644 --- a/packages/zksend/src/links/claim.ts +++ b/packages/zksend/src/links/claim.ts @@ -88,7 +88,7 @@ export class ZkSendLink { constructor({ network = DEFAULT_ZK_SEND_LINK_OPTIONS.network, - client = new SuiClient({ url: getFullnodeUrl(network) }), + client = new SuiClient({ url: getFullnodeUrl(network), network }), keypair, contract = getContractIds(network), address, diff --git a/packages/zksend/src/links/get-sent-transactions.ts b/packages/zksend/src/links/get-sent-transactions.ts index 546803a57..138dc1d2a 100644 --- a/packages/zksend/src/links/get-sent-transactions.ts +++ b/packages/zksend/src/links/get-sent-transactions.ts @@ -15,7 +15,7 @@ export async function getSentTransactionsWithLinks({ limit = 10, network = 'mainnet', contract = getContractIds(network), - client = new SuiClient({ url: getFullnodeUrl(network) }), + client = new SuiClient({ url: getFullnodeUrl(network), network }), loadAssets = true, loadClaimedAssets = false, options, diff --git a/packages/zksend/src/links/list-created-links.ts b/packages/zksend/src/links/list-created-links.ts index 387f97552..3147731f1 100644 --- a/packages/zksend/src/links/list-created-links.ts +++ b/packages/zksend/src/links/list-created-links.ts @@ -54,6 +54,7 @@ export async function listCreatedLinks({ fetch?: typeof fetch; }) { const gqlClient = new SuiGraphQLClient({ + network: network || 'mainnet', url: network === 'testnet' ? 'https://graphql.testnet.sui.io/graphql' From 0f76bcc4594dcfc460e8b6d005da2ae9475fe0ad Mon Sep 17 00:00:00 2001 From: hayes-mysten <135670682+hayes-mysten@users.noreply.github.com> Date: Tue, 21 Oct 2025 16:29:17 -0700 Subject: [PATCH 04/13] remove reportTransactionEffects (#630) Co-authored-by: Michael Hayes --- .changeset/curly-boxes-follow.md | 5 ++ .changeset/mean-bikes-drum.md | 5 ++ .../src/constants/walletMutationKeys.ts | 1 - .../wallet/useReportTransactionEffects.ts | 82 ------------------- .../wallet/useSignAndExecuteTransaction.ts | 14 ---- .../src/hooks/wallet/useSignTransaction.ts | 14 +--- packages/dapp-kit/src/index.ts | 1 - .../useSignAndExecuteTransaction.test.tsx | 29 ------- .../test/hooks/useSignTransaction.test.tsx | 1 - packages/dapp-kit/test/mocks/mockFeatures.ts | 4 - .../content/dapp-kit/wallet-hooks/_meta.json | 3 +- .../useReportTransactionEffects.mdx | 58 ------------- .../wallet-hooks/useSignTransaction.mdx | 8 +- .../content/typescript/migrations/sui-2.0.mdx | 43 ++++++++++ .../wallet-standard/src/features/index.ts | 3 - .../features/suiReportTransactionEffects.ts | 36 -------- 16 files changed, 56 insertions(+), 251 deletions(-) create mode 100644 .changeset/curly-boxes-follow.md create mode 100644 .changeset/mean-bikes-drum.md delete mode 100644 packages/dapp-kit/src/hooks/wallet/useReportTransactionEffects.ts delete mode 100644 packages/docs/content/dapp-kit/wallet-hooks/useReportTransactionEffects.mdx delete mode 100644 packages/wallet-standard/src/features/suiReportTransactionEffects.ts diff --git a/.changeset/curly-boxes-follow.md b/.changeset/curly-boxes-follow.md new file mode 100644 index 000000000..e7dba4469 --- /dev/null +++ b/.changeset/curly-boxes-follow.md @@ -0,0 +1,5 @@ +--- +'@mysten/dapp-kit': minor +--- + +Remove reportTransactionEffects feature diff --git a/.changeset/mean-bikes-drum.md b/.changeset/mean-bikes-drum.md new file mode 100644 index 000000000..0b4d6f089 --- /dev/null +++ b/.changeset/mean-bikes-drum.md @@ -0,0 +1,5 @@ +--- +'@mysten/wallet-standard': minor +--- + +Remove reportTransactionEffects feature diff --git a/packages/dapp-kit/src/constants/walletMutationKeys.ts b/packages/dapp-kit/src/constants/walletMutationKeys.ts index 679d17c12..6d9212283 100644 --- a/packages/dapp-kit/src/constants/walletMutationKeys.ts +++ b/packages/dapp-kit/src/constants/walletMutationKeys.ts @@ -12,7 +12,6 @@ export const walletMutationKeys = { signTransaction: formMutationKeyFn('sign-transaction'), signAndExecuteTransaction: formMutationKeyFn('sign-and-execute-transaction'), switchAccount: formMutationKeyFn('switch-account'), - reportTransactionEffects: formMutationKeyFn('report-transaction-effects'), }; function formMutationKeyFn(baseEntity: string) { diff --git a/packages/dapp-kit/src/hooks/wallet/useReportTransactionEffects.ts b/packages/dapp-kit/src/hooks/wallet/useReportTransactionEffects.ts deleted file mode 100644 index 554d93f4f..000000000 --- a/packages/dapp-kit/src/hooks/wallet/useReportTransactionEffects.ts +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (c) Mysten Labs, Inc. -// SPDX-License-Identifier: Apache-2.0 - -import { toBase64 } from '@mysten/sui/utils'; -import type { SuiReportTransactionEffectsInput } from '@mysten/wallet-standard'; -import type { UseMutationOptions, UseMutationResult } from '@tanstack/react-query'; -import { useMutation } from '@tanstack/react-query'; - -import { walletMutationKeys } from '../../constants/walletMutationKeys.js'; -import type { WalletFeatureNotSupportedError } from '../../errors/walletErrors.js'; -import { - WalletNoAccountSelectedError, - WalletNotConnectedError, -} from '../../errors/walletErrors.js'; -import type { PartialBy } from '../../types/utilityTypes.js'; -import { useCurrentAccount } from './useCurrentAccount.js'; -import { useCurrentWallet } from './useCurrentWallet.js'; - -type UseReportTransactionEffectsArgs = Omit< - PartialBy, - 'effects' -> & { - effects: string | number[]; -}; - -type UseReportTransactionEffectsError = - | WalletFeatureNotSupportedError - | WalletNoAccountSelectedError - | WalletNotConnectedError - | Error; - -type UseReportTransactionEffectsMutationOptions = Omit< - UseMutationOptions< - void, - UseReportTransactionEffectsError, - UseReportTransactionEffectsArgs, - unknown - >, - 'mutationFn' ->; - -/** - * Mutation hook for prompting the user to sign a message. - */ -export function useReportTransactionEffects({ - mutationKey, - ...mutationOptions -}: UseReportTransactionEffectsMutationOptions = {}): UseMutationResult< - void, - UseReportTransactionEffectsError, - UseReportTransactionEffectsArgs -> { - const { currentWallet } = useCurrentWallet(); - const currentAccount = useCurrentAccount(); - - return useMutation({ - mutationKey: walletMutationKeys.reportTransactionEffects(mutationKey), - mutationFn: async ({ effects, chain = currentWallet?.chains[0], account = currentAccount }) => { - if (!currentWallet) { - throw new WalletNotConnectedError('No wallet is connected.'); - } - - if (!account) { - throw new WalletNoAccountSelectedError( - 'No wallet account is selected to report transaction effects for', - ); - } - - const reportTransactionEffectsFeature = - currentWallet.features['sui:reportTransactionEffects']; - - if (reportTransactionEffectsFeature) { - return await reportTransactionEffectsFeature.reportTransactionEffects({ - effects: Array.isArray(effects) ? toBase64(new Uint8Array(effects)) : effects, - account, - chain: chain ?? currentWallet?.chains[0], - }); - } - }, - ...mutationOptions, - }); -} diff --git a/packages/dapp-kit/src/hooks/wallet/useSignAndExecuteTransaction.ts b/packages/dapp-kit/src/hooks/wallet/useSignAndExecuteTransaction.ts index 27db7ee4d..9523fd2a4 100644 --- a/packages/dapp-kit/src/hooks/wallet/useSignAndExecuteTransaction.ts +++ b/packages/dapp-kit/src/hooks/wallet/useSignAndExecuteTransaction.ts @@ -21,7 +21,6 @@ import type { PartialBy } from '../../types/utilityTypes.js'; import { useSuiClientContext } from '../useSuiClient.js'; import { useCurrentAccount } from './useCurrentAccount.js'; import { useCurrentWallet } from './useCurrentWallet.js'; -import { useReportTransactionEffects } from './useReportTransactionEffects.js'; type UseSignAndExecuteTransactionArgs = PartialBy< Omit, @@ -78,7 +77,6 @@ export function useSignAndExecuteTransaction< const { currentWallet, supportedIntents } = useCurrentWallet(); const currentAccount = useCurrentAccount(); const { client, network } = useSuiClientContext(); - const { mutate: reportTransactionEffects } = useReportTransactionEffects(); const executeTransaction: ({ bytes, @@ -152,18 +150,6 @@ export function useSignAndExecuteTransaction< const result = await executeTransaction({ bytes, signature }); - let effects: string; - - if ('effects' in result && result.effects?.bcs) { - effects = result.effects.bcs; - } else if ('rawEffects' in result) { - effects = toBase64(new Uint8Array(result.rawEffects!)); - } else { - throw new Error('Could not parse effects from transaction result.'); - } - - reportTransactionEffects({ effects, account: signerAccount, chain }); - return result as Result; }, ...mutationOptions, diff --git a/packages/dapp-kit/src/hooks/wallet/useSignTransaction.ts b/packages/dapp-kit/src/hooks/wallet/useSignTransaction.ts index 6257f0d2c..3848c2c4b 100644 --- a/packages/dapp-kit/src/hooks/wallet/useSignTransaction.ts +++ b/packages/dapp-kit/src/hooks/wallet/useSignTransaction.ts @@ -17,7 +17,6 @@ import type { PartialBy } from '../../types/utilityTypes.js'; import { useSuiClientContext } from '../useSuiClient.js'; import { useCurrentAccount } from './useCurrentAccount.js'; import { useCurrentWallet } from './useCurrentWallet.js'; -import { useReportTransactionEffects } from './useReportTransactionEffects.js'; type UseSignTransactionArgs = PartialBy< Omit, @@ -26,9 +25,7 @@ type UseSignTransactionArgs = PartialBy< transaction: Transaction | string; }; -interface UseSignTransactionResult extends SignedTransaction { - reportTransactionEffects: (effects: string) => void; -} +interface UseSignTransactionResult extends SignedTransaction {} type UseSignTransactionError = | WalletFeatureNotSupportedError @@ -61,8 +58,6 @@ export function useSignTransaction({ const currentAccount = useCurrentAccount(); const { client, network } = useSuiClientContext(); - const { mutate: reportTransactionEffects } = useReportTransactionEffects(); - return useMutation({ mutationKey: walletMutationKeys.signTransaction(mutationKey), mutationFn: async ({ transaction, ...signTransactionArgs }) => { @@ -110,13 +105,6 @@ export function useSignTransaction({ return { bytes, signature, - reportTransactionEffects: (effects) => { - reportTransactionEffects({ - effects, - account: signerAccount, - chain, - }); - }, }; }, ...mutationOptions, diff --git a/packages/dapp-kit/src/index.ts b/packages/dapp-kit/src/index.ts index 15d4c7a64..24ad8c71e 100644 --- a/packages/dapp-kit/src/index.ts +++ b/packages/dapp-kit/src/index.ts @@ -21,7 +21,6 @@ export * from './hooks/wallet/useDisconnectWallet.js'; export * from './hooks/wallet/useSignAndExecuteTransaction.js'; export * from './hooks/wallet/useSignPersonalMessage.js'; export * from './hooks/wallet/useSignTransaction.js'; -export * from './hooks/wallet/useReportTransactionEffects.js'; export * from './hooks/wallet/useSwitchAccount.js'; export * from './hooks/wallet/useWallets.js'; export * from './themes/lightTheme.js'; diff --git a/packages/dapp-kit/test/hooks/useSignAndExecuteTransaction.test.tsx b/packages/dapp-kit/test/hooks/useSignAndExecuteTransaction.test.tsx index 7e2df1d4e..041afd38a 100644 --- a/packages/dapp-kit/test/hooks/useSignAndExecuteTransaction.test.tsx +++ b/packages/dapp-kit/test/hooks/useSignAndExecuteTransaction.test.tsx @@ -71,11 +71,6 @@ describe('useSignAndExecuteTransaction', () => { signature: '123', }); - const reportEffectsFeature = mockWallet.features['sui:reportTransactionEffects']; - const reportEffects = reportEffectsFeature!.reportTransactionEffects as Mock; - - reportEffects.mockImplementation(async () => {}); - const executeTransaction = vi.spyOn(suiClient, 'executeTransactionBlock'); executeTransaction.mockResolvedValueOnce({ @@ -109,11 +104,6 @@ describe('useSignAndExecuteTransaction', () => { signature: '123', rawEffects: [10, 20, 30], }); - expect(reportEffects).toHaveBeenCalledWith({ - effects: 'ChQe', - chain: 'sui:testnet', - account: mockWallet.accounts[0], - }); const call = signTransaction.mock.calls[0]; @@ -139,10 +129,6 @@ describe('useSignAndExecuteTransaction', () => { signature: '123', }); - const reportEffectsFeature = mockWallet.features['sui:reportTransactionEffects']; - const reportEffects = reportEffectsFeature!.reportTransactionEffects as Mock; - reportEffects.mockImplementation(async () => {}); - const suiClient = new SuiClient({ url: getFullnodeUrl('localnet'), network: 'localnet' }); const executeTransaction = vi.spyOn(suiClient, 'executeTransactionBlock'); executeTransaction.mockResolvedValueOnce({ @@ -167,11 +153,6 @@ describe('useSignAndExecuteTransaction', () => { }); await waitFor(() => expect(result.current.useSignAndExecuteTransaction.isSuccess).toBe(true)); - expect(reportEffects).toHaveBeenCalledWith({ - effects: 'ChQe', - chain: 'sui:test', - account: mockWallet.accounts[0], - }); expect(signTransaction).toHaveBeenCalledWith({ transaction: expect.any(Object), @@ -197,11 +178,6 @@ describe('useSignAndExecuteTransaction', () => { signature: '123', }); - const reportEffectsFeature = mockWallet.features['sui:reportTransactionEffects']; - const reportEffects = reportEffectsFeature!.reportTransactionEffects as Mock; - - reportEffects.mockImplementation(async () => {}); - const wrapper = createWalletProviderContextWrapper({}, suiClient); const fakeDigest = toBase58( @@ -272,11 +248,6 @@ describe('useSignAndExecuteTransaction', () => { custom: 123, }); expect(result.current.useSignAndExecuteTransaction.data?.custom).toBe(123); - expect(reportEffects).toHaveBeenCalledWith({ - account: mockWallet.accounts[0], - chain: 'sui:testnet', - effects: effectsBcs, - }); const call = signTransaction.mock.calls[0]; diff --git a/packages/dapp-kit/test/hooks/useSignTransaction.test.tsx b/packages/dapp-kit/test/hooks/useSignTransaction.test.tsx index 1b1562fc2..6968853de 100644 --- a/packages/dapp-kit/test/hooks/useSignTransaction.test.tsx +++ b/packages/dapp-kit/test/hooks/useSignTransaction.test.tsx @@ -87,7 +87,6 @@ describe('useSignTransaction', () => { expect(result.current.signTransaction.data).toStrictEqual({ bytes: 'abc', signature: '123', - reportTransactionEffects: expect.any(Function), }); expect(signTransactionMock).toHaveBeenCalledWith({ diff --git a/packages/dapp-kit/test/mocks/mockFeatures.ts b/packages/dapp-kit/test/mocks/mockFeatures.ts index 27da03be9..e34689a62 100644 --- a/packages/dapp-kit/test/mocks/mockFeatures.ts +++ b/packages/dapp-kit/test/mocks/mockFeatures.ts @@ -39,8 +39,4 @@ export const suiFeatures: SuiFeatures = { version: '2.0.0', signAndExecuteTransaction: vi.fn(), }, - 'sui:reportTransactionEffects': { - version: '1.0.0', - reportTransactionEffects: vi.fn(), - }, }; diff --git a/packages/docs/content/dapp-kit/wallet-hooks/_meta.json b/packages/docs/content/dapp-kit/wallet-hooks/_meta.json index 12f0853d8..b275c19d5 100644 --- a/packages/docs/content/dapp-kit/wallet-hooks/_meta.json +++ b/packages/docs/content/dapp-kit/wallet-hooks/_meta.json @@ -9,6 +9,5 @@ "useSwitchAccount": "useSwitchAccount", "useSignPersonalMessage": "useSignPersonalMessage", "useSignTransaction": "useSignTransaction", - "useSignAndExecuteTransaction": "useSignAndExecuteTransaction", - "useReportTransactionEffects": "useReportTransactionEffects" + "useSignAndExecuteTransaction": "useSignAndExecuteTransaction" } diff --git a/packages/docs/content/dapp-kit/wallet-hooks/useReportTransactionEffects.mdx b/packages/docs/content/dapp-kit/wallet-hooks/useReportTransactionEffects.mdx deleted file mode 100644 index 6f31e5f8c..000000000 --- a/packages/docs/content/dapp-kit/wallet-hooks/useReportTransactionEffects.mdx +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: useReportTransactionEffects ---- - -import { UseSignTransactionExample } from '../../../examples/wallet-hooks'; - -Use the `useReportTransactionEffects` hook can be used to report the effects of a transaction to the -connected wallet. The `useSignAndExecuteTransaction` hook automatically reports effects, and the -`useSignTransaction` hook provides a `reportTransactionEffects` callback to report effects manually, -so this hook is only needed when using a non-standard flow for executing transactions. - -```ts -import { - ConnectButton, - useCurrentAccount, - useReportTransactionEffects, - useSuiClient, -} from '@mysten/dapp-kit'; -import { toBase64 } from '@mysten/sui/utils'; -import { useState } from 'react'; - -function MyComponent() { - const { mutateAsync: reportTransactionEffects } = useReportTransactionEffects(); - const [signature, setSignature] = useState(''); - const client = useSuiClient(); - const currentAccount = useCurrentAccount(); - - return ( -
- - {currentAccount && ( - <> -
- -
-
Signature: {signature}
- - )} -
- ); -} -``` - -## Arguments - -- `effects`: The effects of an executed transaction. This can either be the `rawEffects` returned - from the JSON-RPC `executeTransactionBlock` method (returned when showRawEffects is set to true), - or the `effects.bcs` when executing with the GraphQL API. -- `chain`: (optional) The chain identifier the transaction was executed on. -- `account` (optional) the account that signed the transaction, defaults to the currently connected - account diff --git a/packages/docs/content/dapp-kit/wallet-hooks/useSignTransaction.mdx b/packages/docs/content/dapp-kit/wallet-hooks/useSignTransaction.mdx index 95e6cc133..b48dbc91a 100644 --- a/packages/docs/content/dapp-kit/wallet-hooks/useSignTransaction.mdx +++ b/packages/docs/content/dapp-kit/wallet-hooks/useSignTransaction.mdx @@ -31,7 +31,7 @@ function MyComponent() {