@lifi/perps-sdk-provider-lighter 3.0.0 → 4.0.1
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 +16 -3
- package/dist/cjs/index.d.ts +1 -1
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/signers/LighterSigner.d.ts +4 -0
- package/dist/cjs/signers/LighterSigner.d.ts.map +1 -1
- package/dist/cjs/signers/LighterSigner.js +25 -1
- package/dist/cjs/signers/LighterSigner.js.map +1 -1
- package/dist/cjs/signers/signActions.d.ts.map +1 -1
- package/dist/cjs/signers/signActions.js +30 -0
- package/dist/cjs/signers/signActions.js.map +1 -1
- package/dist/cjs/signers/wasmLoader.d.ts +3 -1
- package/dist/cjs/signers/wasmLoader.d.ts.map +1 -1
- package/dist/cjs/signers/wasmLoader.js.map +1 -1
- package/dist/cjs/websocket/LighterWsProvider.d.ts +4 -3
- package/dist/cjs/websocket/LighterWsProvider.d.ts.map +1 -1
- package/dist/cjs/websocket/LighterWsProvider.js +21 -5
- package/dist/cjs/websocket/LighterWsProvider.js.map +1 -1
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/signers/LighterSigner.d.ts +21 -6
- package/dist/esm/signers/LighterSigner.d.ts.map +1 -1
- package/dist/esm/signers/LighterSigner.js +40 -7
- package/dist/esm/signers/LighterSigner.js.map +1 -1
- package/dist/esm/signers/signActions.d.ts.map +1 -1
- package/dist/esm/signers/signActions.js +42 -0
- package/dist/esm/signers/signActions.js.map +1 -1
- package/dist/esm/signers/wasmLoader.d.ts +6 -2
- package/dist/esm/signers/wasmLoader.d.ts.map +1 -1
- package/dist/esm/signers/wasmLoader.js.map +1 -1
- package/dist/esm/websocket/LighterWsProvider.d.ts +34 -16
- package/dist/esm/websocket/LighterWsProvider.d.ts.map +1 -1
- package/dist/esm/websocket/LighterWsProvider.js +46 -15
- package/dist/esm/websocket/LighterWsProvider.js.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/signers/LighterSigner.d.ts +21 -6
- package/dist/types/signers/LighterSigner.d.ts.map +1 -1
- package/dist/types/signers/signActions.d.ts.map +1 -1
- package/dist/types/signers/wasmLoader.d.ts +6 -2
- package/dist/types/signers/wasmLoader.d.ts.map +1 -1
- package/dist/types/websocket/LighterWsProvider.d.ts +34 -16
- package/dist/types/websocket/LighterWsProvider.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/index.ts +1 -1
- package/src/signers/LighterSigner.ts +62 -8
- package/src/signers/signActions.ts +57 -0
- package/src/signers/wasmLoader.ts +6 -2
- package/src/websocket/LighterWsProvider.ts +72 -24
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,4BAA4B,EAAE,MAAM,oBAAoB,CAAA;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AACvD,OAAO,EACL,qBAAqB,EACrB,wBAAwB,EACxB,oBAAoB,EACpB,wBAAwB,GACzB,MAAM,gBAAgB,CAAA;AACvB,YAAY,EACV,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAE/D,cAAc,oBAAoB,CAAA;AAClC,cAAc,kBAAkB,CAAA;AAChC,cAAc,kBAAkB,CAAA;AAChC,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,4BAA4B,EAAE,MAAM,oBAAoB,CAAA;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AACvD,OAAO,EACL,qBAAqB,EACrB,wBAAwB,EACxB,oBAAoB,EACpB,wBAAwB,GACzB,MAAM,gBAAgB,CAAA;AACvB,YAAY,EACV,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAE/D,cAAc,oBAAoB,CAAA;AAClC,cAAc,kBAAkB,CAAA;AAChC,cAAc,kBAAkB,CAAA;AAChC,YAAY,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAA;AAChF,OAAO,EACL,iBAAiB,EACjB,KAAK,wBAAwB,EAC7B,iBAAiB,GAClB,MAAM,kCAAkC,CAAA"}
|
|
@@ -28,6 +28,11 @@ export interface ChangePubKeyResult extends LighterSignedBlob {
|
|
|
28
28
|
messageToSign: string;
|
|
29
29
|
}
|
|
30
30
|
/** @public */
|
|
31
|
+
export interface ApproveIntegratorResult extends LighterSignedBlob {
|
|
32
|
+
/** EIP-191 `L2ApproveIntegrator` L1 body the user's wallet must countersign to authorize the integrator approval. */
|
|
33
|
+
messageToSign: string;
|
|
34
|
+
}
|
|
35
|
+
/** @public */
|
|
31
36
|
export interface ApiKeyPair {
|
|
32
37
|
publicKey: string;
|
|
33
38
|
privateKey: string;
|
|
@@ -52,8 +57,9 @@ export declare class LighterSigner {
|
|
|
52
57
|
* `WasmBlobActionStep`. Returns the signed `{ txType, txInfo, txHash }`
|
|
53
58
|
* triple the backend forwards to Lighter's `sendTx` endpoint.
|
|
54
59
|
*
|
|
55
|
-
* For REGISTER_API_KEY use `signChangePubKey`
|
|
56
|
-
*
|
|
60
|
+
* For REGISTER_API_KEY use `signChangePubKey` and for APPROVE_INTEGRATOR
|
|
61
|
+
* use `signApproveIntegrator` instead — both return an additional
|
|
62
|
+
* `messageToSign` the L1 wallet must countersign.
|
|
57
63
|
*/
|
|
58
64
|
sign(action: ActionType, wasmSignParams: Record<string, unknown>, context: LighterSignerContext): Promise<LighterSignedBlob>;
|
|
59
65
|
/**
|
|
@@ -70,10 +76,19 @@ export declare class LighterSigner {
|
|
|
70
76
|
*/
|
|
71
77
|
signChangePubKey(pubKeyHex: string, privateKey: string, nonce: number, apiKeyIndex: number, accountIndex: number, skipNonce?: 0 | 1): Promise<ChangePubKeyResult>;
|
|
72
78
|
/**
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
79
|
+
* Sign an APPROVE_INTEGRATOR action with the stored API key and return the
|
|
80
|
+
* signed blob alongside the EIP-191 `L2ApproveIntegrator` L1 message the
|
|
81
|
+
* user's Ethereum wallet must countersign. Unlike {@link sign}, this exposes
|
|
82
|
+
* `messageToSign`: Lighter requires `L1Sig` (injected via
|
|
83
|
+
* {@link embedL1Signature} before submission) when the integrator account
|
|
84
|
+
* belongs to a different L1 address with non-zero fee caps.
|
|
85
|
+
*/
|
|
86
|
+
signApproveIntegrator(wasmSignParams: Record<string, unknown>, context: LighterSignerContext): Promise<ApproveIntegratorResult>;
|
|
87
|
+
/**
|
|
88
|
+
* Inject the L1 signature produced by the user's Ethereum wallet into a
|
|
89
|
+
* signed txInfo JSON. `L1Sig` is the only field that depends on the L1
|
|
90
|
+
* signature; txHash does NOT include it (so we do not recompute it). Shared
|
|
91
|
+
* by the REGISTER_API_KEY (ChangePubKey) and APPROVE_INTEGRATOR flows.
|
|
77
92
|
*/
|
|
78
93
|
embedL1Signature(txInfo: string, l1Signature: string): string;
|
|
79
94
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LighterSigner.d.ts","sourceRoot":"","sources":["../../../src/signers/LighterSigner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAQ9C,OAAO,EAEL,KAAK,sBAAsB,EAG5B,MAAM,iBAAiB,CAAA;AAOxB,cAAc;AACd,MAAM,WAAW,oBAAoB;IACnC,6EAA6E;IAC7E,gBAAgB,EAAE,MAAM,CAAA;IACxB,gDAAgD;IAChD,WAAW,EAAE,MAAM,CAAA;IACnB,6EAA6E;IAC7E,YAAY,EAAE,MAAM,CAAA;CACrB;AAED,cAAc;AACd,MAAM,WAAW,mBAAoB,SAAQ,sBAAsB;IACjE,iCAAiC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,wCAAwC;IACxC,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,cAAc;AACd,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;CACf;AAED,cAAc;AACd,MAAM,WAAW,kBAAmB,SAAQ,iBAAiB;IAC3D,sFAAsF;IACtF,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,cAAc;AACd,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;CACnB;AAkCD,cAAc;AACd,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAQ;IAChC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAwB;IACtD,OAAO,CAAC,IAAI,CAAgC;IAC5C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAoB;gBAE1C,MAAM,GAAE,mBAAwB;IAUtC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAMjC;;;OAGG;IACG,cAAc,IAAI,OAAO,CAAC,UAAU,CAAC;IAY3C
|
|
1
|
+
{"version":3,"file":"LighterSigner.d.ts","sourceRoot":"","sources":["../../../src/signers/LighterSigner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAQ9C,OAAO,EAEL,KAAK,sBAAsB,EAG5B,MAAM,iBAAiB,CAAA;AAOxB,cAAc;AACd,MAAM,WAAW,oBAAoB;IACnC,6EAA6E;IAC7E,gBAAgB,EAAE,MAAM,CAAA;IACxB,gDAAgD;IAChD,WAAW,EAAE,MAAM,CAAA;IACnB,6EAA6E;IAC7E,YAAY,EAAE,MAAM,CAAA;CACrB;AAED,cAAc;AACd,MAAM,WAAW,mBAAoB,SAAQ,sBAAsB;IACjE,iCAAiC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,wCAAwC;IACxC,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,cAAc;AACd,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;CACf;AAED,cAAc;AACd,MAAM,WAAW,kBAAmB,SAAQ,iBAAiB;IAC3D,sFAAsF;IACtF,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,cAAc;AACd,MAAM,WAAW,uBAAwB,SAAQ,iBAAiB;IAChE,qHAAqH;IACrH,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,cAAc;AACd,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;CACnB;AAkCD,cAAc;AACd,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAQ;IAChC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAwB;IACtD,OAAO,CAAC,IAAI,CAAgC;IAC5C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAoB;gBAE1C,MAAM,GAAE,mBAAwB;IAUtC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAMjC;;;OAGG;IACG,cAAc,IAAI,OAAO,CAAC,UAAU,CAAC;IAY3C;;;;;;;;;OASG;IACG,IAAI,CACR,MAAM,EAAE,UAAU,EAClB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACvC,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,iBAAiB,CAAC;IAmB7B;;;;;;;;;;;OAWG;IACG,gBAAgB,CACpB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,SAAS,GAAE,CAAC,GAAG,CAAK,GACnB,OAAO,CAAC,kBAAkB,CAAC;IAsC9B;;;;;;;OAOG;IACG,qBAAqB,CACzB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACvC,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,uBAAuB,CAAC;IA8BnC;;;;;OAKG;IACH,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM;IAa7D;;;OAGG;IACG,eAAe,CACnB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,MAAM,CAAC;YAiBJ,YAAY;YAOZ,YAAY;IAmB1B;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ;CA+MjB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signActions.d.ts","sourceRoot":"","sources":["../../../src/signers/signActions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AACrE,OAAO,KAAK,EACV,UAAU,EACV,eAAe,EACf,qBAAqB,EACrB,gBAAgB,EAChB,kBAAkB,EAClB,wBAAwB,EACzB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAA8B,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAC7E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAOnC,OAAO,KAAK,EAAa,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxE,OAAO,KAAK,EAAiB,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC1E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAEvD;;;;;;;GAOG;AACH,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,aAAa,CAAA;IACrB,QAAQ,EAAE,eAAe,CAAA;IACzB;;qCAEiC;IACjC,SAAS,EAAE,gBAAgB,CAAA;IAC3B;;;;;OAKG;IACH,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;CACvD;AAiBD;;;;;;;;;;;;GAYG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,sBAAsB,EAC5B,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,kBAAkB,EAAE,EAC3B,GAAG,EAAE,kBAAkB,GAAG,SAAS,GAClC,OAAO,CAAC,wBAAwB,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"signActions.d.ts","sourceRoot":"","sources":["../../../src/signers/signActions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AACrE,OAAO,KAAK,EACV,UAAU,EACV,eAAe,EACf,qBAAqB,EACrB,gBAAgB,EAChB,kBAAkB,EAClB,wBAAwB,EACzB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAA8B,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAC7E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAOnC,OAAO,KAAK,EAAa,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxE,OAAO,KAAK,EAAiB,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC1E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAEvD;;;;;;;GAOG;AACH,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,aAAa,CAAA;IACrB,QAAQ,EAAE,eAAe,CAAA;IACzB;;qCAEiC;IACjC,SAAS,EAAE,gBAAgB,CAAA;IAC3B;;;;;OAKG;IACH,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;CACvD;AAiBD;;;;;;;;;;;;GAYG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,sBAAsB,EAC5B,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,kBAAkB,EAAE,EAC3B,GAAG,EAAE,kBAAkB,GAAG,SAAS,GAClC,OAAO,CAAC,wBAAwB,EAAE,CAAC,CAgBrC;AA2QD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,eAAe,EAAE,EACxB,GAAG,EAAE,kBAAkB,GAAG,SAAS,GAClC,OAAO,CAAC,qBAAqB,EAAE,CAAC,CA6ElC;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,sBAAsB,EAC5B,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,UAAU,EAAE,EACnB,OAAO,EAAE,OAAO,EAChB,GAAG,CAAC,EAAE,kBAAkB,GACvB,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAsB7B"}
|
|
@@ -105,9 +105,13 @@ export interface LighterWasmExports {
|
|
|
105
105
|
* 10 args: integratorAccountIndex, maxPerpsTakerFee, maxPerpsMakerFee,
|
|
106
106
|
* maxSpotTakerFee, maxSpotMakerFee, approvalExpiry, skipNonce, then the
|
|
107
107
|
* trailing three. Fees are uint32 ppm of `FeeTick` (1_000_000); a non-nil
|
|
108
|
-
* fee requires a non-nil integrator index.
|
|
108
|
+
* fee requires a non-nil integrator index. `messageToSign` is the EIP-191
|
|
109
|
+
* `L2ApproveIntegrator` L1 body the user's wallet must countersign — the
|
|
110
|
+
* venue rejects the tx without the resulting `L1Sig`.
|
|
109
111
|
*/
|
|
110
|
-
SignApproveIntegrator: (...args: unknown[]) => SignResult
|
|
112
|
+
SignApproveIntegrator: (...args: unknown[]) => SignResult & {
|
|
113
|
+
messageToSign?: string;
|
|
114
|
+
};
|
|
111
115
|
/**
|
|
112
116
|
* 5 args: accountTradingMode (0 = Classic/Simple, 1 = Unified), skipNonce,
|
|
113
117
|
* then the trailing three. `accountTradingMode` is validated to {0, 1} by
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wasmLoader.d.ts","sourceRoot":"","sources":["../../../src/signers/wasmLoader.ts"],"names":[],"mappings":"AAkDA,cAAc;AACd,MAAM,WAAW,sBAAsB;IACrC,sEAAsE;IACtE,aAAa,CAAC,EAAE,MAAM,GAAG,GAAG,CAAA;IAC5B,oDAAoD;IACpD,aAAa,CAAC,EAAE,MAAM,GAAG,GAAG,CAAA;IAC5B;;;;;;;;;;OAUG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B;AAED,cAAc;AACd,MAAM,WAAW,kBAAkB;IACjC,cAAc,EAAE,MAAM;QACpB,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,UAAU,CAAC,EAAE,MAAM,CAAA;QACnB,KAAK,CAAC,EAAE,MAAM,CAAA;KACf,CAAA;IACD,YAAY,EAAE,CACZ,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,KACjB;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACvB,WAAW,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC9E;;;;;OAKG;IACH,eAAe,EAAE,CACf,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,KACjB;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC3C;;;;;;;OAOG;IACH,gBAAgB,EAAE,CAChB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,KACjB,UAAU,GAAG;QAAE,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC5C;;;;;;;;;;;;;;;OAeG;IACH,eAAe,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,UAAU,CAAA;IACnD,2EAA2E;IAC3E,eAAe,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,UAAU,CAAA;IACnD;;;OAGG;IACH,mBAAmB,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,UAAU,CAAA;IACvD;;;;;OAKG;IACH,YAAY,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,UAAU,CAAA;IAChD,iFAAiF;IACjF,YAAY,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,UAAU,CAAA;IAChD;;;OAGG;IACH,kBAAkB,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,UAAU,CAAA;IACtD;;;;;OAKG;IACH,eAAe,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,UAAU,CAAA;IACnD;;;OAGG;IACH,gBAAgB,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,UAAU,CAAA;IACpD
|
|
1
|
+
{"version":3,"file":"wasmLoader.d.ts","sourceRoot":"","sources":["../../../src/signers/wasmLoader.ts"],"names":[],"mappings":"AAkDA,cAAc;AACd,MAAM,WAAW,sBAAsB;IACrC,sEAAsE;IACtE,aAAa,CAAC,EAAE,MAAM,GAAG,GAAG,CAAA;IAC5B,oDAAoD;IACpD,aAAa,CAAC,EAAE,MAAM,GAAG,GAAG,CAAA;IAC5B;;;;;;;;;;OAUG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B;AAED,cAAc;AACd,MAAM,WAAW,kBAAkB;IACjC,cAAc,EAAE,MAAM;QACpB,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,UAAU,CAAC,EAAE,MAAM,CAAA;QACnB,KAAK,CAAC,EAAE,MAAM,CAAA;KACf,CAAA;IACD,YAAY,EAAE,CACZ,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,KACjB;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACvB,WAAW,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC9E;;;;;OAKG;IACH,eAAe,EAAE,CACf,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,KACjB;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC3C;;;;;;;OAOG;IACH,gBAAgB,EAAE,CAChB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,KACjB,UAAU,GAAG;QAAE,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC5C;;;;;;;;;;;;;;;OAeG;IACH,eAAe,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,UAAU,CAAA;IACnD,2EAA2E;IAC3E,eAAe,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,UAAU,CAAA;IACnD;;;OAGG;IACH,mBAAmB,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,UAAU,CAAA;IACvD;;;;;OAKG;IACH,YAAY,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,UAAU,CAAA;IAChD,iFAAiF;IACjF,YAAY,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,UAAU,CAAA;IAChD;;;OAGG;IACH,kBAAkB,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,UAAU,CAAA;IACtD;;;;;OAKG;IACH,eAAe,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,UAAU,CAAA;IACnD;;;OAGG;IACH,gBAAgB,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,UAAU,CAAA;IACpD;;;;;;;OAOG;IACH,qBAAqB,EAAE,CACrB,GAAG,IAAI,EAAE,OAAO,EAAE,KACf,UAAU,GAAG;QAAE,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC5C;;;;OAIG;IACH,uBAAuB,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,UAAU,CAAA;IAC3D;;;;OAIG;IACH,4BAA4B,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,UAAU,CAAA;CACjE;AAED,gBAAgB;AAChB,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAyFD;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,kBAAkB,CAAC,CAK7B;AAmED;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C"}
|
|
@@ -2,14 +2,20 @@ import { type PerpsSDKClient, type ProviderGetQuoteParams, type QuoteListener, W
|
|
|
2
2
|
import type { Subscription } from '@lifi/perps-types';
|
|
3
3
|
import type { Address } from 'viem';
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* Resolves a Lighter auth token for the given L1 address, or `undefined` when
|
|
6
|
+
* no source can produce one. Called on the initial subscribe and again on
|
|
7
|
+
* every reconnect, so it must return a token still valid a few minutes out.
|
|
8
|
+
*
|
|
9
|
+
* The default resolver — the co-registered `lighterProvider` plugin's
|
|
10
|
+
* `resolveAuthToken` — satisfies that: it never yields an expired token.
|
|
11
|
+
* Stored read-only tokens past expiry are filtered out and otherwise carry a
|
|
12
|
+
* ~10-year lifetime; near-expiry standard tokens are re-created within their
|
|
13
|
+
* renew buffer; and a server-rejected token self-heals on the next resolve. A
|
|
14
|
+
* supplied override owns its own freshness.
|
|
9
15
|
*
|
|
10
16
|
* @public
|
|
11
17
|
*/
|
|
12
|
-
export type
|
|
18
|
+
export type LighterAuthTokenResolver = (address: Address) => Promise<string | undefined>;
|
|
13
19
|
interface SubState {
|
|
14
20
|
/** Raw Lighter WS channel name (e.g. `order_book/5`, `account_all_orders/42`). */
|
|
15
21
|
channel: string;
|
|
@@ -27,11 +33,12 @@ export interface LighterWsProviderOptions {
|
|
|
27
33
|
/** REST base URL for `/api/v1/account` lookups. Defaults to mainnet. */
|
|
28
34
|
restUrl?: string;
|
|
29
35
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
36
|
+
* Override for auth-token resolution on authenticated channels
|
|
37
|
+
* (orderUpdates, positions). Defaults to the co-registered `lighterProvider`
|
|
38
|
+
* plugin's `resolveAuthToken`; supply this only for a standalone WS client
|
|
39
|
+
* with no Lighter REST plugin on the same {@link PerpsSDKClient}.
|
|
33
40
|
*/
|
|
34
|
-
|
|
41
|
+
resolveAuthToken?: LighterAuthTokenResolver;
|
|
35
42
|
}
|
|
36
43
|
/**
|
|
37
44
|
* Lighter realtime WS provider (extends {@link WsProviderBase}): subscribes to
|
|
@@ -42,7 +49,7 @@ export interface LighterWsProviderOptions {
|
|
|
42
49
|
*/
|
|
43
50
|
export declare class LighterWsProvider extends WsProviderBase<SubState> {
|
|
44
51
|
private readonly api;
|
|
45
|
-
private readonly
|
|
52
|
+
private readonly resolveAuthTokenOverride;
|
|
46
53
|
private readonly client;
|
|
47
54
|
private readonly orderbooks;
|
|
48
55
|
private marketsContext;
|
|
@@ -56,6 +63,12 @@ export declare class LighterWsProvider extends WsProviderBase<SubState> {
|
|
|
56
63
|
private readonly accountIndexCache;
|
|
57
64
|
private readonly accountIndexPromises;
|
|
58
65
|
constructor(wsUrl?: string, providerKey?: string, options?: LighterWsProviderOptions, client?: PerpsSDKClient);
|
|
66
|
+
/**
|
|
67
|
+
* Auth-token resolver for gated channels: the explicit `resolveAuthToken`
|
|
68
|
+
* override if supplied, else the co-registered Lighter plugin's
|
|
69
|
+
* `resolveAuthToken`. `undefined` when neither is available.
|
|
70
|
+
*/
|
|
71
|
+
private authTokenResolver;
|
|
59
72
|
subscribeQuote(params: ProviderGetQuoteParams, onQuote: QuoteListener): Promise<() => void>;
|
|
60
73
|
protected openChannel(sub: Subscription): Promise<() => void>;
|
|
61
74
|
protected onClose(): void;
|
|
@@ -84,13 +97,18 @@ export declare class LighterWsProvider extends WsProviderBase<SubState> {
|
|
|
84
97
|
private marketIdFromChannel;
|
|
85
98
|
}
|
|
86
99
|
/**
|
|
87
|
-
* `WsProviderFactory` constructor for Lighter —
|
|
88
|
-
* `new PerpsWsClient(client, { wsProviders: { lighter: lighterWsProvider(
|
|
100
|
+
* `WsProviderFactory` constructor for Lighter — register with
|
|
101
|
+
* `new PerpsWsClient(client, { wsProviders: { lighter: lighterWsProvider() } })`.
|
|
102
|
+
*
|
|
103
|
+
* Bare construction is the default path: authenticated channels resolve their
|
|
104
|
+
* auth token through the `lighterProvider()` plugin co-registered on the same
|
|
105
|
+
* {@link PerpsSDKClient}, so no wiring is needed. Pass `resolveAuthToken` only
|
|
106
|
+
* as the exception — a standalone WS client with no Lighter REST plugin on
|
|
107
|
+
* that client.
|
|
89
108
|
*
|
|
90
|
-
* Closes over the per-instance options (
|
|
91
|
-
* `PerpsWsClient` can call the returned factory with just
|
|
92
|
-
* `({ provider, wsUrl,
|
|
93
|
-
* unused — Lighter advertises a single venue, no sub-DEX filtering.
|
|
109
|
+
* Closes over the per-instance options (`resolveAuthToken` override, `restUrl`)
|
|
110
|
+
* so `PerpsWsClient` can call the returned factory with just
|
|
111
|
+
* `({ provider, wsUrl, client })` at subscribe time.
|
|
94
112
|
*
|
|
95
113
|
* @public
|
|
96
114
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LighterWsProvider.d.ts","sourceRoot":"","sources":["../../../src/websocket/LighterWsProvider.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"LighterWsProvider.d.ts","sourceRoot":"","sources":["../../../src/websocket/LighterWsProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,cAAc,EACnB,KAAK,sBAAsB,EAC3B,KAAK,aAAa,EAIlB,cAAc,EACd,KAAK,iBAAiB,EAEvB,MAAM,iBAAiB,CAAA;AACxB,OAAO,KAAK,EAIV,YAAY,EACb,MAAM,mBAAmB,CAAA;AAC1B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AA2EnC;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,wBAAwB,GAAG,CACrC,OAAO,EAAE,OAAO,KACb,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;AAEhC,UAAU,QAAQ;IAChB,kFAAkF;IAClF,OAAO,EAAE,MAAM,CAAA;IACf,+DAA+D;IAC/D,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,yEAAyE;IACzE,SAAS,EAAE,OAAO,CAAA;CACnB;AAkBD;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC,wEAAwE;IACxE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,wBAAwB,CAAA;CAC5C;AAED;;;;;;GAMG;AACH,qBAAa,iBAAkB,SAAQ,cAAc,CAAC,QAAQ,CAAC;IAC7D,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAkB;IACtC,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAE5B;IACb,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA4B;IAEnD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAoC;IAC/D,OAAO,CAAC,cAAc,CAAoC;IAE1D;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA2C;IAE9E,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA4B;IAErD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA4B;IAC9D,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAqC;gBAGxE,KAAK,GAAE,MAA+B,EACtC,WAAW,SAAY,EACvB,OAAO,GAAE,wBAA6B,EACtC,MAAM,CAAC,EAAE,cAAc;IAsBzB;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAWnB,cAAc,CAClB,MAAM,EAAE,sBAAsB,EAC9B,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,IAAI,CAAC;cAkBN,WAAW,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC;cA4ChD,OAAO,IAAI,IAAI;cAMlB,aAAa,CAAC,EAC5B,OAAO,EACP,SAAS,EACT,OAAO,GACR,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAwB3B,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM;YA2B5B,cAAc;YAsFd,mBAAmB;YAqBnB,iBAAiB;IAK/B,SAAS,CAAC,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAqB1C,OAAO,CAAC,QAAQ;IAkFhB,OAAO,CAAC,mBAAmB;IAgB3B,OAAO,CAAC,eAAe;IA2BvB,OAAO,CAAC,mBAAmB;IAiB3B,OAAO,CAAC,sBAAsB;IAiC9B;;;;;;OAMG;IACH,OAAO,CAAC,kBAAkB;IAuB1B,OAAO,CAAC,iBAAiB;IAuCzB,OAAO,CAAC,eAAe;IA+BvB,OAAO,CAAC,YAAY;IAwBpB,OAAO,CAAC,mBAAmB;CAc5B;AAkID;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,iBAAiB,GAC3B,UAAU,wBAAwB,KAAG,iBAEmB,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lifi/perps-sdk-provider-lighter",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.1",
|
|
4
4
|
"description": "Lighter provider plugin for @lifi/perps-sdk",
|
|
5
5
|
"homepage": "https://github.com/lifinance/perps-sdk",
|
|
6
6
|
"bugs": {
|
|
@@ -46,10 +46,10 @@
|
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"big.js": "^7.0.1",
|
|
48
48
|
"viem": "^2.48.8",
|
|
49
|
-
"@lifi/perps-types": "^2.0.
|
|
49
|
+
"@lifi/perps-types": "^2.0.1"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
|
-
"@lifi/perps-sdk": "^3.
|
|
52
|
+
"@lifi/perps-sdk": "^3.1.1"
|
|
53
53
|
},
|
|
54
54
|
"publishConfig": {
|
|
55
55
|
"access": "public"
|
package/src/index.ts
CHANGED
|
@@ -30,7 +30,7 @@ export { Lighter, lighterProvider } from './LighterProvider.js'
|
|
|
30
30
|
export * from './signers/index.js'
|
|
31
31
|
export * from './types/index.js'
|
|
32
32
|
export * from './utils/index.js'
|
|
33
|
-
export type {
|
|
33
|
+
export type { LighterAuthTokenResolver } from './websocket/LighterWsProvider.js'
|
|
34
34
|
export {
|
|
35
35
|
LighterWsProvider,
|
|
36
36
|
type LighterWsProviderOptions,
|
|
@@ -49,6 +49,12 @@ export interface ChangePubKeyResult extends LighterSignedBlob {
|
|
|
49
49
|
messageToSign: string
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
/** @public */
|
|
53
|
+
export interface ApproveIntegratorResult extends LighterSignedBlob {
|
|
54
|
+
/** EIP-191 `L2ApproveIntegrator` L1 body the user's wallet must countersign to authorize the integrator approval. */
|
|
55
|
+
messageToSign: string
|
|
56
|
+
}
|
|
57
|
+
|
|
52
58
|
/** @public */
|
|
53
59
|
export interface ApiKeyPair {
|
|
54
60
|
publicKey: string
|
|
@@ -133,8 +139,9 @@ export class LighterSigner {
|
|
|
133
139
|
* `WasmBlobActionStep`. Returns the signed `{ txType, txInfo, txHash }`
|
|
134
140
|
* triple the backend forwards to Lighter's `sendTx` endpoint.
|
|
135
141
|
*
|
|
136
|
-
* For REGISTER_API_KEY use `signChangePubKey`
|
|
137
|
-
*
|
|
142
|
+
* For REGISTER_API_KEY use `signChangePubKey` and for APPROVE_INTEGRATOR
|
|
143
|
+
* use `signApproveIntegrator` instead — both return an additional
|
|
144
|
+
* `messageToSign` the L1 wallet must countersign.
|
|
138
145
|
*/
|
|
139
146
|
async sign(
|
|
140
147
|
action: ActionType,
|
|
@@ -147,6 +154,12 @@ export class LighterSigner {
|
|
|
147
154
|
'must be coordinated by the caller.'
|
|
148
155
|
)
|
|
149
156
|
}
|
|
157
|
+
if (action === ActionType.APPROVE_INTEGRATOR) {
|
|
158
|
+
throw new Error(
|
|
159
|
+
'Use signApproveIntegrator() for APPROVE_INTEGRATOR — sign() does ' +
|
|
160
|
+
'not collect the required L1 user wallet signature.'
|
|
161
|
+
)
|
|
162
|
+
}
|
|
150
163
|
const wasm = await this.ensureLoaded()
|
|
151
164
|
await this.ensureClient(context)
|
|
152
165
|
const result = this.dispatch(wasm, action, wasmSignParams, context)
|
|
@@ -211,10 +224,51 @@ export class LighterSigner {
|
|
|
211
224
|
}
|
|
212
225
|
|
|
213
226
|
/**
|
|
214
|
-
*
|
|
215
|
-
*
|
|
216
|
-
*
|
|
217
|
-
*
|
|
227
|
+
* Sign an APPROVE_INTEGRATOR action with the stored API key and return the
|
|
228
|
+
* signed blob alongside the EIP-191 `L2ApproveIntegrator` L1 message the
|
|
229
|
+
* user's Ethereum wallet must countersign. Unlike {@link sign}, this exposes
|
|
230
|
+
* `messageToSign`: Lighter requires `L1Sig` (injected via
|
|
231
|
+
* {@link embedL1Signature} before submission) when the integrator account
|
|
232
|
+
* belongs to a different L1 address with non-zero fee caps.
|
|
233
|
+
*/
|
|
234
|
+
async signApproveIntegrator(
|
|
235
|
+
wasmSignParams: Record<string, unknown>,
|
|
236
|
+
context: LighterSignerContext
|
|
237
|
+
): Promise<ApproveIntegratorResult> {
|
|
238
|
+
const wasm = await this.ensureLoaded()
|
|
239
|
+
await this.ensureClient(context)
|
|
240
|
+
const result = this.dispatch(
|
|
241
|
+
wasm,
|
|
242
|
+
ActionType.APPROVE_INTEGRATOR,
|
|
243
|
+
wasmSignParams,
|
|
244
|
+
context
|
|
245
|
+
)
|
|
246
|
+
if (result.error) {
|
|
247
|
+
throw new Error(`Lighter SignApproveIntegrator failed: ${result.error}`)
|
|
248
|
+
}
|
|
249
|
+
if (
|
|
250
|
+
result.txType === undefined ||
|
|
251
|
+
result.txInfo === undefined ||
|
|
252
|
+
result.txHash === undefined ||
|
|
253
|
+
!result.messageToSign
|
|
254
|
+
) {
|
|
255
|
+
throw new Error(
|
|
256
|
+
'Lighter SignApproveIntegrator returned an incomplete result'
|
|
257
|
+
)
|
|
258
|
+
}
|
|
259
|
+
return {
|
|
260
|
+
txType: result.txType,
|
|
261
|
+
txInfo: result.txInfo,
|
|
262
|
+
txHash: result.txHash,
|
|
263
|
+
messageToSign: result.messageToSign,
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Inject the L1 signature produced by the user's Ethereum wallet into a
|
|
269
|
+
* signed txInfo JSON. `L1Sig` is the only field that depends on the L1
|
|
270
|
+
* signature; txHash does NOT include it (so we do not recompute it). Shared
|
|
271
|
+
* by the REGISTER_API_KEY (ChangePubKey) and APPROVE_INTEGRATOR flows.
|
|
218
272
|
*/
|
|
219
273
|
embedL1Signature(txInfo: string, l1Signature: string): string {
|
|
220
274
|
let parsed: Record<string, unknown>
|
|
@@ -222,7 +276,7 @@ export class LighterSigner {
|
|
|
222
276
|
parsed = JSON.parse(txInfo) as Record<string, unknown>
|
|
223
277
|
} catch (err) {
|
|
224
278
|
throw new Error(
|
|
225
|
-
`Failed to parse
|
|
279
|
+
`Failed to parse signed txInfo as JSON: ${(err as Error).message}`
|
|
226
280
|
)
|
|
227
281
|
}
|
|
228
282
|
parsed.L1Sig = l1Signature
|
|
@@ -291,7 +345,7 @@ export class LighterSigner {
|
|
|
291
345
|
action: ActionType,
|
|
292
346
|
p: Record<string, unknown>,
|
|
293
347
|
ctx: LighterSignerContext
|
|
294
|
-
): SignResult {
|
|
348
|
+
): SignResult & { messageToSign?: string } {
|
|
295
349
|
const nonce = numberField(p, 'nonce')
|
|
296
350
|
switch (action) {
|
|
297
351
|
case ActionType.PLACE_ORDER:
|
|
@@ -81,6 +81,8 @@ export async function signWasmBlobActions(
|
|
|
81
81
|
for (const step of steps) {
|
|
82
82
|
if (step.action === ActionType.REGISTER_API_KEY) {
|
|
83
83
|
signed.push(await signRegisterApiKey(deps, address, step, ctx))
|
|
84
|
+
} else if (step.action === ActionType.APPROVE_INTEGRATOR) {
|
|
85
|
+
signed.push(await signApproveIntegrator(deps, address, step, ctx))
|
|
84
86
|
} else if (
|
|
85
87
|
TOKEN_AUTH_MUTATION_KINDS.has(step.wasmSignParams.kind as string)
|
|
86
88
|
) {
|
|
@@ -196,6 +198,61 @@ async function signRegisterApiKey(
|
|
|
196
198
|
}
|
|
197
199
|
}
|
|
198
200
|
|
|
201
|
+
/**
|
|
202
|
+
* APPROVE_INTEGRATOR flow:
|
|
203
|
+
* 1. Load the user's stored API key (no keypair generation).
|
|
204
|
+
* 2. Wasm-sign the `L2ApproveIntegrator` blob with that key, obtaining the
|
|
205
|
+
* EIP-191 L1 message the wallet must countersign.
|
|
206
|
+
* 3. Have the user's L1 Ethereum wallet sign that message.
|
|
207
|
+
* 4. Inject the L1 signature into the txInfo JSON as `L1Sig`.
|
|
208
|
+
*
|
|
209
|
+
* Requires the end-user's wallet in `ctx.userWallet`: Lighter rejects the tx
|
|
210
|
+
* without the user's `L1Sig` when the integrator account belongs to a
|
|
211
|
+
* different L1 address with non-zero fee caps.
|
|
212
|
+
*/
|
|
213
|
+
async function signApproveIntegrator(
|
|
214
|
+
deps: LighterSignActionsDeps,
|
|
215
|
+
address: Address,
|
|
216
|
+
step: WasmBlobActionStep,
|
|
217
|
+
ctx: SignActionsContext | undefined
|
|
218
|
+
): Promise<WasmBlobSignedActionStep> {
|
|
219
|
+
const walletSigner = ctx?.userWallet
|
|
220
|
+
if (!walletSigner) {
|
|
221
|
+
throw new PerpsError(
|
|
222
|
+
PerpsErrorCode.SDKError,
|
|
223
|
+
'APPROVE_INTEGRATOR requires the end-user wallet — pass `userWallet` to ' +
|
|
224
|
+
'createPerpsClient or call setUserWallet(walletClient).'
|
|
225
|
+
)
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const apiKey = await requireApiKey(deps, address)
|
|
229
|
+
const signed = await deps.signer.signApproveIntegrator(step.wasmSignParams, {
|
|
230
|
+
apiKeyPrivateKey: apiKey.apiKeyPrivateKey,
|
|
231
|
+
apiKeyIndex: apiKey.apiKeyIndex,
|
|
232
|
+
accountIndex: apiKey.accountIndex,
|
|
233
|
+
})
|
|
234
|
+
|
|
235
|
+
const l1Signature = await walletSigner.signMessage({
|
|
236
|
+
account: walletSigner.account,
|
|
237
|
+
message: signed.messageToSign,
|
|
238
|
+
})
|
|
239
|
+
|
|
240
|
+
const txInfoWithL1Sig = deps.signer.embedL1Signature(
|
|
241
|
+
signed.txInfo,
|
|
242
|
+
l1Signature
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
return {
|
|
246
|
+
action: step.action,
|
|
247
|
+
wasmSignParams: step.wasmSignParams,
|
|
248
|
+
signedTx: {
|
|
249
|
+
txType: signed.txType,
|
|
250
|
+
txInfo: txInfoWithL1Sig,
|
|
251
|
+
txHash: signed.txHash,
|
|
252
|
+
},
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
199
256
|
/**
|
|
200
257
|
* Execute a token-authenticated Lighter mutation (`ACCOUNT_TYPE` →
|
|
201
258
|
* `/changeAccountTier`, `SET_REFERRAL` → `/referral/use`) client-side.
|
|
@@ -163,9 +163,13 @@ export interface LighterWasmExports {
|
|
|
163
163
|
* 10 args: integratorAccountIndex, maxPerpsTakerFee, maxPerpsMakerFee,
|
|
164
164
|
* maxSpotTakerFee, maxSpotMakerFee, approvalExpiry, skipNonce, then the
|
|
165
165
|
* trailing three. Fees are uint32 ppm of `FeeTick` (1_000_000); a non-nil
|
|
166
|
-
* fee requires a non-nil integrator index.
|
|
166
|
+
* fee requires a non-nil integrator index. `messageToSign` is the EIP-191
|
|
167
|
+
* `L2ApproveIntegrator` L1 body the user's wallet must countersign — the
|
|
168
|
+
* venue rejects the tx without the resulting `L1Sig`.
|
|
167
169
|
*/
|
|
168
|
-
SignApproveIntegrator: (
|
|
170
|
+
SignApproveIntegrator: (
|
|
171
|
+
...args: unknown[]
|
|
172
|
+
) => SignResult & { messageToSign?: string }
|
|
169
173
|
/**
|
|
170
174
|
* 5 args: accountTradingMode (0 = Classic/Simple, 1 = Unified), skipNonce,
|
|
171
175
|
* then the trailing three. `accountTradingMode` is validated to {0, 1} by
|
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
cachePromise,
|
|
3
3
|
getMarketRegistry,
|
|
4
4
|
type MarketRegistry,
|
|
5
|
+
type PerpsProvider,
|
|
5
6
|
type PerpsSDKClient,
|
|
6
7
|
type ProviderGetQuoteParams,
|
|
7
8
|
type QuoteListener,
|
|
@@ -25,6 +26,7 @@ import {
|
|
|
25
26
|
LIGHTER_BASE_FEE_TIER,
|
|
26
27
|
LIGHTER_PROVIDER_KEY,
|
|
27
28
|
} from '../constants.js'
|
|
29
|
+
import type { LighterPerpsProvider } from '../LighterProvider.js'
|
|
28
30
|
import type {
|
|
29
31
|
LtAccountPosition,
|
|
30
32
|
LtOrder,
|
|
@@ -54,16 +56,16 @@ import {
|
|
|
54
56
|
// Public channels: `marketsContext` (market_stats/all + spot_market_stats/all),
|
|
55
57
|
// `marketContext` (market_stats/N or spot_market_stats/N), `orderbook`
|
|
56
58
|
// (order_book/N), `trades` (trade/N).
|
|
57
|
-
// Authenticated channels (
|
|
59
|
+
// Authenticated channels (resolve an auth token per subscribe send):
|
|
58
60
|
// - orderUpdates → account_all_orders/{account_index}
|
|
59
61
|
// - fills → account_all_trades/{account_index}
|
|
60
62
|
// - positions → account_all_positions/{account_index}
|
|
61
63
|
//
|
|
62
64
|
// Auth pattern (per Lighter WS spec): the subscribe payload carries the
|
|
63
65
|
// token directly — `{ type: "subscribe", channel: "...", auth: "<token>" }`.
|
|
64
|
-
//
|
|
65
|
-
//
|
|
66
|
-
//
|
|
66
|
+
// The token is resolved per send (default: the co-registered `lighterProvider`
|
|
67
|
+
// plugin's `resolveAuthToken`), so reconnects after the original token expires
|
|
68
|
+
// automatically pick up a fresh one.
|
|
67
69
|
//
|
|
68
70
|
// account_index is resolved per-address via `/api/v1/account?by=l1_address`
|
|
69
71
|
// and cached for the lifetime of the provider — Lighter's account index is
|
|
@@ -93,14 +95,20 @@ function channelNeedsMarkets(channel: Subscription['channel']): boolean {
|
|
|
93
95
|
}
|
|
94
96
|
|
|
95
97
|
/**
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
98
|
+
* Resolves a Lighter auth token for the given L1 address, or `undefined` when
|
|
99
|
+
* no source can produce one. Called on the initial subscribe and again on
|
|
100
|
+
* every reconnect, so it must return a token still valid a few minutes out.
|
|
101
|
+
*
|
|
102
|
+
* The default resolver — the co-registered `lighterProvider` plugin's
|
|
103
|
+
* `resolveAuthToken` — satisfies that: it never yields an expired token.
|
|
104
|
+
* Stored read-only tokens past expiry are filtered out and otherwise carry a
|
|
105
|
+
* ~10-year lifetime; near-expiry standard tokens are re-created within their
|
|
106
|
+
* renew buffer; and a server-rejected token self-heals on the next resolve. A
|
|
107
|
+
* supplied override owns its own freshness.
|
|
100
108
|
*
|
|
101
109
|
* @public
|
|
102
110
|
*/
|
|
103
|
-
export type
|
|
111
|
+
export type LighterAuthTokenResolver = (
|
|
104
112
|
address: Address
|
|
105
113
|
) => Promise<string | undefined>
|
|
106
114
|
|
|
@@ -138,11 +146,12 @@ export interface LighterWsProviderOptions {
|
|
|
138
146
|
/** REST base URL for `/api/v1/account` lookups. Defaults to mainnet. */
|
|
139
147
|
restUrl?: string
|
|
140
148
|
/**
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
149
|
+
* Override for auth-token resolution on authenticated channels
|
|
150
|
+
* (orderUpdates, positions). Defaults to the co-registered `lighterProvider`
|
|
151
|
+
* plugin's `resolveAuthToken`; supply this only for a standalone WS client
|
|
152
|
+
* with no Lighter REST plugin on the same {@link PerpsSDKClient}.
|
|
144
153
|
*/
|
|
145
|
-
|
|
154
|
+
resolveAuthToken?: LighterAuthTokenResolver
|
|
146
155
|
}
|
|
147
156
|
|
|
148
157
|
/**
|
|
@@ -154,7 +163,9 @@ export interface LighterWsProviderOptions {
|
|
|
154
163
|
*/
|
|
155
164
|
export class LighterWsProvider extends WsProviderBase<SubState> {
|
|
156
165
|
private readonly api: LighterApiClient
|
|
157
|
-
private readonly
|
|
166
|
+
private readonly resolveAuthTokenOverride:
|
|
167
|
+
| LighterAuthTokenResolver
|
|
168
|
+
| undefined
|
|
158
169
|
private readonly client: PerpsSDKClient | undefined
|
|
159
170
|
|
|
160
171
|
private readonly orderbooks = new Map<number, OrderbookState>()
|
|
@@ -193,11 +204,27 @@ export class LighterWsProvider extends WsProviderBase<SubState> {
|
|
|
193
204
|
fetchImpl: client?.config.fetch,
|
|
194
205
|
}
|
|
195
206
|
)
|
|
196
|
-
this.
|
|
207
|
+
this.resolveAuthTokenOverride = options.resolveAuthToken
|
|
197
208
|
this.client = client
|
|
198
209
|
this.registry = client && getMarketRegistry(client, providerKey)
|
|
199
210
|
}
|
|
200
211
|
|
|
212
|
+
/**
|
|
213
|
+
* Auth-token resolver for gated channels: the explicit `resolveAuthToken`
|
|
214
|
+
* override if supplied, else the co-registered Lighter plugin's
|
|
215
|
+
* `resolveAuthToken`. `undefined` when neither is available.
|
|
216
|
+
*/
|
|
217
|
+
private authTokenResolver(): LighterAuthTokenResolver | undefined {
|
|
218
|
+
if (this.resolveAuthTokenOverride !== undefined) {
|
|
219
|
+
return this.resolveAuthTokenOverride
|
|
220
|
+
}
|
|
221
|
+
const provider = this.client?.getProvider(this.providerKey)
|
|
222
|
+
if (provider !== undefined && hasAuthTokenResolver(provider)) {
|
|
223
|
+
return (address) => provider.resolveAuthToken(address)
|
|
224
|
+
}
|
|
225
|
+
return undefined
|
|
226
|
+
}
|
|
227
|
+
|
|
201
228
|
async subscribeQuote(
|
|
202
229
|
params: ProviderGetQuoteParams,
|
|
203
230
|
onQuote: QuoteListener
|
|
@@ -279,12 +306,14 @@ export class LighterWsProvider extends WsProviderBase<SubState> {
|
|
|
279
306
|
channel,
|
|
280
307
|
}
|
|
281
308
|
if (needsAuth) {
|
|
282
|
-
|
|
309
|
+
const resolve = this.authTokenResolver()
|
|
310
|
+
if (!resolve || !address) {
|
|
283
311
|
throw new Error(
|
|
284
|
-
`Lighter WS channel '${channel}' requires authentication but no
|
|
312
|
+
`Lighter WS channel '${channel}' requires authentication but no auth-token resolver was available. ` +
|
|
313
|
+
'Register `lighterProvider()` on the same client, or pass `resolveAuthToken` to `lighterWsProvider`.'
|
|
285
314
|
)
|
|
286
315
|
}
|
|
287
|
-
const token = await
|
|
316
|
+
const token = await resolve(address)
|
|
288
317
|
if (!token) {
|
|
289
318
|
throw new Error(
|
|
290
319
|
`Lighter WS channel '${channel}' requires authentication but no token was available for ${address}.`
|
|
@@ -770,6 +799,20 @@ export class LighterWsProvider extends WsProviderBase<SubState> {
|
|
|
770
799
|
}
|
|
771
800
|
}
|
|
772
801
|
|
|
802
|
+
/**
|
|
803
|
+
* Narrow a co-registered {@link PerpsProvider} to the Lighter plugin that
|
|
804
|
+
* exposes `resolveAuthToken`. The base plugin contract is provider-agnostic,
|
|
805
|
+
* so the WS layer must feature-detect rather than assume the capability.
|
|
806
|
+
*/
|
|
807
|
+
function hasAuthTokenResolver(
|
|
808
|
+
provider: PerpsProvider
|
|
809
|
+
): provider is LighterPerpsProvider {
|
|
810
|
+
return (
|
|
811
|
+
'resolveAuthToken' in provider &&
|
|
812
|
+
typeof (provider as LighterPerpsProvider).resolveAuthToken === 'function'
|
|
813
|
+
)
|
|
814
|
+
}
|
|
815
|
+
|
|
773
816
|
const isObject = (v: unknown): v is Record<string, unknown> =>
|
|
774
817
|
typeof v === 'object' && v !== null
|
|
775
818
|
|
|
@@ -885,13 +928,18 @@ function collectAuthChannelItems<T>(
|
|
|
885
928
|
}
|
|
886
929
|
|
|
887
930
|
/**
|
|
888
|
-
* `WsProviderFactory` constructor for Lighter —
|
|
889
|
-
* `new PerpsWsClient(client, { wsProviders: { lighter: lighterWsProvider(
|
|
931
|
+
* `WsProviderFactory` constructor for Lighter — register with
|
|
932
|
+
* `new PerpsWsClient(client, { wsProviders: { lighter: lighterWsProvider() } })`.
|
|
933
|
+
*
|
|
934
|
+
* Bare construction is the default path: authenticated channels resolve their
|
|
935
|
+
* auth token through the `lighterProvider()` plugin co-registered on the same
|
|
936
|
+
* {@link PerpsSDKClient}, so no wiring is needed. Pass `resolveAuthToken` only
|
|
937
|
+
* as the exception — a standalone WS client with no Lighter REST plugin on
|
|
938
|
+
* that client.
|
|
890
939
|
*
|
|
891
|
-
* Closes over the per-instance options (
|
|
892
|
-
* `PerpsWsClient` can call the returned factory with just
|
|
893
|
-
* `({ provider, wsUrl,
|
|
894
|
-
* unused — Lighter advertises a single venue, no sub-DEX filtering.
|
|
940
|
+
* Closes over the per-instance options (`resolveAuthToken` override, `restUrl`)
|
|
941
|
+
* so `PerpsWsClient` can call the returned factory with just
|
|
942
|
+
* `({ provider, wsUrl, client })` at subscribe time.
|
|
895
943
|
*
|
|
896
944
|
* @public
|
|
897
945
|
*/
|