• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

nktkas / hyperliquid / 19405103680

16 Nov 2025 11:46AM UTC coverage: 94.726% (-0.6%) from 95.329%
19405103680

push

github

nktkas
test(info): adapt command execution for Deno and Node.js environments

368 of 581 branches covered (63.34%)

Branch coverage included in aggregate %.

11667 of 12124 relevant lines covered (96.23%)

951.31 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.88
/src/api/exchange/convertToMultiSigUser.ts
1
import * as v from "valibot";
353✔
2
import { Address, type DeepImmutable, Hex, parser, UnsignedInteger } from "../_base.ts";
353✔
3
import {
353✔
4
  type ExchangeRequestConfig,
5
  executeUserSignedAction,
353✔
6
  type ExtractRequestAction,
7
  type ExtractRequestOptions,
8
  getSignatureChainId,
353✔
9
  type MultiSignRequestConfig,
10
  Signature,
353✔
11
} from "./_base/mod.ts";
353✔
12

13
// -------------------- Schemas --------------------
14

15
/** Signers configuration for {@linkcode ConvertToMultiSigUserRequest}. */
16
export const ConvertToMultiSigUserRequestSigners = /* @__PURE__ */ (() => {
353✔
17
  return v.pipe(
598✔
18
    v.union([
598✔
19
      v.object({
598✔
20
        /** List of authorized user addresses. */
21
        authorizedUsers: v.pipe(
598✔
22
          v.array(Address),
598✔
23
          v.description("List of authorized user addresses."),
598✔
24
        ),
25
        /** Minimum number of signatures required. */
26
        threshold: v.pipe(
598✔
27
          UnsignedInteger,
598✔
28
          v.description("Minimum number of signatures required."),
598✔
29
        ),
30
      }),
598✔
31
      /** Convert a multi-signature account to a single-signature account. */
32
      v.pipe(
598✔
33
        v.null(),
598✔
34
        v.description("Convert a multi-signature account to a single-signature account."),
598✔
35
      ),
36
    ]),
598✔
37
    v.description("Signers configuration for `ConvertToMultiSigUserRequest`"),
598✔
38
  );
39
})();
353✔
40
export type ConvertToMultiSigUserRequestSigners = v.InferOutput<typeof ConvertToMultiSigUserRequestSigners>;
41

42
/**
43
 * Convert a single-signature account to a multi-signature account or vice versa.
44
 * @see https://hyperliquid.gitbook.io/hyperliquid-docs/hypercore/multi-sig
45
 */
46
export const ConvertToMultiSigUserRequest = /* @__PURE__ */ (() => {
353✔
47
  return v.pipe(
598✔
48
    v.object({
598✔
49
      /** Action to perform. */
50
      action: v.pipe(
598✔
51
        v.object({
598✔
52
          /** Type of action. */
53
          type: v.pipe(
598✔
54
            v.literal("convertToMultiSigUser"),
598✔
55
            v.description("Type of action."),
598✔
56
          ),
57
          /** Chain ID used for signing. */
58
          signatureChainId: v.pipe(
598✔
59
            Hex,
598✔
60
            v.description("Chain ID used for signing."),
598✔
61
          ),
62
          /** HyperLiquid network. */
63
          hyperliquidChain: v.pipe(
598✔
64
            v.union([v.literal("Mainnet"), v.literal("Testnet")]),
2,392✔
65
            v.description("HyperLiquid network."),
598✔
66
          ),
67
          /**
68
           * Signers configuration.
69
           *
70
           * Must be {@linkcode ConvertToMultiSigUserRequestSigners} converted to a string via `JSON.stringify(...)`.
71
           */
72
          signers: v.pipe(
598✔
73
            v.union([
598✔
74
              v.pipe(
598✔
75
                v.string(),
598✔
76
                v.parseJson(),
598✔
77
                ConvertToMultiSigUserRequestSigners,
598✔
78
                v.stringifyJson(),
598✔
79
              ),
80
              v.pipe(
598✔
81
                ConvertToMultiSigUserRequestSigners,
598✔
82
                v.stringifyJson(),
598✔
83
              ),
84
            ]),
598✔
85
            v.description(
598✔
86
              "Signers configuration." +
598✔
87
                "\n\nMust be `ConvertToMultiSigUserRequestSigners` converted to a string via `JSON.stringify(...)`.",
598✔
88
            ),
89
          ),
90
          /** Unique request identifier (current timestamp in ms). */
91
          nonce: v.pipe(
598✔
92
            UnsignedInteger,
598✔
93
            v.description("Unique request identifier (current timestamp in ms)."),
598✔
94
          ),
95
        }),
598✔
96
        v.description("Action to perform."),
598✔
97
      ),
98
      /** Unique request identifier (current timestamp in ms). */
99
      nonce: v.pipe(
598✔
100
        UnsignedInteger,
598✔
101
        v.description("Unique request identifier (current timestamp in ms)."),
598✔
102
      ),
103
      /** Cryptographic signature. */
104
      signature: v.pipe(
598✔
105
        Signature,
598✔
106
        v.description("Cryptographic signature."),
598✔
107
      ),
108
    }),
598✔
109
    v.description("Convert a single-signature account to a multi-signature account or vice versa."),
598✔
110
  );
111
})();
353✔
112
export type ConvertToMultiSigUserRequest = v.InferOutput<typeof ConvertToMultiSigUserRequest>;
113

114
import { SuccessResponse } from "./_base/mod.ts";
353✔
115
export { SuccessResponse };
353✔
116

117
// -------------------- Function --------------------
118

119
/** Action parameters for the {@linkcode convertToMultiSigUser} function. */
120
export type ConvertToMultiSigUserParameters = ExtractRequestAction<v.InferInput<typeof ConvertToMultiSigUserRequest>>;
121
/** Request options for the {@linkcode convertToMultiSigUser} function. */
122
export type ConvertToMultiSigUserOptions = ExtractRequestOptions<v.InferInput<typeof ConvertToMultiSigUserRequest>>;
123

124
/** EIP-712 types for the {@linkcode convertToMultiSigUser} function. */
125
export const ConvertToMultiSigUserTypes = {
353✔
126
  "HyperliquidTransaction:ConvertToMultiSigUser": [
353✔
127
    { name: "hyperliquidChain", type: "string" },
1,412✔
128
    { name: "signers", type: "string" },
1,412✔
129
    { name: "nonce", type: "uint64" },
1,412✔
130
  ],
131
};
353✔
132

133
/**
134
 * Convert a single-signature account to a multi-signature account or vice versa.
135
 * @param config - General configuration for Exchange API requests.
136
 * @param params - Parameters specific to the API request.
137
 * @param opts - Request execution options.
138
 * @returns Successful response without specific data.
139
 *
140
 * @throws {ApiRequestError} When the API returns an unsuccessful response.
141
 * @throws {TransportError} When the transport layer throws an error.
142
 *
143
 * @see https://hyperliquid.gitbook.io/hyperliquid-docs/hypercore/multi-sig
144
 * @example
145
 * ```ts
146
 * import { HttpTransport } from "@nktkas/hyperliquid";
147
 * import { convertToMultiSigUser } from "@nktkas/hyperliquid/api/exchange";
148
 * import { privateKeyToAccount } from "npm:viem/accounts";
149
 *
150
 * const wallet = privateKeyToAccount("0x..."); // viem or ethers
151
 * const transport = new HttpTransport(); // or `WebSocketTransport`
152
 *
153
 * // Convert to multi-sig user
154
 * await convertToMultiSigUser(
155
 *   { transport, wallet },
156
 *   {
157
 *     signers: {
158
 *       authorizedUsers: ["0x...", "0x...", "0x..."],
159
 *       threshold: 2,
160
 *     },
161
 *   },
162
 * );
163
 *
164
 * // Convert to single-sig user
165
 * await convertToMultiSigUser(
166
 *   { transport, wallet },
167
 *   { signers: null },
168
 * );
169
 * ```
170
 */
171
export async function convertToMultiSigUser(
353✔
172
  config: ExchangeRequestConfig | MultiSignRequestConfig,
353✔
173
  params: DeepImmutable<ConvertToMultiSigUserParameters>,
353✔
174
  opts?: ConvertToMultiSigUserOptions,
353✔
175
): Promise<SuccessResponse> {
176
  const request = parser(ConvertToMultiSigUserRequest)({
396✔
177
    action: {
396✔
178
      type: "convertToMultiSigUser",
396✔
179
      hyperliquidChain: config.transport.isTestnet ? "Testnet" : "Mainnet",
×
180
      signatureChainId: await getSignatureChainId(config),
396✔
181
      nonce: 0, // Placeholder; actual nonce generated in `executeUserSignedAction` to prevent race conditions
396✔
182
      ...params,
396✔
183
    },
396✔
184
    nonce: 0, // Placeholder; actual nonce generated in `executeUserSignedAction` to prevent race conditions
396✔
185
    signature: { // Placeholder; actual signature generated in `executeUserSignedAction`
396✔
186
      r: "0x0000000000000000000000000000000000000000000000000000000000000000",
396✔
187
      s: "0x0000000000000000000000000000000000000000000000000000000000000000",
396✔
188
      v: 27,
396✔
189
    },
396✔
190
  });
396✔
191
  return await executeUserSignedAction(config, request, ConvertToMultiSigUserTypes, opts?.signal);
×
192
}
396✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc