{"record":{"id":"01deb8ee6cc0faf0","repo":"unionlabs/union","slug":"invalid-sui-signer-expected-ed25519keypair","errorCode":null,"errorMessage":"Invalid Sui signer: expected Ed25519Keypair","messagePattern":"Invalid Sui signer: expected Ed25519Keypair","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ts-sdk-sui/src/internal/sui.ts","lineNumber":38,"sourceCode":"          new Sui.CreatePublicClientError({\n            cause: Utils.extractErrorDetails(err as Sui.CreatePublicClientError),\n          }),\n      }),\n      Effect.map((client) => ({ client })),\n    ),\n  )\n\n/** @internal */\nexport const walletClientLayer = <Id>(\n  tag: Context.Tag<Id, Sui.Sui.WalletClient>,\n) =>\n(opts: { url: string; signer: Ed25519Keypair }): Layer.Layer<Id, Sui.CreateWalletClientError> =>\n  Layer.effect(\n    tag,\n    Effect.try({\n      try: () => {\n        if (!opts?.signer || typeof opts.signer.getPublicKey !== \"function\") {\n          throw new Error(\"Invalid Sui signer: expected Ed25519Keypair\")\n        }\n        const client = new SuiClient({ url: opts.url } satisfies SuiClientOptions)\n        return { client, signer: opts.signer, rpc: opts.url }\n      },\n      catch: (err) =>\n        new Sui.CreateWalletClientError({\n          cause: Utils.extractErrorDetails(err as Error),\n        }),\n    }),\n  )\n","sourceCodeStart":20,"sourceCodeEnd":49,"githubUrl":"https://github.com/unionlabs/union/blob/031785bb6dc6b957c624e62bc64c184409c97d7b/ts-sdk-sui/src/internal/sui.ts#L20-L49","documentation":"ts-sdk-sui's walletClientLayer duck-types opts.signer: it must be an object exposing a callable getPublicKey, i.e. an @mysten/sui Ed25519Keypair. Anything else — a raw private key string/bytes, an Ed25519PublicKey, or undefined/null — triggers this throw, which the catch then wraps into a typed Sui.CreateWalletClientError.","triggerScenarios":"Passing a hex/base64 private key string where the keypair object is expected; passing Ed25519PublicKey instead of the keypair; omitting signer in the layer options so opts?.signer is undefined.","commonSituations":"Loading keys from environment variables and forgetting to construct the keypair; mixing up @mysten/sui/keypairs/ed25519 exports when integrating the SDK.","solutions":["Construct the keypair first: Ed25519Keypair.fromSecretKey(fromB64(privateKey)) or Ed25519Keypair.deriveKeypair(mnemonic), then pass that object as signer","Pass an Ed25519Keypair, never the string key, public key, or raw bytes","Fail fast with a clear message when opts.signer is missing before building the layer"],"exampleFix":"// before\nconst layer = walletClientLayer(Tag)({\n  url: rpcUrl,\n  signer: process.env.SUI_PRIVATE_KEY as unknown as Ed25519Keypair, // string!\n})\n\n// after\nimport { Ed25519Keypair } from \"@mysten/sui/keypairs/ed25519\"\nimport { fromB64 } from \"@mysten/sui/utils\"\n\nconst signer = Ed25519Keypair.fromSecretKey(fromB64(process.env.SUI_PRIVATE_KEY!))\nconst layer = walletClientLayer(Tag)({ url: rpcUrl, signer })","handlingStrategy":"type-guard","validationCode":"if (!opts?.signer || typeof opts.signer.getPublicKey !== \"function\") {\n  throw new Error(\"Pass an Ed25519Keypair — build it with Ed25519Keypair.fromSecretKey()\")\n}","typeGuard":"import { Ed25519Keypair } from \"@mysten/sui/keypairs/ed25519\"\n\nconst isEd25519Keypair = (s: unknown): s is Ed25519Keypair =>\n  !!s && typeof (s as Ed25519Keypair).getPublicKey === \"function\"","tryCatchPattern":"try {\n  const layer = walletClientLayer(Tag)({ url, signer })\n} catch (e) {\n  if (e instanceof Sui.CreateWalletClientError && /Invalid Sui signer/.test(String(e.cause))) {\n    throw new Error(\"signer must be an Ed25519Keypair (fromSecretKey/deriveKeypair)\")\n  }\n  throw e\n}","preventionTips":["Always construct the keypair object before building the layer","Type the signer field as Ed25519Keypair at the boundary so strings fail at compile time","Never cast env-loaded strings to keypair types"],"tags":["sui","signer","keypair","validation"],"backgroundTag":null,"analyzedSha":"031785bb6dc6b957c624e62bc64c184409c97d7b","analyzedAt":"2026-08-16T06:24:09.996Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}