@nktkas/hyperliquid 0.22.1 → 0.22.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +84 -27
- package/esm/mod.d.ts +1 -1
- package/esm/mod.d.ts.map +1 -1
- package/esm/src/clients/exchange.d.ts +136 -166
- package/esm/src/clients/exchange.d.ts.map +1 -1
- package/esm/src/clients/exchange.js +121 -146
- package/esm/src/clients/multiSign.d.ts +121 -280
- package/esm/src/clients/multiSign.d.ts.map +1 -1
- package/esm/src/clients/multiSign.js +123 -246
- package/esm/src/signing/_ethers.d.ts +33 -0
- package/esm/src/signing/_ethers.d.ts.map +1 -0
- package/esm/src/signing/_ethers.js +12 -0
- package/esm/src/signing/_private_key.d.ts +22 -0
- package/esm/src/signing/_private_key.d.ts.map +1 -0
- package/esm/src/signing/_private_key.js +124 -0
- package/esm/src/signing/_sorter.d.ts +154 -0
- package/esm/src/signing/_sorter.d.ts.map +1 -0
- package/esm/src/{signing.js → signing/_sorter.js} +0 -400
- package/esm/src/signing/_viem.d.ts +23 -0
- package/esm/src/signing/_viem.d.ts.map +1 -0
- package/esm/src/signing/_viem.js +6 -0
- package/esm/src/signing/_window.d.ts +23 -0
- package/esm/src/signing/_window.d.ts.map +1 -0
- package/esm/src/signing/_window.js +29 -0
- package/esm/src/signing/mod.d.ts +251 -0
- package/esm/src/signing/mod.d.ts.map +1 -0
- package/esm/src/signing/mod.js +352 -0
- package/package.json +6 -5
- package/script/mod.d.ts +1 -1
- package/script/mod.d.ts.map +1 -1
- package/script/src/clients/exchange.d.ts +136 -166
- package/script/src/clients/exchange.d.ts.map +1 -1
- package/script/src/clients/exchange.js +205 -230
- package/script/src/clients/multiSign.d.ts +121 -280
- package/script/src/clients/multiSign.d.ts.map +1 -1
- package/script/src/clients/multiSign.js +168 -291
- package/script/src/signing/_ethers.d.ts +33 -0
- package/script/src/signing/_ethers.d.ts.map +1 -0
- package/script/src/signing/_ethers.js +26 -0
- package/script/src/signing/_private_key.d.ts +22 -0
- package/script/src/signing/_private_key.d.ts.map +1 -0
- package/script/src/signing/_private_key.js +138 -0
- package/script/src/signing/_sorter.d.ts +154 -0
- package/script/src/signing/_sorter.d.ts.map +1 -0
- package/script/src/{signing.js → signing/_sorter.js} +1 -409
- package/script/src/signing/_viem.d.ts +23 -0
- package/script/src/signing/_viem.d.ts.map +1 -0
- package/script/src/signing/_viem.js +19 -0
- package/script/src/signing/_window.d.ts +23 -0
- package/script/src/signing/_window.d.ts.map +1 -0
- package/script/src/signing/_window.js +43 -0
- package/script/src/signing/mod.d.ts +251 -0
- package/script/src/signing/mod.d.ts.map +1 -0
- package/script/src/signing/mod.js +387 -0
- package/esm/src/signing.d.ts +0 -463
- package/esm/src/signing.d.ts.map +0 -1
- package/script/src/signing.d.ts +0 -463
- package/script/src/signing.d.ts.map +0 -1
|
@@ -1,423 +1,15 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This module contains functions for generating Hyperliquid transaction signatures
|
|
3
|
-
* and interfaces to various wallet implementations.
|
|
4
|
-
*
|
|
5
|
-
* @example
|
|
6
|
-
* ```ts
|
|
7
|
-
* import { signL1Action } from "@nktkas/hyperliquid/signing";
|
|
8
|
-
*
|
|
9
|
-
* const action = {
|
|
10
|
-
* type: "cancel",
|
|
11
|
-
* cancels: [{ a: 0, o: 12345 }],
|
|
12
|
-
* };
|
|
13
|
-
* const nonce = Date.now();
|
|
14
|
-
*
|
|
15
|
-
* const signature = await signL1Action({
|
|
16
|
-
* wallet,
|
|
17
|
-
* action,
|
|
18
|
-
* nonce,
|
|
19
|
-
* isTestnet: true, // Change to false for mainnet
|
|
20
|
-
* });
|
|
21
|
-
* ```
|
|
22
|
-
* @example
|
|
23
|
-
* ```ts
|
|
24
|
-
* import { signUserSignedAction } from "@nktkas/hyperliquid/signing";
|
|
25
|
-
*
|
|
26
|
-
* const action = {
|
|
27
|
-
* type: "approveAgent",
|
|
28
|
-
* hyperliquidChain: "Testnet", // "Mainnet" or "Testnet"
|
|
29
|
-
* signatureChainId: "0x66eee",
|
|
30
|
-
* nonce: Date.now(),
|
|
31
|
-
* agentAddress: "0x...",
|
|
32
|
-
* agentName: "Agent",
|
|
33
|
-
* };
|
|
34
|
-
*
|
|
35
|
-
* const signature = await signUserSignedAction({
|
|
36
|
-
* wallet,
|
|
37
|
-
* action,
|
|
38
|
-
* types: {
|
|
39
|
-
* "HyperliquidTransaction:ApproveAgent": [
|
|
40
|
-
* { name: "hyperliquidChain", type: "string" },
|
|
41
|
-
* { name: "agentAddress", type: "address" },
|
|
42
|
-
* { name: "agentName", type: "string" },
|
|
43
|
-
* { name: "nonce", type: "uint64" },
|
|
44
|
-
* ],
|
|
45
|
-
* },
|
|
46
|
-
* chainId: parseInt(action.signatureChainId, 16),
|
|
47
|
-
* });
|
|
48
|
-
* ```
|
|
49
|
-
*
|
|
50
|
-
* @module
|
|
51
|
-
*/
|
|
52
1
|
(function (factory) {
|
|
53
2
|
if (typeof module === "object" && typeof module.exports === "object") {
|
|
54
3
|
var v = factory(require, exports);
|
|
55
4
|
if (v !== undefined) module.exports = v;
|
|
56
5
|
}
|
|
57
6
|
else if (typeof define === "function" && define.amd) {
|
|
58
|
-
define(["require", "exports"
|
|
7
|
+
define(["require", "exports"], factory);
|
|
59
8
|
}
|
|
60
9
|
})(function (require, exports) {
|
|
61
10
|
"use strict";
|
|
62
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
63
12
|
exports.userSignedActionEip712Types = exports.actionSorter = void 0;
|
|
64
|
-
exports.createL1ActionHash = createL1ActionHash;
|
|
65
|
-
exports.signL1Action = signL1Action;
|
|
66
|
-
exports.signUserSignedAction = signUserSignedAction;
|
|
67
|
-
exports.signMultiSigAction = signMultiSigAction;
|
|
68
|
-
exports.isAbstractViemWalletClient = isAbstractViemWalletClient;
|
|
69
|
-
exports.isAbstractEthersSigner = isAbstractEthersSigner;
|
|
70
|
-
exports.isAbstractEthersV5Signer = isAbstractEthersV5Signer;
|
|
71
|
-
exports.isAbstractWindowEthereum = isAbstractWindowEthereum;
|
|
72
|
-
const sha3_1 = require("@noble/hashes/sha3");
|
|
73
|
-
const encode_js_1 = require("../deps/jsr.io/@std/msgpack/1.0.3/encode.js");
|
|
74
|
-
const hex_js_1 = require("../deps/jsr.io/@std/encoding/1.0.10/hex.js");
|
|
75
|
-
const concat_js_1 = require("../deps/jsr.io/@std/bytes/1.0.6/concat.js");
|
|
76
|
-
/**
|
|
77
|
-
* Create a hash of the L1 action.
|
|
78
|
-
*
|
|
79
|
-
* Note: Hash generation depends on the order of the action keys.
|
|
80
|
-
* @param action - The action to be hashed.
|
|
81
|
-
* @param nonce - Unique request identifier (recommended current timestamp in ms).
|
|
82
|
-
* @param vaultAddress - Optional vault address used in the action.
|
|
83
|
-
* @param expiresAfter - Optional expiration time of the action in milliseconds since the epoch.
|
|
84
|
-
* @returns The hash of the action.
|
|
85
|
-
*/
|
|
86
|
-
function createL1ActionHash(action, nonce, vaultAddress, expiresAfter) {
|
|
87
|
-
// 1. Action
|
|
88
|
-
const actionBytes = (0, encode_js_1.encode)(normalizeIntegersForMsgPack(action));
|
|
89
|
-
// 2. Nonce
|
|
90
|
-
const nonceBytes = new Uint8Array(8);
|
|
91
|
-
new DataView(nonceBytes.buffer).setBigUint64(0, BigInt(nonce));
|
|
92
|
-
// 3. Vault address
|
|
93
|
-
let vaultMarker;
|
|
94
|
-
let vaultBytes;
|
|
95
|
-
if (vaultAddress) {
|
|
96
|
-
vaultMarker = Uint8Array.of(1);
|
|
97
|
-
vaultBytes = (0, hex_js_1.decodeHex)(vaultAddress.slice(2));
|
|
98
|
-
}
|
|
99
|
-
else {
|
|
100
|
-
vaultMarker = new Uint8Array(1);
|
|
101
|
-
vaultBytes = new Uint8Array();
|
|
102
|
-
}
|
|
103
|
-
// 4. Expires after
|
|
104
|
-
let expiresMarker;
|
|
105
|
-
let expiresBytes;
|
|
106
|
-
if (expiresAfter !== undefined) {
|
|
107
|
-
expiresMarker = new Uint8Array(1);
|
|
108
|
-
expiresBytes = new Uint8Array(8);
|
|
109
|
-
new DataView(expiresBytes.buffer).setBigUint64(0, BigInt(expiresAfter));
|
|
110
|
-
}
|
|
111
|
-
else {
|
|
112
|
-
expiresMarker = new Uint8Array();
|
|
113
|
-
expiresBytes = new Uint8Array();
|
|
114
|
-
}
|
|
115
|
-
// Create a keccak256 hash
|
|
116
|
-
const chunks = [
|
|
117
|
-
actionBytes,
|
|
118
|
-
nonceBytes,
|
|
119
|
-
vaultMarker,
|
|
120
|
-
vaultBytes,
|
|
121
|
-
expiresMarker,
|
|
122
|
-
expiresBytes,
|
|
123
|
-
];
|
|
124
|
-
const bytes = (0, concat_js_1.concat)(chunks);
|
|
125
|
-
const hash = (0, sha3_1.keccak_256)(bytes);
|
|
126
|
-
return `0x${(0, hex_js_1.encodeHex)(hash)}`;
|
|
127
|
-
}
|
|
128
|
-
/** Layer to make {@link https://jsr.io/@std/msgpack | @std/msgpack} compatible with {@link https://github.com/msgpack/msgpack-javascript | @msgpack/msgpack}. */
|
|
129
|
-
function normalizeIntegersForMsgPack(obj) {
|
|
130
|
-
const THIRTY_ONE_BITS = 2147483648;
|
|
131
|
-
const THIRTY_TWO_BITS = 4294967296;
|
|
132
|
-
if (typeof obj === "number" && Number.isInteger(obj) &&
|
|
133
|
-
obj <= Number.MAX_SAFE_INTEGER && obj >= Number.MIN_SAFE_INTEGER &&
|
|
134
|
-
(obj >= THIRTY_TWO_BITS || obj < -THIRTY_ONE_BITS)) {
|
|
135
|
-
return BigInt(obj);
|
|
136
|
-
}
|
|
137
|
-
if (Array.isArray(obj)) {
|
|
138
|
-
return obj.map(normalizeIntegersForMsgPack);
|
|
139
|
-
}
|
|
140
|
-
if (obj && typeof obj === "object" && obj !== null) {
|
|
141
|
-
return Object.fromEntries(Object.entries(obj).map(([key, value]) => [key, normalizeIntegersForMsgPack(value)]));
|
|
142
|
-
}
|
|
143
|
-
return obj;
|
|
144
|
-
}
|
|
145
|
-
/**
|
|
146
|
-
* Sign an L1 action.
|
|
147
|
-
*
|
|
148
|
-
* Note: Signature generation depends on the order of the action keys.
|
|
149
|
-
* @param args - Arguments for signing the action.
|
|
150
|
-
* @returns The signature components r, s, and v.
|
|
151
|
-
* @example
|
|
152
|
-
* ```ts
|
|
153
|
-
* import { signL1Action } from "@nktkas/hyperliquid/signing";
|
|
154
|
-
* import { privateKeyToAccount } from "viem/accounts";
|
|
155
|
-
*
|
|
156
|
-
* const wallet = privateKeyToAccount("0x..."); // Your private key
|
|
157
|
-
*
|
|
158
|
-
* const action = {
|
|
159
|
-
* type: "cancel",
|
|
160
|
-
* cancels: [
|
|
161
|
-
* { a: 0, o: 12345 }, // Asset index and order ID
|
|
162
|
-
* ],
|
|
163
|
-
* };
|
|
164
|
-
* const nonce = Date.now();
|
|
165
|
-
*
|
|
166
|
-
* const signature = await signL1Action({
|
|
167
|
-
* wallet,
|
|
168
|
-
* action,
|
|
169
|
-
* nonce,
|
|
170
|
-
* isTestnet: true, // Change to false for mainnet
|
|
171
|
-
* });
|
|
172
|
-
*
|
|
173
|
-
* const response = await fetch("https://api.hyperliquid-testnet.xyz/exchange", {
|
|
174
|
-
* method: "POST",
|
|
175
|
-
* headers: { "Content-Type": "application/json" },
|
|
176
|
-
* body: JSON.stringify({ action, signature, nonce }),
|
|
177
|
-
* });
|
|
178
|
-
* const body = await response.json();
|
|
179
|
-
* ```
|
|
180
|
-
*/
|
|
181
|
-
async function signL1Action(args) {
|
|
182
|
-
const { wallet, action, nonce, isTestnet = false, vaultAddress, expiresAfter, } = args;
|
|
183
|
-
const domain = {
|
|
184
|
-
name: "Exchange",
|
|
185
|
-
version: "1",
|
|
186
|
-
chainId: 1337,
|
|
187
|
-
verifyingContract: "0x0000000000000000000000000000000000000000",
|
|
188
|
-
};
|
|
189
|
-
const types = {
|
|
190
|
-
Agent: [
|
|
191
|
-
{ name: "source", type: "string" },
|
|
192
|
-
{ name: "connectionId", type: "bytes32" },
|
|
193
|
-
],
|
|
194
|
-
};
|
|
195
|
-
const actionHash = createL1ActionHash(action, nonce, vaultAddress, expiresAfter);
|
|
196
|
-
const message = {
|
|
197
|
-
source: isTestnet ? "b" : "a",
|
|
198
|
-
connectionId: actionHash,
|
|
199
|
-
};
|
|
200
|
-
const signature = await abstractSignTypedData({ wallet, domain, types, message });
|
|
201
|
-
return splitSignature(signature);
|
|
202
|
-
}
|
|
203
|
-
/**
|
|
204
|
-
* Sign a user-signed action.
|
|
205
|
-
*
|
|
206
|
-
* Note: Signature generation depends on the order of types.
|
|
207
|
-
*
|
|
208
|
-
* @param args - Arguments for signing the action.
|
|
209
|
-
* @returns The signature components r, s, and v.
|
|
210
|
-
* @example
|
|
211
|
-
* ```ts
|
|
212
|
-
* import { signUserSignedAction } from "@nktkas/hyperliquid/signing";
|
|
213
|
-
* import { privateKeyToAccount } from "viem/accounts";
|
|
214
|
-
*
|
|
215
|
-
* const wallet = privateKeyToAccount("0x..."); // Your private key
|
|
216
|
-
*
|
|
217
|
-
* const action = {
|
|
218
|
-
* type: "approveAgent",
|
|
219
|
-
* hyperliquidChain: "Testnet", // "Mainnet" or "Testnet"
|
|
220
|
-
* signatureChainId: "0x66eee",
|
|
221
|
-
* nonce: Date.now(),
|
|
222
|
-
* agentAddress: "0x...", // Change to your agent address
|
|
223
|
-
* agentName: "Agent",
|
|
224
|
-
* };
|
|
225
|
-
*
|
|
226
|
-
* const signature = await signUserSignedAction({
|
|
227
|
-
* wallet,
|
|
228
|
-
* action,
|
|
229
|
-
* types: {
|
|
230
|
-
* "HyperliquidTransaction:ApproveAgent": [
|
|
231
|
-
* { name: "hyperliquidChain", type: "string" },
|
|
232
|
-
* { name: "agentAddress", type: "address" },
|
|
233
|
-
* { name: "agentName", type: "string" },
|
|
234
|
-
* { name: "nonce", type: "uint64" },
|
|
235
|
-
* ],
|
|
236
|
-
* },
|
|
237
|
-
* chainId: parseInt(action.signatureChainId, 16),
|
|
238
|
-
* });
|
|
239
|
-
*
|
|
240
|
-
* const response = await fetch("https://api.hyperliquid-testnet.xyz/exchange", {
|
|
241
|
-
* method: "POST",
|
|
242
|
-
* headers: { "Content-Type": "application/json" },
|
|
243
|
-
* body: JSON.stringify({ action, signature, nonce: action.nonce }),
|
|
244
|
-
* });
|
|
245
|
-
* const body = await response.json();
|
|
246
|
-
* ```
|
|
247
|
-
*/
|
|
248
|
-
async function signUserSignedAction(args) {
|
|
249
|
-
const { wallet, action, types, chainId } = args;
|
|
250
|
-
const domain = {
|
|
251
|
-
name: "HyperliquidSignTransaction",
|
|
252
|
-
version: "1",
|
|
253
|
-
chainId,
|
|
254
|
-
verifyingContract: "0x0000000000000000000000000000000000000000",
|
|
255
|
-
};
|
|
256
|
-
const signature = await abstractSignTypedData({ wallet, domain, types, message: action });
|
|
257
|
-
return splitSignature(signature);
|
|
258
|
-
}
|
|
259
|
-
/**
|
|
260
|
-
* Sign a multi-signature action.
|
|
261
|
-
*
|
|
262
|
-
* Note: Signature generation depends on the order of the action keys.
|
|
263
|
-
*
|
|
264
|
-
* @param args - Arguments for signing the action.
|
|
265
|
-
* @returns The signature components r, s, and v.
|
|
266
|
-
* @example
|
|
267
|
-
* ```ts
|
|
268
|
-
* import { signL1Action, signMultiSigAction } from "@nktkas/hyperliquid/signing";
|
|
269
|
-
* import { privateKeyToAccount } from "viem/accounts";
|
|
270
|
-
*
|
|
271
|
-
* const wallet = privateKeyToAccount("0x..."); // Your private key
|
|
272
|
-
* const multiSigUser = "0x..."; // Multi-sig user address
|
|
273
|
-
*
|
|
274
|
-
* const nonce = Date.now();
|
|
275
|
-
* const action = { // Example action
|
|
276
|
-
* type: "scheduleCancel",
|
|
277
|
-
* time: Date.now() + 10000
|
|
278
|
-
* };
|
|
279
|
-
*
|
|
280
|
-
* // First, create signature from one of the authorized signers
|
|
281
|
-
* const signature = await signL1Action({
|
|
282
|
-
* wallet,
|
|
283
|
-
* action: [multiSigUser.toLowerCase(), wallet.address.toLowerCase(), action],
|
|
284
|
-
* nonce,
|
|
285
|
-
* isTestnet: true,
|
|
286
|
-
* });
|
|
287
|
-
*
|
|
288
|
-
* // Then use it in the multi-sig action
|
|
289
|
-
* const multiSigSignature = await signMultiSigAction({
|
|
290
|
-
* wallet,
|
|
291
|
-
* action: {
|
|
292
|
-
* type: "multiSig",
|
|
293
|
-
* signatureChainId: "0x66eee",
|
|
294
|
-
* signatures: [signature],
|
|
295
|
-
* payload: {
|
|
296
|
-
* multiSigUser,
|
|
297
|
-
* outerSigner: wallet.address,
|
|
298
|
-
* action,
|
|
299
|
-
* }
|
|
300
|
-
* },
|
|
301
|
-
* nonce,
|
|
302
|
-
* hyperliquidChain: "Testnet",
|
|
303
|
-
* signatureChainId: "0x66eee",
|
|
304
|
-
* });
|
|
305
|
-
* ```
|
|
306
|
-
*/
|
|
307
|
-
async function signMultiSigAction(args) {
|
|
308
|
-
const { wallet, action, nonce, hyperliquidChain, signatureChainId, vaultAddress, expiresAfter, } = args;
|
|
309
|
-
const multiSigActionHash = createL1ActionHash(action, nonce, vaultAddress, expiresAfter);
|
|
310
|
-
const message = {
|
|
311
|
-
multiSigActionHash,
|
|
312
|
-
hyperliquidChain,
|
|
313
|
-
signatureChainId,
|
|
314
|
-
nonce,
|
|
315
|
-
};
|
|
316
|
-
return await signUserSignedAction({
|
|
317
|
-
wallet,
|
|
318
|
-
action: message,
|
|
319
|
-
types: {
|
|
320
|
-
"HyperliquidTransaction:SendMultiSig": [
|
|
321
|
-
{ name: "hyperliquidChain", type: "string" },
|
|
322
|
-
{ name: "multiSigActionHash", type: "bytes32" },
|
|
323
|
-
{ name: "nonce", type: "uint64" },
|
|
324
|
-
],
|
|
325
|
-
},
|
|
326
|
-
chainId: parseInt(signatureChainId, 16),
|
|
327
|
-
});
|
|
328
|
-
}
|
|
329
|
-
/** Signs typed data with the provided wallet using EIP-712. */
|
|
330
|
-
async function abstractSignTypedData(args) {
|
|
331
|
-
const { wallet, domain, types, message } = args;
|
|
332
|
-
if (isAbstractViemWalletClient(wallet)) {
|
|
333
|
-
return await wallet.signTypedData({
|
|
334
|
-
domain,
|
|
335
|
-
types: {
|
|
336
|
-
EIP712Domain: [
|
|
337
|
-
{ name: "name", type: "string" },
|
|
338
|
-
{ name: "version", type: "string" },
|
|
339
|
-
{ name: "chainId", type: "uint256" },
|
|
340
|
-
{ name: "verifyingContract", type: "address" },
|
|
341
|
-
],
|
|
342
|
-
...types,
|
|
343
|
-
},
|
|
344
|
-
primaryType: Object.keys(types)[0],
|
|
345
|
-
message,
|
|
346
|
-
});
|
|
347
|
-
}
|
|
348
|
-
else if (isAbstractEthersSigner(wallet)) {
|
|
349
|
-
return await wallet.signTypedData(domain, types, message);
|
|
350
|
-
}
|
|
351
|
-
else if (isAbstractEthersV5Signer(wallet)) {
|
|
352
|
-
return await wallet._signTypedData(domain, types, message);
|
|
353
|
-
}
|
|
354
|
-
else if (isAbstractWindowEthereum(wallet)) {
|
|
355
|
-
return await signTypedDataWithWindowEthereum(wallet, domain, types, message);
|
|
356
|
-
}
|
|
357
|
-
else {
|
|
358
|
-
throw new Error("Unsupported wallet for signing typed data");
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
/** Signs typed data using `window.ethereum` (EIP-1193) with `eth_signTypedData_v4` (EIP-712). */
|
|
362
|
-
async function signTypedDataWithWindowEthereum(ethereum, domain, types, message) {
|
|
363
|
-
const accounts = await ethereum.request({
|
|
364
|
-
method: "eth_requestAccounts",
|
|
365
|
-
params: [],
|
|
366
|
-
});
|
|
367
|
-
if (!Array.isArray(accounts) || accounts.length === 0) {
|
|
368
|
-
throw new Error("No Ethereum accounts available");
|
|
369
|
-
}
|
|
370
|
-
const from = accounts[0];
|
|
371
|
-
const dataToSign = JSON.stringify({
|
|
372
|
-
domain,
|
|
373
|
-
types: {
|
|
374
|
-
EIP712Domain: [
|
|
375
|
-
{ name: "name", type: "string" },
|
|
376
|
-
{ name: "version", type: "string" },
|
|
377
|
-
{ name: "chainId", type: "uint256" },
|
|
378
|
-
{ name: "verifyingContract", type: "address" },
|
|
379
|
-
],
|
|
380
|
-
...types,
|
|
381
|
-
},
|
|
382
|
-
primaryType: Object.keys(types)[0],
|
|
383
|
-
message,
|
|
384
|
-
});
|
|
385
|
-
return await ethereum.request({
|
|
386
|
-
method: "eth_signTypedData_v4",
|
|
387
|
-
params: [from, dataToSign],
|
|
388
|
-
});
|
|
389
|
-
}
|
|
390
|
-
/** Splits a signature hexadecimal string into its components. */
|
|
391
|
-
function splitSignature(signature) {
|
|
392
|
-
const r = `0x${signature.slice(2, 66)}`;
|
|
393
|
-
const s = `0x${signature.slice(66, 130)}`;
|
|
394
|
-
const v = parseInt(signature.slice(130, 132), 16);
|
|
395
|
-
return { r, s, v };
|
|
396
|
-
}
|
|
397
|
-
/** Checks if the given value is an abstract viem wallet. */
|
|
398
|
-
function isAbstractViemWalletClient(client) {
|
|
399
|
-
return typeof client === "object" && client !== null &&
|
|
400
|
-
"signTypedData" in client && typeof client.signTypedData === "function" &&
|
|
401
|
-
(client.signTypedData.length === 1 || client.signTypedData.length === 2);
|
|
402
|
-
}
|
|
403
|
-
/** Checks if the given value is an abstract ethers signer. */
|
|
404
|
-
function isAbstractEthersSigner(client) {
|
|
405
|
-
return typeof client === "object" && client !== null &&
|
|
406
|
-
"signTypedData" in client && typeof client.signTypedData === "function" &&
|
|
407
|
-
client.signTypedData.length === 3;
|
|
408
|
-
}
|
|
409
|
-
/** Checks if the given value is an abstract ethers v5 signer. */
|
|
410
|
-
function isAbstractEthersV5Signer(client) {
|
|
411
|
-
return typeof client === "object" && client !== null &&
|
|
412
|
-
"_signTypedData" in client && typeof client._signTypedData === "function" &&
|
|
413
|
-
client._signTypedData.length === 3;
|
|
414
|
-
}
|
|
415
|
-
/** Checks if the given value is an abstract `window.ethereum` object. */
|
|
416
|
-
function isAbstractWindowEthereum(client) {
|
|
417
|
-
return typeof client === "object" && client !== null &&
|
|
418
|
-
"request" in client && typeof client.request === "function" &&
|
|
419
|
-
client.request.length >= 1;
|
|
420
|
-
}
|
|
421
13
|
/** Action sorter for correct signature generation. */
|
|
422
14
|
exports.actionSorter = {
|
|
423
15
|
/** Sorts and formats an `approveAgent` action. */
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Hex } from "../base.js";
|
|
2
|
+
/** Abstract interface for a [viem wallet](https://viem.sh/docs/clients/wallet). */
|
|
3
|
+
export interface AbstractViemWalletClient {
|
|
4
|
+
signTypedData(params: {
|
|
5
|
+
domain: {
|
|
6
|
+
name: string;
|
|
7
|
+
version: string;
|
|
8
|
+
chainId: number;
|
|
9
|
+
verifyingContract: Hex;
|
|
10
|
+
};
|
|
11
|
+
types: {
|
|
12
|
+
[key: string]: {
|
|
13
|
+
name: string;
|
|
14
|
+
type: string;
|
|
15
|
+
}[];
|
|
16
|
+
};
|
|
17
|
+
primaryType: string;
|
|
18
|
+
message: Record<string, unknown>;
|
|
19
|
+
}, options?: unknown): Promise<Hex>;
|
|
20
|
+
}
|
|
21
|
+
/** Checks if the given value is an abstract viem wallet. */
|
|
22
|
+
export declare function isAbstractViemWalletClient(client: unknown): client is AbstractViemWalletClient;
|
|
23
|
+
//# sourceMappingURL=_viem.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_viem.d.ts","sourceRoot":"","sources":["../../../src/src/signing/_viem.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAEtC,mFAAmF;AACnF,MAAM,WAAW,wBAAwB;IACrC,aAAa,CACT,MAAM,EAAE;QACJ,MAAM,EAAE;YACJ,IAAI,EAAE,MAAM,CAAC;YACb,OAAO,EAAE,MAAM,CAAC;YAChB,OAAO,EAAE,MAAM,CAAC;YAChB,iBAAiB,EAAE,GAAG,CAAC;SAC1B,CAAC;QACF,KAAK,EAAE;YACH,CAAC,GAAG,EAAE,MAAM,GAAG;gBACX,IAAI,EAAE,MAAM,CAAC;gBACb,IAAI,EAAE,MAAM,CAAC;aAChB,EAAE,CAAC;SACP,CAAC;QACF,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACpC,EACD,OAAO,CAAC,EAAE,OAAO,GAClB,OAAO,CAAC,GAAG,CAAC,CAAC;CACnB;AAED,4DAA4D;AAC5D,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,IAAI,wBAAwB,CAI9F"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
(function (factory) {
|
|
2
|
+
if (typeof module === "object" && typeof module.exports === "object") {
|
|
3
|
+
var v = factory(require, exports);
|
|
4
|
+
if (v !== undefined) module.exports = v;
|
|
5
|
+
}
|
|
6
|
+
else if (typeof define === "function" && define.amd) {
|
|
7
|
+
define(["require", "exports"], factory);
|
|
8
|
+
}
|
|
9
|
+
})(function (require, exports) {
|
|
10
|
+
"use strict";
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.isAbstractViemWalletClient = isAbstractViemWalletClient;
|
|
13
|
+
/** Checks if the given value is an abstract viem wallet. */
|
|
14
|
+
function isAbstractViemWalletClient(client) {
|
|
15
|
+
return typeof client === "object" && client !== null &&
|
|
16
|
+
"signTypedData" in client && typeof client.signTypedData === "function" &&
|
|
17
|
+
(client.signTypedData.length === 1 || client.signTypedData.length === 2);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Hex } from "../base.js";
|
|
2
|
+
/** Abstract interface for a [window.ethereum](https://eips.ethereum.org/EIPS/eip-1193) object. */
|
|
3
|
+
export interface AbstractWindowEthereum {
|
|
4
|
+
request(args: {
|
|
5
|
+
method: any;
|
|
6
|
+
params: any;
|
|
7
|
+
}): Promise<any>;
|
|
8
|
+
}
|
|
9
|
+
/** Signs typed data using `window.ethereum` (EIP-1193) with `eth_signTypedData_v4` (EIP-712). */
|
|
10
|
+
export declare function signTypedDataWithWindowEthereum(ethereum: AbstractWindowEthereum, domain: {
|
|
11
|
+
name: string;
|
|
12
|
+
version: string;
|
|
13
|
+
chainId: number;
|
|
14
|
+
verifyingContract: Hex;
|
|
15
|
+
}, types: {
|
|
16
|
+
[key: string]: {
|
|
17
|
+
name: string;
|
|
18
|
+
type: string;
|
|
19
|
+
}[];
|
|
20
|
+
}, message: Record<string, unknown>): Promise<Hex>;
|
|
21
|
+
/** Checks if the given value is an abstract `window.ethereum` object. */
|
|
22
|
+
export declare function isAbstractWindowEthereum(client: unknown): client is AbstractWindowEthereum;
|
|
23
|
+
//# sourceMappingURL=_window.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_window.d.ts","sourceRoot":"","sources":["../../../src/src/signing/_window.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAEtC,kGAAkG;AAClG,MAAM,WAAW,sBAAsB;IAEnC,OAAO,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,GAAG,CAAC;QAAC,MAAM,EAAE,GAAG,CAAA;KAAE,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;CAC7D;AAED,iGAAiG;AACjG,wBAAsB,+BAA+B,CACjD,QAAQ,EAAE,sBAAsB,EAChC,MAAM,EAAE;IACJ,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,GAAG,CAAC;CAC1B,EACD,KAAK,EAAE;IACH,CAAC,GAAG,EAAE,MAAM,GAAG;QACX,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;KAChB,EAAE,CAAC;CACP,EACD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,OAAO,CAAC,GAAG,CAAC,CAsBd;AAED,yEAAyE;AACzE,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,IAAI,sBAAsB,CAI1F"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
(function (factory) {
|
|
2
|
+
if (typeof module === "object" && typeof module.exports === "object") {
|
|
3
|
+
var v = factory(require, exports);
|
|
4
|
+
if (v !== undefined) module.exports = v;
|
|
5
|
+
}
|
|
6
|
+
else if (typeof define === "function" && define.amd) {
|
|
7
|
+
define(["require", "exports"], factory);
|
|
8
|
+
}
|
|
9
|
+
})(function (require, exports) {
|
|
10
|
+
"use strict";
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.signTypedDataWithWindowEthereum = signTypedDataWithWindowEthereum;
|
|
13
|
+
exports.isAbstractWindowEthereum = isAbstractWindowEthereum;
|
|
14
|
+
/** Signs typed data using `window.ethereum` (EIP-1193) with `eth_signTypedData_v4` (EIP-712). */
|
|
15
|
+
async function signTypedDataWithWindowEthereum(ethereum, domain, types, message) {
|
|
16
|
+
const accounts = await ethereum.request({ method: "eth_requestAccounts", params: [] });
|
|
17
|
+
if (!Array.isArray(accounts) || accounts.length === 0) {
|
|
18
|
+
throw new Error("No Ethereum accounts available");
|
|
19
|
+
}
|
|
20
|
+
const from = accounts[0];
|
|
21
|
+
const dataToSign = JSON.stringify({
|
|
22
|
+
domain,
|
|
23
|
+
types: {
|
|
24
|
+
EIP712Domain: [
|
|
25
|
+
{ name: "name", type: "string" },
|
|
26
|
+
{ name: "version", type: "string" },
|
|
27
|
+
{ name: "chainId", type: "uint256" },
|
|
28
|
+
{ name: "verifyingContract", type: "address" },
|
|
29
|
+
],
|
|
30
|
+
...types,
|
|
31
|
+
},
|
|
32
|
+
primaryType: Object.keys(types)[0],
|
|
33
|
+
message,
|
|
34
|
+
});
|
|
35
|
+
return await ethereum.request({ method: "eth_signTypedData_v4", params: [from, dataToSign] });
|
|
36
|
+
}
|
|
37
|
+
/** Checks if the given value is an abstract `window.ethereum` object. */
|
|
38
|
+
function isAbstractWindowEthereum(client) {
|
|
39
|
+
return typeof client === "object" && client !== null &&
|
|
40
|
+
"request" in client && typeof client.request === "function" &&
|
|
41
|
+
client.request.length >= 1;
|
|
42
|
+
}
|
|
43
|
+
});
|