@hfunlabs/hypurr-connect 0.1.10 → 0.1.12
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 +28 -1
- package/dist/index.d.ts +49 -2
- package/dist/index.js +179 -12
- package/dist/index.js.map +1 -1
- package/package.json +5 -4
- package/src/HypurrConnectProvider.tsx +194 -25
- package/src/agent.ts +2 -2
- package/src/index.ts +7 -0
- package/src/privateKeySigner.ts +32 -0
- package/src/types.ts +46 -0
package/README.md
CHANGED
|
@@ -119,6 +119,7 @@ function AppShell() {
|
|
|
119
119
|
```typescript
|
|
120
120
|
interface HypurrConnectConfig {
|
|
121
121
|
grpcUrl?: string; // gRPC-web base URL (default: https://grpc.hypurr.fun)
|
|
122
|
+
mediaUrl?: string; // Media base URL (default: https://media.hypurr.fun)
|
|
122
123
|
grpcTimeout?: number; // Request timeout in ms (default: 15000)
|
|
123
124
|
isTestnet?: boolean; // Use testnet endpoints (default: false)
|
|
124
125
|
telegram: {
|
|
@@ -219,6 +220,24 @@ connectEoa(address); // no signer — only L1 actions after manual approval
|
|
|
219
220
|
await approveAgent(signTypedDataAsync, chainId);
|
|
220
221
|
```
|
|
221
222
|
|
|
223
|
+
### EVM Transaction Signing
|
|
224
|
+
|
|
225
|
+
`signEvmTransaction(transaction)` signs a JSON-RPC-style EVM transaction and returns the raw serialized transaction. In Telegram mode it calls the `EVMSignTransaction` gRPC endpoint for the selected private-key wallet; in EOA mode it calls the `signTransaction` or EIP-1193 `request` function supplied to `connectEoa`.
|
|
226
|
+
|
|
227
|
+
```tsx
|
|
228
|
+
const { signEvmTransaction } = useHypurrConnect();
|
|
229
|
+
|
|
230
|
+
const raw = await signEvmTransaction({
|
|
231
|
+
to: "0x0000000000000000000000000000000000000000",
|
|
232
|
+
data: "0x",
|
|
233
|
+
value: "0x0",
|
|
234
|
+
chainId: "0x66eee",
|
|
235
|
+
nonce: "0x1",
|
|
236
|
+
gas: "0x5208",
|
|
237
|
+
gasPrice: "0x3b9aca00",
|
|
238
|
+
});
|
|
239
|
+
```
|
|
240
|
+
|
|
222
241
|
### Using the Exchange Client
|
|
223
242
|
|
|
224
243
|
Once authenticated, the `exchange` object from `useHypurrConnect()` is a fully functional `ExchangeClient` from `@hfunlabs/hyperliquid`. For EOA users with a signer, it handles **both** L1 and user-signed actions transparently:
|
|
@@ -380,6 +399,7 @@ Returns the full auth and exchange state. Throws if used outside `HypurrConnectP
|
|
|
380
399
|
| `openLoginModal` | `() => void` | Show the login modal |
|
|
381
400
|
| `closeLoginModal` | `() => void` | Hide the login modal |
|
|
382
401
|
| `connectEoa` | `(address: \`0x\${string}\`, signer?: EoaSigner) => void` | Connect EOA wallet (sync); pass signer to enable user-signed actions and auto-provisioning |
|
|
402
|
+
| `signEvmTransaction` | `(transaction: EvmTransactionRequest) => Promise<\`0x\${string}\`>` | Sign an EVM transaction through EOA wallet provider or Telegram RPC |
|
|
383
403
|
| `approveAgent` | `(signTypedDataAsync: SignTypedDataFn, chainId: number) => Promise<void>` | Approve a named agent key (async, triggers wallet prompt) |
|
|
384
404
|
| `logout` | `() => void` | Clear all auth state and localStorage |
|
|
385
405
|
| `agent` | `StoredAgent \| null` | Current agent key (EOA flow only) |
|
|
@@ -472,11 +492,13 @@ Encapsulates the master wallet's EIP-712 signing function and chain ID. Pass to
|
|
|
472
492
|
```typescript
|
|
473
493
|
interface EoaSigner {
|
|
474
494
|
signTypedData: SignTypedDataFn;
|
|
495
|
+
signTransaction?: (transaction: EvmTransactionRequest) => Promise<unknown>;
|
|
496
|
+
request?: (args: { method: string; params?: unknown[] }) => Promise<unknown>;
|
|
475
497
|
chainId: number;
|
|
476
498
|
}
|
|
477
499
|
```
|
|
478
500
|
|
|
479
|
-
#### `createEoaSigner(signTypedData, chainId): EoaSigner`
|
|
501
|
+
#### `createEoaSigner(signTypedData, chainId, options?): EoaSigner`
|
|
480
502
|
|
|
481
503
|
Helper to create an `EoaSigner` from wagmi's `signTypedDataAsync` (or any compatible function). Accepts either a direct function or a `{ current: Function }` ref to avoid stale closures with React hooks:
|
|
482
504
|
|
|
@@ -488,6 +510,11 @@ const signer = createEoaSigner(signerRef, chainId);
|
|
|
488
510
|
|
|
489
511
|
// With a direct function (fine for stable references)
|
|
490
512
|
const signer = createEoaSigner(signTypedDataAsync, chainId);
|
|
513
|
+
|
|
514
|
+
// With an EIP-1193 provider for EVM transaction signing
|
|
515
|
+
const signer = createEoaSigner(signTypedDataAsync, chainId, {
|
|
516
|
+
request: provider.request.bind(provider),
|
|
517
|
+
});
|
|
491
518
|
```
|
|
492
519
|
|
|
493
520
|
#### `SignTypedDataFn`
|
package/dist/index.d.ts
CHANGED
|
@@ -11,10 +11,13 @@ import { TelegramChatWalletPack } from 'hypurr-grpc/ts/hypurr/user';
|
|
|
11
11
|
export { TelegramChatWalletPack } from 'hypurr-grpc/ts/hypurr/user';
|
|
12
12
|
import { HyperliquidWallet } from 'hypurr-grpc/ts/hypurr/wallet';
|
|
13
13
|
export { HyperliquidWallet } from 'hypurr-grpc/ts/hypurr/wallet';
|
|
14
|
+
import { AbstractViemLocalAccount } from '@hfunlabs/hyperliquid/signing';
|
|
14
15
|
|
|
15
16
|
interface HypurrConnectConfig {
|
|
16
17
|
/** gRPC-web base URL. Defaults to https://grpc.hypurr.fun. */
|
|
17
18
|
grpcUrl?: string;
|
|
19
|
+
/** Media base URL for user-uploaded assets. Defaults to https://media.hypurr.fun. */
|
|
20
|
+
mediaUrl?: string;
|
|
18
21
|
grpcTimeout?: number;
|
|
19
22
|
isTestnet?: boolean;
|
|
20
23
|
/** Polling interval in ms for TWAP/Scale session updates. Default 5000. Set 0 to disable. */
|
|
@@ -71,11 +74,41 @@ type SignTypedDataFn = (params: {
|
|
|
71
74
|
primaryType: string;
|
|
72
75
|
message: Record<string, unknown>;
|
|
73
76
|
}) => Promise<`0x${string}`>;
|
|
77
|
+
type Hex = `0x${string}`;
|
|
78
|
+
interface EvmTransactionRequest {
|
|
79
|
+
from?: Hex;
|
|
80
|
+
to?: Hex;
|
|
81
|
+
gas?: Hex;
|
|
82
|
+
gasPrice?: Hex;
|
|
83
|
+
value?: Hex;
|
|
84
|
+
data?: Hex;
|
|
85
|
+
nonce?: Hex;
|
|
86
|
+
chainId?: Hex;
|
|
87
|
+
maxFeePerGas?: Hex;
|
|
88
|
+
maxPriorityFeePerGas?: Hex;
|
|
89
|
+
type?: Hex;
|
|
90
|
+
accessList?: unknown;
|
|
91
|
+
[key: string]: unknown;
|
|
92
|
+
}
|
|
93
|
+
type EvmRequestFn = (args: {
|
|
94
|
+
method: string;
|
|
95
|
+
params?: unknown[];
|
|
96
|
+
}) => Promise<unknown>;
|
|
97
|
+
type SignEvmTransactionFn = (transaction: EvmTransactionRequest) => Promise<Hex>;
|
|
98
|
+
type EoaSignTransactionFn = (transaction: EvmTransactionRequest) => Promise<unknown>;
|
|
74
99
|
/** Wallet signer provided at EOA connect time for user-signed actions. */
|
|
75
100
|
interface EoaSigner {
|
|
76
101
|
signTypedData: SignTypedDataFn;
|
|
102
|
+
/** Optional raw EVM transaction signer. Used by `signEvmTransaction()` in EOA mode. */
|
|
103
|
+
signTransaction?: EoaSignTransactionFn;
|
|
104
|
+
/** Optional EIP-1193 provider request function. Used as a fallback for `eth_signTransaction`. */
|
|
105
|
+
request?: EvmRequestFn;
|
|
77
106
|
chainId: number;
|
|
78
107
|
}
|
|
108
|
+
interface EoaSignerOptions {
|
|
109
|
+
signTransaction?: EoaSignTransactionFn;
|
|
110
|
+
request?: EvmRequestFn;
|
|
111
|
+
}
|
|
79
112
|
/**
|
|
80
113
|
* Create an {@link EoaSigner} from any EIP-712 signing function.
|
|
81
114
|
*
|
|
@@ -101,7 +134,7 @@ interface EoaSigner {
|
|
|
101
134
|
*/
|
|
102
135
|
declare function createEoaSigner(signTypedDataAsync: ((args: Record<string, unknown>) => Promise<`0x${string}`>) | {
|
|
103
136
|
current: (args: Record<string, unknown>) => Promise<`0x${string}`>;
|
|
104
|
-
}, chainId: number): EoaSigner;
|
|
137
|
+
}, chainId: number, options?: EoaSignerOptions): EoaSigner;
|
|
105
138
|
type TwapCreateParams = Omit<HyperliquidTwapCreateRequest, "authData" | "walletId">;
|
|
106
139
|
type TwapModifyParams = Omit<HyperliquidTwapModifyRequest, "authData" | "walletId">;
|
|
107
140
|
type ScaleCreateParams = Omit<HyperliquidScaleCreateRequest, "authData" | "walletId">;
|
|
@@ -143,6 +176,7 @@ interface HypurrConnectState {
|
|
|
143
176
|
openLoginModal: () => void;
|
|
144
177
|
closeLoginModal: () => void;
|
|
145
178
|
connectEoa: (address: `0x${string}`, signer?: EoaSigner) => void;
|
|
179
|
+
signEvmTransaction: SignEvmTransactionFn;
|
|
146
180
|
approveAgent: (signTypedDataAsync: SignTypedDataFn, chainId: number) => Promise<void>;
|
|
147
181
|
logout: () => void;
|
|
148
182
|
agent: StoredAgent | null;
|
|
@@ -199,4 +233,17 @@ declare class GrpcExchangeTransport implements IRequestTransport {
|
|
|
199
233
|
declare function createTelegramClient(config: HypurrConnectConfig): TelegramClient;
|
|
200
234
|
declare function createStaticClient(config: HypurrConnectConfig): StaticClient;
|
|
201
235
|
|
|
202
|
-
|
|
236
|
+
type SignTypedDataParams = Parameters<AbstractViemLocalAccount["signTypedData"]>[0];
|
|
237
|
+
/**
|
|
238
|
+
* Compatibility wrapper for SDK versions that removed PrivateKeySigner.
|
|
239
|
+
*
|
|
240
|
+
* It exposes the viem local-account shape accepted by the Hyperliquid SDK.
|
|
241
|
+
*/
|
|
242
|
+
declare class PrivateKeySigner implements AbstractViemLocalAccount {
|
|
243
|
+
#private;
|
|
244
|
+
readonly address: Hex;
|
|
245
|
+
constructor(privateKey: string);
|
|
246
|
+
signTypedData(params: SignTypedDataParams): Promise<Hex>;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
export { type AuthMethod, type EoaSignTransactionFn, type EoaSigner, type EoaSignerOptions, type EvmRequestFn, type EvmTransactionRequest, GrpcExchangeTransport, type GrpcExchangeTransportConfig, type Hex, type HypurrConnectConfig, HypurrConnectProvider, type HypurrConnectState, type HypurrUser, LoginModal, type LoginModalProps, PrivateKeySigner, type ScaleCreateParams, type SignEvmTransactionFn, type SignTypedDataFn, type StoredAgent, type TelegramLoginData, type TwapCreateParams, type TwapModifyParams, createEoaSigner, createStaticClient, createTelegramClient, useHypurrConnect };
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,6 @@ import {
|
|
|
4
4
|
HttpTransport
|
|
5
5
|
} from "@hfunlabs/hyperliquid";
|
|
6
6
|
import {
|
|
7
|
-
PrivateKeySigner,
|
|
8
7
|
signUserSignedAction
|
|
9
8
|
} from "@hfunlabs/hyperliquid/signing";
|
|
10
9
|
import {
|
|
@@ -17,6 +16,25 @@ import {
|
|
|
17
16
|
useState
|
|
18
17
|
} from "react";
|
|
19
18
|
|
|
19
|
+
// src/privateKeySigner.ts
|
|
20
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
21
|
+
var PrivateKeySigner = class {
|
|
22
|
+
#account;
|
|
23
|
+
address;
|
|
24
|
+
constructor(privateKey) {
|
|
25
|
+
this.#account = privateKeyToAccount(normalizePrivateKey(privateKey));
|
|
26
|
+
this.address = this.#account.address;
|
|
27
|
+
}
|
|
28
|
+
signTypedData(params) {
|
|
29
|
+
return this.#account.signTypedData(
|
|
30
|
+
params
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
function normalizePrivateKey(privateKey) {
|
|
35
|
+
return privateKey.startsWith("0x") ? privateKey : `0x${privateKey}`;
|
|
36
|
+
}
|
|
37
|
+
|
|
20
38
|
// src/agent.ts
|
|
21
39
|
var AGENT_NAME = "hypurr-connect";
|
|
22
40
|
var AGENT_STORAGE_PREFIX = "hypurr-connect-agent";
|
|
@@ -41,8 +59,7 @@ async function generateAgentKey() {
|
|
|
41
59
|
const bytes = crypto.getRandomValues(new Uint8Array(32));
|
|
42
60
|
const hex = Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
43
61
|
const privateKey = `0x${hex}`;
|
|
44
|
-
const
|
|
45
|
-
const signer = new PrivateKeySigner2(privateKey);
|
|
62
|
+
const signer = new PrivateKeySigner(privateKey);
|
|
46
63
|
return { privateKey, address: signer.address };
|
|
47
64
|
}
|
|
48
65
|
async function fetchActiveAgent(userAddress, isTestnet) {
|
|
@@ -186,7 +203,9 @@ var TELEGRAM_STORAGE_KEY = "hypurr-connect-tg-jwt";
|
|
|
186
203
|
var LEGACY_TELEGRAM_STORAGE_KEY = "hypurr-connect-tg-user";
|
|
187
204
|
var TELEGRAM_AUTH_STATE_KEY = "hypurr-connect-auth-state";
|
|
188
205
|
var TELEGRAM_AUTH_MESSAGE = "hypurr-connect:telegram-auth";
|
|
189
|
-
var DEFAULT_AUTH_HUB_URL = "https://
|
|
206
|
+
var DEFAULT_AUTH_HUB_URL = "https://auth.hypurr.fun/login";
|
|
207
|
+
var DEFAULT_MEDIA_URL = "https://media.hypurr.fun";
|
|
208
|
+
var IGNORED_EXTERNAL_SIGNATURE = "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001b";
|
|
190
209
|
var DEFAULT_TELEGRAM_SCOPES = [
|
|
191
210
|
"telegram:user:read",
|
|
192
211
|
"telegram:wallet:read",
|
|
@@ -195,14 +214,69 @@ var DEFAULT_TELEGRAM_SCOPES = [
|
|
|
195
214
|
"telegram:trade:write",
|
|
196
215
|
"telegram:cabal:read",
|
|
197
216
|
"telegram:cabal:write",
|
|
198
|
-
"telegram:agent:write"
|
|
217
|
+
"telegram:agent:write",
|
|
218
|
+
"telegram:support:read",
|
|
219
|
+
"telegram:support:write"
|
|
199
220
|
];
|
|
221
|
+
function createExternalSigningWallet(address) {
|
|
222
|
+
return {
|
|
223
|
+
address,
|
|
224
|
+
signTypedData(params) {
|
|
225
|
+
void params;
|
|
226
|
+
return Promise.resolve(IGNORED_EXTERNAL_SIGNATURE);
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
}
|
|
200
230
|
function isInvalidTelegramAuthError(err) {
|
|
201
231
|
const msg = err instanceof Error ? err.message : typeof err === "object" && err !== null && "message" in err ? String(err.message) : String(err);
|
|
202
232
|
return /invalid telegram auth data|invalid auth token|missing authorization token/i.test(
|
|
203
233
|
msg
|
|
204
234
|
);
|
|
205
235
|
}
|
|
236
|
+
function normalizeMediaUrl(mediaUrl) {
|
|
237
|
+
return (mediaUrl?.trim() || DEFAULT_MEDIA_URL).replace(/\/+$/, "");
|
|
238
|
+
}
|
|
239
|
+
function isAddress(value) {
|
|
240
|
+
return !!value && /^0x[a-fA-F0-9]{40}$/.test(value);
|
|
241
|
+
}
|
|
242
|
+
function getRawSignedTransaction(result) {
|
|
243
|
+
if (typeof result === "string" && result.startsWith("0x")) {
|
|
244
|
+
return result;
|
|
245
|
+
}
|
|
246
|
+
if (!result || typeof result !== "object") return null;
|
|
247
|
+
const record = result;
|
|
248
|
+
const candidates = [
|
|
249
|
+
record.raw,
|
|
250
|
+
record.rawTransaction,
|
|
251
|
+
record.signedTransaction,
|
|
252
|
+
record.serializedTransaction,
|
|
253
|
+
record.result
|
|
254
|
+
];
|
|
255
|
+
const raw = candidates.find(
|
|
256
|
+
(value) => typeof value === "string" && value.startsWith("0x")
|
|
257
|
+
);
|
|
258
|
+
return raw ? raw : null;
|
|
259
|
+
}
|
|
260
|
+
function decodeJsonBytes(bytes) {
|
|
261
|
+
const text = new TextDecoder().decode(bytes);
|
|
262
|
+
if (!text) return null;
|
|
263
|
+
try {
|
|
264
|
+
return JSON.parse(text);
|
|
265
|
+
} catch {
|
|
266
|
+
return text;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
function encodeJsonBytes(value) {
|
|
270
|
+
return new TextEncoder().encode(JSON.stringify(value));
|
|
271
|
+
}
|
|
272
|
+
function withExpectedFrom(transaction, address) {
|
|
273
|
+
if (transaction.from && transaction.from.toLowerCase() !== address.toLowerCase()) {
|
|
274
|
+
throw new Error(
|
|
275
|
+
"[HypurrConnect] EVM transaction `from` does not match the connected wallet."
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
return transaction.from ? transaction : { ...transaction, from: address };
|
|
279
|
+
}
|
|
206
280
|
function currentReturnTo() {
|
|
207
281
|
const url = new URL(window.location.href);
|
|
208
282
|
for (const param of [
|
|
@@ -465,10 +539,12 @@ function HypurrConnectProvider({
|
|
|
465
539
|
]);
|
|
466
540
|
const user = useMemo(() => {
|
|
467
541
|
if (tgAuthToken && authMethod === "telegram" && selectedWallet && tgUser) {
|
|
542
|
+
const mediaUrl = normalizeMediaUrl(config.mediaUrl);
|
|
468
543
|
return {
|
|
469
544
|
address: selectedWallet.ethereumAddress,
|
|
470
545
|
walletId: selectedWallet.id,
|
|
471
546
|
displayName: tgUser.telegramUsername ? `@${tgUser.telegramUsername}` : `Telegram ${tgUser.telegramId}`,
|
|
547
|
+
photoUrl: tgUser.pictureFileId ? `${mediaUrl}/${tgUser.pictureFileId}` : void 0,
|
|
472
548
|
authMethod: "telegram",
|
|
473
549
|
telegramId: String(tgUser.telegramId),
|
|
474
550
|
hfunScore: tgUser?.reputation?.hfunScore,
|
|
@@ -484,7 +560,14 @@ function HypurrConnectProvider({
|
|
|
484
560
|
};
|
|
485
561
|
}
|
|
486
562
|
return null;
|
|
487
|
-
}, [
|
|
563
|
+
}, [
|
|
564
|
+
tgAuthToken,
|
|
565
|
+
selectedWallet,
|
|
566
|
+
eoaAddress,
|
|
567
|
+
authMethod,
|
|
568
|
+
tgUser,
|
|
569
|
+
config.mediaUrl
|
|
570
|
+
]);
|
|
488
571
|
const onDeadAgentRef = useRef(
|
|
489
572
|
null
|
|
490
573
|
);
|
|
@@ -512,8 +595,7 @@ function HypurrConnectProvider({
|
|
|
512
595
|
});
|
|
513
596
|
return new ExchangeClient({
|
|
514
597
|
transport,
|
|
515
|
-
|
|
516
|
-
userAddress: user.address
|
|
598
|
+
wallet: createExternalSigningWallet(user.address)
|
|
517
599
|
});
|
|
518
600
|
}
|
|
519
601
|
if (authMethod === "eoa" && eoaAddress) {
|
|
@@ -529,8 +611,7 @@ function HypurrConnectProvider({
|
|
|
529
611
|
};
|
|
530
612
|
return new ExchangeClient({
|
|
531
613
|
transport: noAgentTransport,
|
|
532
|
-
|
|
533
|
-
userAddress: eoaAddress
|
|
614
|
+
wallet: createExternalSigningWallet(eoaAddress)
|
|
534
615
|
});
|
|
535
616
|
}
|
|
536
617
|
const isTestnet = config.isTestnet ?? false;
|
|
@@ -671,6 +752,81 @@ function HypurrConnectProvider({
|
|
|
671
752
|
setAgent(null);
|
|
672
753
|
}
|
|
673
754
|
}, [eoaAddress]);
|
|
755
|
+
const signEvmTransaction = useCallback(
|
|
756
|
+
async (transaction) => {
|
|
757
|
+
if (authMethod === "eoa") {
|
|
758
|
+
if (!eoaAddress) {
|
|
759
|
+
throw new Error("[HypurrConnect] No EOA wallet connected.");
|
|
760
|
+
}
|
|
761
|
+
const signer = eoaSignerRef.current;
|
|
762
|
+
if (!signer) {
|
|
763
|
+
throw new Error(
|
|
764
|
+
"[HypurrConnect] No EOA signer available. Pass a signer to connectEoa(address, signer)."
|
|
765
|
+
);
|
|
766
|
+
}
|
|
767
|
+
const tx = withExpectedFrom(transaction, eoaAddress);
|
|
768
|
+
const result = signer.signTransaction ? await signer.signTransaction(tx) : signer.request ? await signer.request({
|
|
769
|
+
method: "eth_signTransaction",
|
|
770
|
+
params: [tx]
|
|
771
|
+
}) : null;
|
|
772
|
+
const rawTransaction = getRawSignedTransaction(result);
|
|
773
|
+
if (!rawTransaction) {
|
|
774
|
+
throw new Error(
|
|
775
|
+
"[HypurrConnect] EOA signer did not return a raw transaction."
|
|
776
|
+
);
|
|
777
|
+
}
|
|
778
|
+
return rawTransaction;
|
|
779
|
+
}
|
|
780
|
+
if (authMethod === "telegram") {
|
|
781
|
+
if (!telegramRpcOptions) {
|
|
782
|
+
throw new Error("[HypurrConnect] No Telegram RPC session available.");
|
|
783
|
+
}
|
|
784
|
+
if (!selectedWallet) {
|
|
785
|
+
throw new Error("[HypurrConnect] No Telegram wallet selected.");
|
|
786
|
+
}
|
|
787
|
+
if (selectedWallet.id <= 0 || selectedWallet.isReadOnly || selectedWallet.isAgent) {
|
|
788
|
+
throw new Error(
|
|
789
|
+
"[HypurrConnect] Select a Telegram private-key wallet to sign EVM transactions."
|
|
790
|
+
);
|
|
791
|
+
}
|
|
792
|
+
if (!isAddress(selectedWallet.ethereumAddress)) {
|
|
793
|
+
throw new Error(
|
|
794
|
+
"[HypurrConnect] Selected Telegram wallet does not have a valid EVM address."
|
|
795
|
+
);
|
|
796
|
+
}
|
|
797
|
+
const tx = withExpectedFrom(
|
|
798
|
+
transaction,
|
|
799
|
+
selectedWallet.ethereumAddress
|
|
800
|
+
);
|
|
801
|
+
try {
|
|
802
|
+
const signResponse = await tgClient.eVMSignTransaction(
|
|
803
|
+
{
|
|
804
|
+
authData: {},
|
|
805
|
+
walletId: selectedWallet.id,
|
|
806
|
+
params: encodeJsonBytes(tx)
|
|
807
|
+
},
|
|
808
|
+
telegramRpcOptions
|
|
809
|
+
);
|
|
810
|
+
const rawTransaction = getRawSignedTransaction(
|
|
811
|
+
decodeJsonBytes(signResponse.response.result)
|
|
812
|
+
);
|
|
813
|
+
if (!rawTransaction) {
|
|
814
|
+
throw new Error(
|
|
815
|
+
"[HypurrConnect] Telegram signer did not return a raw transaction."
|
|
816
|
+
);
|
|
817
|
+
}
|
|
818
|
+
return rawTransaction;
|
|
819
|
+
} catch (err) {
|
|
820
|
+
if (isInvalidTelegramAuthError(err)) {
|
|
821
|
+
onInvalidAuthRef.current?.();
|
|
822
|
+
}
|
|
823
|
+
throw err;
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
throw new Error("[HypurrConnect] No wallet connected.");
|
|
827
|
+
},
|
|
828
|
+
[authMethod, eoaAddress, selectedWallet, telegramRpcOptions, tgClient]
|
|
829
|
+
);
|
|
674
830
|
const createWallet = useCallback(
|
|
675
831
|
async (name) => {
|
|
676
832
|
const { response } = await tgClient.hyperliquidWalletCreate(
|
|
@@ -936,7 +1092,13 @@ function HypurrConnectProvider({
|
|
|
936
1092
|
"[HypurrConnect] Cannot approve agent: no EOA wallet connected. Call connectEoa(address) first."
|
|
937
1093
|
);
|
|
938
1094
|
}
|
|
939
|
-
eoaSignerRef.current
|
|
1095
|
+
const currentSigner = eoaSignerRef.current;
|
|
1096
|
+
eoaSignerRef.current = {
|
|
1097
|
+
signTypedData: signTypedDataAsync,
|
|
1098
|
+
signTransaction: currentSigner?.signTransaction,
|
|
1099
|
+
request: currentSigner?.request,
|
|
1100
|
+
chainId
|
|
1101
|
+
};
|
|
940
1102
|
setEoaLoading(true);
|
|
941
1103
|
setEoaError(null);
|
|
942
1104
|
try {
|
|
@@ -1055,6 +1217,7 @@ function HypurrConnectProvider({
|
|
|
1055
1217
|
closeLoginModal,
|
|
1056
1218
|
loginTelegram,
|
|
1057
1219
|
connectEoa,
|
|
1220
|
+
signEvmTransaction,
|
|
1058
1221
|
approveAgent: approveAgentFn,
|
|
1059
1222
|
logout,
|
|
1060
1223
|
agent,
|
|
@@ -1098,6 +1261,7 @@ function HypurrConnectProvider({
|
|
|
1098
1261
|
closeLoginModal,
|
|
1099
1262
|
loginTelegram,
|
|
1100
1263
|
connectEoa,
|
|
1264
|
+
signEvmTransaction,
|
|
1101
1265
|
approveAgentFn,
|
|
1102
1266
|
logout,
|
|
1103
1267
|
agent,
|
|
@@ -1520,10 +1684,12 @@ function MobileDrawer({
|
|
|
1520
1684
|
}
|
|
1521
1685
|
|
|
1522
1686
|
// src/types.ts
|
|
1523
|
-
function createEoaSigner(signTypedDataAsync, chainId) {
|
|
1687
|
+
function createEoaSigner(signTypedDataAsync, chainId, options = {}) {
|
|
1524
1688
|
const resolve = typeof signTypedDataAsync === "function" ? signTypedDataAsync : (args) => signTypedDataAsync.current(args);
|
|
1525
1689
|
return {
|
|
1526
1690
|
signTypedData: (params) => resolve(params),
|
|
1691
|
+
signTransaction: options.signTransaction,
|
|
1692
|
+
request: options.request,
|
|
1527
1693
|
chainId
|
|
1528
1694
|
};
|
|
1529
1695
|
}
|
|
@@ -1531,6 +1697,7 @@ export {
|
|
|
1531
1697
|
GrpcExchangeTransport,
|
|
1532
1698
|
HypurrConnectProvider,
|
|
1533
1699
|
LoginModal,
|
|
1700
|
+
PrivateKeySigner,
|
|
1534
1701
|
createEoaSigner,
|
|
1535
1702
|
createStaticClient,
|
|
1536
1703
|
createTelegramClient,
|