@meshconnect/uwc-types 0.14.0-snapshot.6b75329 → 0.15.0

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.
@@ -2,7 +2,7 @@ import type { Network, NetworkId, Namespace } from './networks';
2
2
  import type { AvailableAddress } from './session';
3
3
  import type { DetectedEIP6963WalletInfo, DetectedSolanaWalletInfo, DetectedTronWalletInfo, DetectedTonWalletInfo, ExtensionInjectedProvider, IntegratedBrowserInjectedProvider, WalletConnectProvider, TonConnectWalletProvider, WalletMetadata } from './UWC-state';
4
4
  import type { EVMCapabilities, TransactionRequest, TransactionResult } from './transactions';
5
- import type { SignatureType } from './signature';
5
+ import type { SignatureType, EIP712TypedData } from './signature';
6
6
  /**
7
7
  * Result interface for connect operations
8
8
  */
@@ -68,6 +68,13 @@ export interface Connector {
68
68
  * @returns A promise that resolves to the signature
69
69
  */
70
70
  signMessage?(message: string, provider?: ExtensionInjectedProvider | IntegratedBrowserInjectedProvider | WalletConnectProvider | TonConnectWalletProvider): Promise<SignatureType>;
71
+ /**
72
+ * Sign EIP-712 typed structured data (eth_signTypedData_v4).
73
+ * Required for ERC-3009 (Transfer With Authorization) and EIP-2612 (Permit) relay flows.
74
+ * EVM-only (eip155); connectors that don't support it leave this undefined.
75
+ * @returns A promise that resolves to the 65-byte hex signature (0x-prefixed)
76
+ */
77
+ signTypedData?(typedData: EIP712TypedData, provider?: ExtensionInjectedProvider | IntegratedBrowserInjectedProvider | WalletConnectProvider): Promise<string>;
71
78
  /**
72
79
  * Send a transaction with the connected wallet
73
80
  * @param request The transaction request parameters
@@ -1 +1 @@
1
- {"version":3,"file":"connector.d.ts","sourceRoot":"","sources":["../src/connector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAC/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAA;AACjD,OAAO,KAAK,EACV,yBAAyB,EACzB,wBAAwB,EACxB,sBAAsB,EACtB,qBAAqB,EACrB,yBAAyB,EACzB,iCAAiC,EACjC,qBAAqB,EACrB,wBAAwB,EACxB,cAAc,EACf,MAAM,aAAa,CAAA;AACpB,OAAO,KAAK,EACV,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EAClB,MAAM,gBAAgB,CAAA;AACvB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAEhD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,SAAS,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;IACf,kBAAkB,EAAE,gBAAgB,EAAE,CAAA;IACtC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,SAAS,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;IACf,kBAAkB,CAAC,EAAE,gBAAgB,EAAE,CAAA;CACxC;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB;;;;;OAKG;IAEH,OAAO,CACL,OAAO,EAAE,OAAO,EAChB,QAAQ,CAAC,EACL,yBAAyB,GACzB,iCAAiC,GACjC,qBAAqB,GACrB,wBAAwB,GAC3B,OAAO,CAAC,eAAe,CAAC,CAAA;IAE3B;;;;;;;OAOG;IACH,gBAAgB,CAAC,IAAI,MAAM,CAAA;IAE3B;;;;OAIG;IACH,UAAU,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IAE5B;;;;;OAKG;IAEH,aAAa,CACX,OAAO,EAAE,OAAO,EAChB,QAAQ,CAAC,EACL,yBAAyB,GACzB,iCAAiC,GACjC,qBAAqB,GACrB,wBAAwB,GAC3B,OAAO,CAAC,mBAAmB,CAAC,CAAA;IAE/B;;;;;;OAMG;IACH,mBAAmB,CAAC,CAClB,SAAS,EAAE,SAAS,EACpB,eAAe,CAAC,EAAE,cAAc,EAAE,GACjC,OAAO,CACN,yBAAyB,EAAE,GAC3B,wBAAwB,EAAE,GAC1B,sBAAsB,EAAE,GACxB,qBAAqB,EAAE,CAC1B,CAAA;IAED;;;;;OAKG;IACH,WAAW,CAAC,CACV,OAAO,EAAE,MAAM,EACf,QAAQ,CAAC,EACL,yBAAyB,GACzB,iCAAiC,GACjC,qBAAqB,GACrB,wBAAwB,GAC3B,OAAO,CAAC,aAAa,CAAC,CAAA;IAEzB;;;;;OAKG;IACH,eAAe,CAAC,CACd,OAAO,EAAE,kBAAkB,EAC3B,QAAQ,CAAC,EACL,yBAAyB,GACzB,iCAAiC,GACjC,qBAAqB,GACrB,wBAAwB,GAC3B,OAAO,CAAC,iBAAiB,CAAC,CAAA;IAE7B,qBAAqB,CAAC,CACpB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,OAAO,EAAE,GAClB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAA;IAE3C;;;;OAIG;IACH,0BAA0B,CAAC,CAAC,YAAY,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;CAC3E"}
1
+ {"version":3,"file":"connector.d.ts","sourceRoot":"","sources":["../src/connector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAC/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAA;AACjD,OAAO,KAAK,EACV,yBAAyB,EACzB,wBAAwB,EACxB,sBAAsB,EACtB,qBAAqB,EACrB,yBAAyB,EACzB,iCAAiC,EACjC,qBAAqB,EACrB,wBAAwB,EACxB,cAAc,EACf,MAAM,aAAa,CAAA;AACpB,OAAO,KAAK,EACV,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EAClB,MAAM,gBAAgB,CAAA;AACvB,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAEjE;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,SAAS,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;IACf,kBAAkB,EAAE,gBAAgB,EAAE,CAAA;IACtC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,SAAS,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;IACf,kBAAkB,CAAC,EAAE,gBAAgB,EAAE,CAAA;CACxC;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB;;;;;OAKG;IAEH,OAAO,CACL,OAAO,EAAE,OAAO,EAChB,QAAQ,CAAC,EACL,yBAAyB,GACzB,iCAAiC,GACjC,qBAAqB,GACrB,wBAAwB,GAC3B,OAAO,CAAC,eAAe,CAAC,CAAA;IAE3B;;;;;;;OAOG;IACH,gBAAgB,CAAC,IAAI,MAAM,CAAA;IAE3B;;;;OAIG;IACH,UAAU,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IAE5B;;;;;OAKG;IAEH,aAAa,CACX,OAAO,EAAE,OAAO,EAChB,QAAQ,CAAC,EACL,yBAAyB,GACzB,iCAAiC,GACjC,qBAAqB,GACrB,wBAAwB,GAC3B,OAAO,CAAC,mBAAmB,CAAC,CAAA;IAE/B;;;;;;OAMG;IACH,mBAAmB,CAAC,CAClB,SAAS,EAAE,SAAS,EACpB,eAAe,CAAC,EAAE,cAAc,EAAE,GACjC,OAAO,CACN,yBAAyB,EAAE,GAC3B,wBAAwB,EAAE,GAC1B,sBAAsB,EAAE,GACxB,qBAAqB,EAAE,CAC1B,CAAA;IAED;;;;;OAKG;IACH,WAAW,CAAC,CACV,OAAO,EAAE,MAAM,EACf,QAAQ,CAAC,EACL,yBAAyB,GACzB,iCAAiC,GACjC,qBAAqB,GACrB,wBAAwB,GAC3B,OAAO,CAAC,aAAa,CAAC,CAAA;IAEzB;;;;;OAKG;IACH,aAAa,CAAC,CACZ,SAAS,EAAE,eAAe,EAC1B,QAAQ,CAAC,EACL,yBAAyB,GACzB,iCAAiC,GACjC,qBAAqB,GACxB,OAAO,CAAC,MAAM,CAAC,CAAA;IAElB;;;;;OAKG;IACH,eAAe,CAAC,CACd,OAAO,EAAE,kBAAkB,EAC3B,QAAQ,CAAC,EACL,yBAAyB,GACzB,iCAAiC,GACjC,qBAAqB,GACrB,wBAAwB,GAC3B,OAAO,CAAC,iBAAiB,CAAC,CAAA;IAE7B,qBAAqB,CAAC,CACpB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,OAAO,EAAE,GAClB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAA;IAE3C;;;;OAIG;IACH,0BAA0B,CAAC,CAAC,YAAY,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;CAC3E"}
@@ -1,4 +1,4 @@
1
- import type { NetworkId, Network, ConnectionMode, Session, AvailableAddress, TransactionRequest, TransactionResult, WalletError, EVMCapabilities, SignatureType, WalletMetadata } from './index';
1
+ import type { NetworkId, Network, ConnectionMode, Session, AvailableAddress, TransactionRequest, TransactionResult, WalletError, EVMCapabilities, SignatureType, EIP712TypedData, WalletMetadata } from './index';
2
2
  /**
3
3
  * WalletConnect connection interface for the useConnection hook
4
4
  */
@@ -230,6 +230,32 @@ export interface UseSignMessageReturn {
230
230
  */
231
231
  error: WalletError | undefined;
232
232
  }
233
+ /**
234
+ * Return type for the useSignTypedData hook.
235
+ * Provides EIP-712 typed data signing (eth_signTypedData_v4) for EVM wallets.
236
+ * Used by ERC-3009 (Transfer With Authorization) and EIP-2612 (Permit) relay flows.
237
+ */
238
+ export interface UseSignTypedDataReturn {
239
+ /**
240
+ * Signs EIP-712 typed data with the connected EVM wallet
241
+ * @param typedData - The EIP-712 typed data to sign
242
+ * @returns Promise that resolves to the 65-byte hex signature (0x-prefixed)
243
+ * @throws Error if no wallet is connected, the wallet is non-EVM, or signing fails
244
+ */
245
+ signTypedData: (typedData: EIP712TypedData) => Promise<string>;
246
+ /**
247
+ * Indicates if a typed-data signing operation is currently in progress
248
+ */
249
+ isLoading: boolean;
250
+ /**
251
+ * The raw hex signature from the last successful sign, undefined if not yet signed
252
+ */
253
+ signature: string | undefined;
254
+ /**
255
+ * Error from the last signing attempt, undefined if no error occurred
256
+ */
257
+ error: WalletError | undefined;
258
+ }
233
259
  /**
234
260
  * Return type for useSignSolanaTransaction — sign-only Solana signing (bytes in,
235
261
  * bytes out) for fee-payer relay flows where the relay, not the wallet, broadcasts.
@@ -1 +1 @@
1
- {"version":3,"file":"react-hooks.d.ts","sourceRoot":"","sources":["../src/react-hooks.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"react-hooks.d.ts","sourceRoot":"","sources":["../src/react-hooks.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,39 @@
1
1
  import type { ExtensionInjectedProvider, IntegratedBrowserInjectedProvider } from './UWC-state';
2
+ /**
3
+ * EIP-712 typed structured data for eth_signTypedData_v4.
4
+ * Used by ERC-3009 (Transfer With Authorization), EIP-2612 (Permit), and similar standards.
5
+ */
6
+ export interface EIP712TypedData {
7
+ domain: {
8
+ name?: string;
9
+ version?: string;
10
+ chainId?: number;
11
+ verifyingContract?: string;
12
+ salt?: string;
13
+ };
14
+ types: Record<string, Array<{
15
+ name: string;
16
+ type: string;
17
+ }>>;
18
+ primaryType: string;
19
+ message: Record<string, unknown>;
20
+ }
21
+ /**
22
+ * Ensures the EIP712Domain type entry is present in `types`, derived from the
23
+ * fields actually set on `domain`, in EIP-712's canonical order.
24
+ *
25
+ * Why: some wallets (notably Trust Wallet and several mobile wallets over
26
+ * WalletConnect) parse the `types` object strictly and reject an
27
+ * eth_signTypedData_v4 request that omits EIP712Domain. Desktop MetaMask derives
28
+ * it implicitly, so callers tend to leave it out — this normalizes both.
29
+ *
30
+ * If the caller already supplied EIP712Domain, theirs is authoritative and the
31
+ * input is returned untouched. Otherwise a new object is returned (input is not
32
+ * mutated) with EIP712Domain inserted first.
33
+ *
34
+ * @see https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator
35
+ */
36
+ export declare function withEIP712Domain(typedData: EIP712TypedData): EIP712TypedData;
2
37
  /**
3
38
  * Standard signature format for most blockchains (EVM, Solana, etc.)
4
39
  */
@@ -1 +1 @@
1
- {"version":3,"file":"signature.d.ts","sourceRoot":"","sources":["../src/signature.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,yBAAyB,EACzB,iCAAiC,EAClC,MAAM,aAAa,CAAA;AAEpB;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,UAAU,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;CACb;AAED;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAC1B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9C;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA;AAErC;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,KAAK,CAAA;IACX,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,kBAAkB,CAAA;CAC5B;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,iBAAiB,GAAG,aAAa,GAAG,YAAY,CAAA;AAE5E;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,aAAa,CAAA;IACxB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;OAKG;IACH,WAAW,CACT,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,yBAAyB,GAAG,iCAAiC,GACtE,OAAO,CAAC,eAAe,CAAC,CAAA;CAC5B"}
1
+ {"version":3,"file":"signature.d.ts","sourceRoot":"","sources":["../src/signature.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,yBAAyB,EACzB,iCAAiC,EAClC,MAAM,aAAa,CAAA;AAEpB;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE;QACN,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,iBAAiB,CAAC,EAAE,MAAM,CAAA;QAC1B,IAAI,CAAC,EAAE,MAAM,CAAA;KACd,CAAA;IACD,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAA;IAC5D,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACjC;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,eAAe,GAAG,eAAe,CAyB5E;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,UAAU,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;CACb;AAED;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAC1B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9C;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA;AAErC;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,KAAK,CAAA;IACX,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,kBAAkB,CAAA;CAC5B;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,iBAAiB,GAAG,aAAa,GAAG,YAAY,CAAA;AAE5E;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,aAAa,CAAA;IACxB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;OAKG;IACH,WAAW,CACT,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,yBAAyB,GAAG,iCAAiC,GACtE,OAAO,CAAC,eAAe,CAAC,CAAA;CAC5B"}
package/dist/signature.js CHANGED
@@ -1,2 +1,40 @@
1
- export {};
1
+ /**
2
+ * Ensures the EIP712Domain type entry is present in `types`, derived from the
3
+ * fields actually set on `domain`, in EIP-712's canonical order.
4
+ *
5
+ * Why: some wallets (notably Trust Wallet and several mobile wallets over
6
+ * WalletConnect) parse the `types` object strictly and reject an
7
+ * eth_signTypedData_v4 request that omits EIP712Domain. Desktop MetaMask derives
8
+ * it implicitly, so callers tend to leave it out — this normalizes both.
9
+ *
10
+ * If the caller already supplied EIP712Domain, theirs is authoritative and the
11
+ * input is returned untouched. Otherwise a new object is returned (input is not
12
+ * mutated) with EIP712Domain inserted first.
13
+ *
14
+ * @see https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator
15
+ */
16
+ export function withEIP712Domain(typedData) {
17
+ if (Object.hasOwn(typedData.types, 'EIP712Domain'))
18
+ return typedData;
19
+ const { domain } = typedData;
20
+ const domainFields = [];
21
+ // Canonical field order — the on-chain domainSeparator hash depends on it.
22
+ if (domain.name !== undefined)
23
+ domainFields.push({ name: 'name', type: 'string' });
24
+ if (domain.version !== undefined)
25
+ domainFields.push({ name: 'version', type: 'string' });
26
+ if (domain.chainId !== undefined)
27
+ domainFields.push({ name: 'chainId', type: 'uint256' });
28
+ if (domain.verifyingContract !== undefined)
29
+ domainFields.push({ name: 'verifyingContract', type: 'address' });
30
+ if (domain.salt !== undefined)
31
+ domainFields.push({ name: 'salt', type: 'bytes32' });
32
+ return {
33
+ ...typedData,
34
+ types: {
35
+ EIP712Domain: domainFields,
36
+ ...typedData.types
37
+ }
38
+ };
39
+ }
2
40
  //# sourceMappingURL=signature.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"signature.js","sourceRoot":"","sources":["../src/signature.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"signature.js","sourceRoot":"","sources":["../src/signature.ts"],"names":[],"mappings":"AAsBA;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,gBAAgB,CAAC,SAA0B;IACzD,IAAI,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,cAAc,CAAC;QAAE,OAAO,SAAS,CAAA;IAEpE,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,CAAA;IAC5B,MAAM,YAAY,GAA0C,EAAE,CAAA;IAE9D,2EAA2E;IAC3E,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS;QAC3B,YAAY,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAA;IACrD,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS;QAC9B,YAAY,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAA;IACxD,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS;QAC9B,YAAY,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAA;IACzD,IAAI,MAAM,CAAC,iBAAiB,KAAK,SAAS;QACxC,YAAY,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAA;IACnE,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS;QAC3B,YAAY,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAA;IAEtD,OAAO;QACL,GAAG,SAAS;QACZ,KAAK,EAAE;YACL,YAAY,EAAE,YAAY;YAC1B,GAAG,SAAS,CAAC,KAAK;SACnB;KACF,CAAA;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meshconnect/uwc-types",
3
- "version": "0.14.0-snapshot.6b75329",
3
+ "version": "0.15.0",
4
4
  "description": "TypeScript types for Universal Wallet Connector",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/src/connector.ts CHANGED
@@ -16,7 +16,7 @@ import type {
16
16
  TransactionRequest,
17
17
  TransactionResult
18
18
  } from './transactions'
19
- import type { SignatureType } from './signature'
19
+ import type { SignatureType, EIP712TypedData } from './signature'
20
20
 
21
21
  /**
22
22
  * Result interface for connect operations
@@ -122,6 +122,20 @@ export interface Connector {
122
122
  | TonConnectWalletProvider
123
123
  ): Promise<SignatureType>
124
124
 
125
+ /**
126
+ * Sign EIP-712 typed structured data (eth_signTypedData_v4).
127
+ * Required for ERC-3009 (Transfer With Authorization) and EIP-2612 (Permit) relay flows.
128
+ * EVM-only (eip155); connectors that don't support it leave this undefined.
129
+ * @returns A promise that resolves to the 65-byte hex signature (0x-prefixed)
130
+ */
131
+ signTypedData?(
132
+ typedData: EIP712TypedData,
133
+ provider?:
134
+ | ExtensionInjectedProvider
135
+ | IntegratedBrowserInjectedProvider
136
+ | WalletConnectProvider
137
+ ): Promise<string>
138
+
125
139
  /**
126
140
  * Send a transaction with the connected wallet
127
141
  * @param request The transaction request parameters
@@ -9,6 +9,7 @@ import type {
9
9
  WalletError,
10
10
  EVMCapabilities,
11
11
  SignatureType,
12
+ EIP712TypedData,
12
13
  WalletMetadata
13
14
  } from './index'
14
15
 
@@ -258,6 +259,35 @@ export interface UseSignMessageReturn {
258
259
  error: WalletError | undefined
259
260
  }
260
261
 
262
+ // useSignTypedData hook types
263
+
264
+ /**
265
+ * Return type for the useSignTypedData hook.
266
+ * Provides EIP-712 typed data signing (eth_signTypedData_v4) for EVM wallets.
267
+ * Used by ERC-3009 (Transfer With Authorization) and EIP-2612 (Permit) relay flows.
268
+ */
269
+ export interface UseSignTypedDataReturn {
270
+ /**
271
+ * Signs EIP-712 typed data with the connected EVM wallet
272
+ * @param typedData - The EIP-712 typed data to sign
273
+ * @returns Promise that resolves to the 65-byte hex signature (0x-prefixed)
274
+ * @throws Error if no wallet is connected, the wallet is non-EVM, or signing fails
275
+ */
276
+ signTypedData: (typedData: EIP712TypedData) => Promise<string>
277
+ /**
278
+ * Indicates if a typed-data signing operation is currently in progress
279
+ */
280
+ isLoading: boolean
281
+ /**
282
+ * The raw hex signature from the last successful sign, undefined if not yet signed
283
+ */
284
+ signature: string | undefined
285
+ /**
286
+ * Error from the last signing attempt, undefined if no error occurred
287
+ */
288
+ error: WalletError | undefined
289
+ }
290
+
261
291
  // useSignSolanaTransaction hook types
262
292
 
263
293
  /**
@@ -0,0 +1,197 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { withEIP712Domain } from './signature'
3
+ import type { EIP712TypedData } from './signature'
4
+
5
+ const baseTypes = {
6
+ TransferWithAuthorization: [
7
+ { name: 'from', type: 'address' },
8
+ { name: 'to', type: 'address' },
9
+ { name: 'value', type: 'uint256' },
10
+ { name: 'validAfter', type: 'uint256' },
11
+ { name: 'validBefore', type: 'uint256' },
12
+ { name: 'nonce', type: 'bytes32' }
13
+ ]
14
+ }
15
+
16
+ const baseMessage = {
17
+ from: '0xabc',
18
+ to: '0xdef',
19
+ value: '1000000',
20
+ validAfter: 0,
21
+ validBefore: 9999999999,
22
+ nonce: '0xdeadbeef'
23
+ }
24
+
25
+ describe('withEIP712Domain', () => {
26
+ it('injects EIP712Domain with all four standard fields when all are present in domain', () => {
27
+ const input: EIP712TypedData = {
28
+ domain: {
29
+ name: 'USD Coin',
30
+ version: '2',
31
+ chainId: 1,
32
+ verifyingContract: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'
33
+ },
34
+ types: baseTypes,
35
+ primaryType: 'TransferWithAuthorization',
36
+ message: baseMessage
37
+ }
38
+
39
+ const result = withEIP712Domain(input)
40
+
41
+ expect(result.types.EIP712Domain).toEqual([
42
+ { name: 'name', type: 'string' },
43
+ { name: 'version', type: 'string' },
44
+ { name: 'chainId', type: 'uint256' },
45
+ { name: 'verifyingContract', type: 'address' }
46
+ ])
47
+ // Existing types are preserved
48
+ expect(result.types.TransferWithAuthorization).toEqual(
49
+ baseTypes.TransferWithAuthorization
50
+ )
51
+ // Other fields are unchanged
52
+ expect(result.domain).toBe(input.domain)
53
+ expect(result.primaryType).toBe(input.primaryType)
54
+ expect(result.message).toBe(input.message)
55
+ })
56
+
57
+ it('omits version from EIP712Domain when domain has no version (UNI-style)', () => {
58
+ const input: EIP712TypedData = {
59
+ domain: { name: 'Uniswap V2', chainId: 1, verifyingContract: '0x...' },
60
+ types: { Permit: [{ name: 'owner', type: 'address' }] },
61
+ primaryType: 'Permit',
62
+ message: {}
63
+ }
64
+
65
+ const result = withEIP712Domain(input)
66
+
67
+ expect(result.types.EIP712Domain).toEqual([
68
+ { name: 'name', type: 'string' },
69
+ { name: 'chainId', type: 'uint256' },
70
+ { name: 'verifyingContract', type: 'address' }
71
+ ])
72
+ })
73
+
74
+ it('includes salt when present in domain', () => {
75
+ const input: EIP712TypedData = {
76
+ domain: {
77
+ name: 'MyToken',
78
+ chainId: 137,
79
+ salt: '0xdeadbeef00000000000000000000000000000000000000000000000000000000'
80
+ },
81
+ types: baseTypes,
82
+ primaryType: 'TransferWithAuthorization',
83
+ message: baseMessage
84
+ }
85
+
86
+ const result = withEIP712Domain(input)
87
+
88
+ expect(result.types.EIP712Domain).toEqual([
89
+ { name: 'name', type: 'string' },
90
+ { name: 'chainId', type: 'uint256' },
91
+ { name: 'salt', type: 'bytes32' }
92
+ ])
93
+ })
94
+
95
+ it('preserves canonical field order: name, version, chainId, verifyingContract, salt', () => {
96
+ const input: EIP712TypedData = {
97
+ domain: {
98
+ salt: '0x00000000000000000000000000000000000000000000000000000000000000ab',
99
+ verifyingContract: '0x123',
100
+ name: 'Token',
101
+ chainId: 1,
102
+ version: '1'
103
+ },
104
+ types: baseTypes,
105
+ primaryType: 'TransferWithAuthorization',
106
+ message: baseMessage
107
+ }
108
+
109
+ const result = withEIP712Domain(input)
110
+ const names = result.types.EIP712Domain.map(f => f.name)
111
+
112
+ expect(names).toEqual([
113
+ 'name',
114
+ 'version',
115
+ 'chainId',
116
+ 'verifyingContract',
117
+ 'salt'
118
+ ])
119
+ })
120
+
121
+ it('does not modify input when EIP712Domain is already present', () => {
122
+ const existingEIP712Domain = [
123
+ { name: 'name', type: 'string' },
124
+ { name: 'chainId', type: 'uint256' }
125
+ ]
126
+ const input: EIP712TypedData = {
127
+ domain: {
128
+ name: 'USD Coin',
129
+ version: '2',
130
+ chainId: 1,
131
+ verifyingContract: '0xabc'
132
+ },
133
+ types: { EIP712Domain: existingEIP712Domain, ...baseTypes },
134
+ primaryType: 'TransferWithAuthorization',
135
+ message: baseMessage
136
+ }
137
+
138
+ const result = withEIP712Domain(input)
139
+
140
+ // Returns input unchanged — caller's EIP712Domain is authoritative
141
+ expect(result).toBe(input)
142
+ expect(result.types.EIP712Domain).toBe(existingEIP712Domain)
143
+ })
144
+
145
+ it('returns a new object (does not mutate input) when injecting EIP712Domain', () => {
146
+ const input: EIP712TypedData = {
147
+ domain: {
148
+ name: 'USD Coin',
149
+ version: '2',
150
+ chainId: 1,
151
+ verifyingContract: '0xabc'
152
+ },
153
+ types: { ...baseTypes },
154
+ primaryType: 'TransferWithAuthorization',
155
+ message: baseMessage
156
+ }
157
+
158
+ const result = withEIP712Domain(input)
159
+
160
+ expect(result).not.toBe(input)
161
+ expect(result.types).not.toBe(input.types)
162
+ // Original is untouched
163
+ expect(input.types.EIP712Domain).toBeUndefined()
164
+ })
165
+
166
+ it('handles a domain with only chainId (minimal domain)', () => {
167
+ const input: EIP712TypedData = {
168
+ domain: { chainId: 8453 },
169
+ types: baseTypes,
170
+ primaryType: 'TransferWithAuthorization',
171
+ message: baseMessage
172
+ }
173
+
174
+ const result = withEIP712Domain(input)
175
+
176
+ expect(result.types.EIP712Domain).toEqual([
177
+ { name: 'chainId', type: 'uint256' }
178
+ ])
179
+ })
180
+
181
+ it('places EIP712Domain before other types in the types object', () => {
182
+ const input: EIP712TypedData = {
183
+ domain: {
184
+ name: 'USD Coin',
185
+ version: '2',
186
+ chainId: 1,
187
+ verifyingContract: '0xabc'
188
+ },
189
+ types: baseTypes,
190
+ primaryType: 'TransferWithAuthorization',
191
+ message: baseMessage
192
+ }
193
+
194
+ const keys = Object.keys(withEIP712Domain(input).types)
195
+ expect(keys[0]).toBe('EIP712Domain')
196
+ })
197
+ })
package/src/signature.ts CHANGED
@@ -3,6 +3,65 @@ import type {
3
3
  IntegratedBrowserInjectedProvider
4
4
  } from './UWC-state'
5
5
 
6
+ /**
7
+ * EIP-712 typed structured data for eth_signTypedData_v4.
8
+ * Used by ERC-3009 (Transfer With Authorization), EIP-2612 (Permit), and similar standards.
9
+ */
10
+ export interface EIP712TypedData {
11
+ domain: {
12
+ name?: string
13
+ version?: string
14
+ chainId?: number
15
+ verifyingContract?: string
16
+ salt?: string
17
+ }
18
+ types: Record<string, Array<{ name: string; type: string }>>
19
+ primaryType: string
20
+ message: Record<string, unknown>
21
+ }
22
+
23
+ /**
24
+ * Ensures the EIP712Domain type entry is present in `types`, derived from the
25
+ * fields actually set on `domain`, in EIP-712's canonical order.
26
+ *
27
+ * Why: some wallets (notably Trust Wallet and several mobile wallets over
28
+ * WalletConnect) parse the `types` object strictly and reject an
29
+ * eth_signTypedData_v4 request that omits EIP712Domain. Desktop MetaMask derives
30
+ * it implicitly, so callers tend to leave it out — this normalizes both.
31
+ *
32
+ * If the caller already supplied EIP712Domain, theirs is authoritative and the
33
+ * input is returned untouched. Otherwise a new object is returned (input is not
34
+ * mutated) with EIP712Domain inserted first.
35
+ *
36
+ * @see https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator
37
+ */
38
+ export function withEIP712Domain(typedData: EIP712TypedData): EIP712TypedData {
39
+ if (Object.hasOwn(typedData.types, 'EIP712Domain')) return typedData
40
+
41
+ const { domain } = typedData
42
+ const domainFields: Array<{ name: string; type: string }> = []
43
+
44
+ // Canonical field order — the on-chain domainSeparator hash depends on it.
45
+ if (domain.name !== undefined)
46
+ domainFields.push({ name: 'name', type: 'string' })
47
+ if (domain.version !== undefined)
48
+ domainFields.push({ name: 'version', type: 'string' })
49
+ if (domain.chainId !== undefined)
50
+ domainFields.push({ name: 'chainId', type: 'uint256' })
51
+ if (domain.verifyingContract !== undefined)
52
+ domainFields.push({ name: 'verifyingContract', type: 'address' })
53
+ if (domain.salt !== undefined)
54
+ domainFields.push({ name: 'salt', type: 'bytes32' })
55
+
56
+ return {
57
+ ...typedData,
58
+ types: {
59
+ EIP712Domain: domainFields,
60
+ ...typedData.types
61
+ }
62
+ }
63
+ }
64
+
6
65
  /**
7
66
  * Standard signature format for most blockchains (EVM, Solana, etc.)
8
67
  */