phantasma-sdk-ts 0.9.2 → 0.10.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.
Files changed (75) hide show
  1. package/README.md +6 -0
  2. package/dist/cjs/index.js +3 -1
  3. package/dist/cjs/link/index.js +5 -0
  4. package/dist/cjs/link/v5/capabilities.js +6 -0
  5. package/dist/cjs/link/v5/client.js +324 -0
  6. package/dist/cjs/link/v5/deeplink.js +123 -0
  7. package/dist/cjs/link/v5/encoding.js +95 -0
  8. package/dist/cjs/link/v5/envelope.js +73 -0
  9. package/dist/cjs/link/v5/errors.js +60 -0
  10. package/dist/cjs/link/v5/index.js +33 -0
  11. package/dist/cjs/link/v5/loopback-transport.js +70 -0
  12. package/dist/cjs/link/v5/methods.js +4 -0
  13. package/dist/cjs/link/v5/pairing.js +95 -0
  14. package/dist/cjs/link/v5/protocol.js +61 -0
  15. package/dist/cjs/link/v5/relay-transport.js +303 -0
  16. package/dist/cjs/link/v5/session-crypto.js +120 -0
  17. package/dist/cjs/link/v5/transport.js +208 -0
  18. package/dist/cjs/link/v5/web-deeplink.js +141 -0
  19. package/dist/cjs/public.js +37 -1
  20. package/dist/esm/index.js +2 -0
  21. package/dist/esm/link/index.js +5 -0
  22. package/dist/esm/link/v5/capabilities.js +5 -0
  23. package/dist/esm/link/v5/client.js +320 -0
  24. package/dist/esm/link/v5/deeplink.js +115 -0
  25. package/dist/esm/link/v5/encoding.js +87 -0
  26. package/dist/esm/link/v5/envelope.js +65 -0
  27. package/dist/esm/link/v5/errors.js +56 -0
  28. package/dist/esm/link/v5/index.js +17 -0
  29. package/dist/esm/link/v5/loopback-transport.js +66 -0
  30. package/dist/esm/link/v5/methods.js +3 -0
  31. package/dist/esm/link/v5/pairing.js +91 -0
  32. package/dist/esm/link/v5/protocol.js +58 -0
  33. package/dist/esm/link/v5/relay-transport.js +299 -0
  34. package/dist/esm/link/v5/session-crypto.js +104 -0
  35. package/dist/esm/link/v5/transport.js +204 -0
  36. package/dist/esm/link/v5/web-deeplink.js +133 -0
  37. package/dist/esm/public.js +3 -0
  38. package/dist/types/index.d.ts +1 -0
  39. package/dist/types/index.d.ts.map +1 -1
  40. package/dist/types/link/v5/capabilities.d.ts +80 -0
  41. package/dist/types/link/v5/capabilities.d.ts.map +1 -0
  42. package/dist/types/link/v5/client.d.ts +119 -0
  43. package/dist/types/link/v5/client.d.ts.map +1 -0
  44. package/dist/types/link/v5/deeplink.d.ts +52 -0
  45. package/dist/types/link/v5/deeplink.d.ts.map +1 -0
  46. package/dist/types/link/v5/encoding.d.ts +15 -0
  47. package/dist/types/link/v5/encoding.d.ts.map +1 -0
  48. package/dist/types/link/v5/envelope.d.ts +48 -0
  49. package/dist/types/link/v5/envelope.d.ts.map +1 -0
  50. package/dist/types/link/v5/errors.d.ts +39 -0
  51. package/dist/types/link/v5/errors.d.ts.map +1 -0
  52. package/dist/types/link/v5/index.d.ts +15 -0
  53. package/dist/types/link/v5/index.d.ts.map +1 -0
  54. package/dist/types/link/v5/loopback-transport.d.ts +43 -0
  55. package/dist/types/link/v5/loopback-transport.d.ts.map +1 -0
  56. package/dist/types/link/v5/methods.d.ts +83 -0
  57. package/dist/types/link/v5/methods.d.ts.map +1 -0
  58. package/dist/types/link/v5/pairing.d.ts +37 -0
  59. package/dist/types/link/v5/pairing.d.ts.map +1 -0
  60. package/dist/types/link/v5/protocol.d.ts +60 -0
  61. package/dist/types/link/v5/protocol.d.ts.map +1 -0
  62. package/dist/types/link/v5/relay-transport.d.ts +73 -0
  63. package/dist/types/link/v5/relay-transport.d.ts.map +1 -0
  64. package/dist/types/link/v5/session-crypto.d.ts +51 -0
  65. package/dist/types/link/v5/session-crypto.d.ts.map +1 -0
  66. package/dist/types/link/v5/transport.d.ts +77 -0
  67. package/dist/types/link/v5/transport.d.ts.map +1 -0
  68. package/dist/types/link/v5/web-deeplink.d.ts +77 -0
  69. package/dist/types/link/v5/web-deeplink.d.ts.map +1 -0
  70. package/dist/types/public.d.ts +1 -0
  71. package/dist/types/public.d.ts.map +1 -1
  72. package/examples/web-deeplink-dapp.ts +53 -0
  73. package/package.json +8 -2
  74. package/spec/CHANGELOG.md +9 -0
  75. package/spec/phantasma-link-v5.md +701 -0
@@ -0,0 +1,48 @@
1
+ import { PLV } from './protocol.js';
2
+ import { LinkErrorObject } from './errors.js';
3
+ /** Request: dApp -> wallet. `session` is omitted only on the first `pha_connect`. */
4
+ export interface LinkRequest {
5
+ plv: typeof PLV;
6
+ id: string;
7
+ session?: string;
8
+ method: string;
9
+ params?: Record<string, unknown>;
10
+ }
11
+ /** Success response: wallet -> dApp. */
12
+ export interface LinkSuccessResponse {
13
+ plv: typeof PLV;
14
+ id: string;
15
+ result: unknown;
16
+ }
17
+ /** Error response: wallet -> dApp. */
18
+ export interface LinkErrorResponse {
19
+ plv: typeof PLV;
20
+ id: string;
21
+ error: LinkErrorObject;
22
+ }
23
+ export type LinkResponse = LinkSuccessResponse | LinkErrorResponse;
24
+ /** Event: wallet -> dApp, no reply expected (spec §9.5; persistent transports only). */
25
+ export interface LinkEventMessage {
26
+ plv: typeof PLV;
27
+ type: 'event';
28
+ session?: string;
29
+ event: string;
30
+ data?: unknown;
31
+ }
32
+ export type LinkMessage = LinkRequest | LinkResponse | LinkEventMessage;
33
+ export declare function isLinkRequest(msg: LinkMessage): msg is LinkRequest;
34
+ export declare function isLinkEvent(msg: LinkMessage): msg is LinkEventMessage;
35
+ export declare function isLinkErrorResponse(msg: LinkMessage): msg is LinkErrorResponse;
36
+ export declare function isLinkSuccessResponse(msg: LinkMessage): msg is LinkSuccessResponse;
37
+ /** Serialize an envelope to its on-the-wire JSON text. */
38
+ export declare function encodeEnvelope(message: LinkMessage): string;
39
+ /**
40
+ * Parse and validate an on-the-wire JSON text into a {@link LinkMessage}.
41
+ *
42
+ * Throws {@link LinkError} with `ParseError` for non-JSON and `InvalidRequest` for a JSON
43
+ * value that is not a well-formed v5 envelope (wrong `plv`, missing `id`, or a shape that
44
+ * is neither request, response, nor event). Validation happens here, once, so every
45
+ * downstream consumer can trust the structure.
46
+ */
47
+ export declare function decodeEnvelope(text: string): LinkMessage;
48
+ //# sourceMappingURL=envelope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"envelope.d.ts","sourceRoot":"","sources":["../../../../src/link/v5/envelope.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,OAAO,EAA4B,eAAe,EAAE,MAAM,aAAa,CAAC;AAExE,qFAAqF;AACrF,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,OAAO,GAAG,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,wCAAwC;AACxC,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,OAAO,GAAG,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,sCAAsC;AACtC,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,OAAO,GAAG,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,eAAe,CAAC;CACxB;AAED,MAAM,MAAM,YAAY,GAAG,mBAAmB,GAAG,iBAAiB,CAAC;AAEnE,wFAAwF;AACxF,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,OAAO,GAAG,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,YAAY,GAAG,gBAAgB,CAAC;AAExE,wBAAgB,aAAa,CAAC,GAAG,EAAE,WAAW,GAAG,GAAG,IAAI,WAAW,CAElE;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,WAAW,GAAG,GAAG,IAAI,gBAAgB,CAErE;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,WAAW,GAAG,GAAG,IAAI,iBAAiB,CAE9E;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,WAAW,GAAG,GAAG,IAAI,mBAAmB,CAElF;AAED,0DAA0D;AAC1D,wBAAgB,cAAc,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAE3D;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CA8CxD"}
@@ -0,0 +1,39 @@
1
+ /** Numeric error codes. JSON-RPC reserved range + EIP-1193-aligned app codes + Phantasma
2
+ * specific codes. Carried in {@link LinkErrorObject.code}. */
3
+ export declare const LinkErrorCode: {
4
+ readonly ParseError: -32700;
5
+ readonly InvalidRequest: -32600;
6
+ readonly MethodNotFound: -32601;
7
+ readonly InvalidParams: -32602;
8
+ readonly InternalError: -32603;
9
+ readonly UserRejected: 4001;
10
+ readonly Unauthorized: 4100;
11
+ readonly Disconnected: 4900;
12
+ readonly UnsupportedChain: 4902;
13
+ readonly PayloadTooLarge: 5001;
14
+ readonly NexusMismatch: 5002;
15
+ readonly UnsupportedSignatureKind: 5003;
16
+ readonly CapabilityNotSupported: 5004;
17
+ readonly SessionExpired: 5100;
18
+ readonly SessionRevoked: 5101;
19
+ };
20
+ export type LinkErrorCode = (typeof LinkErrorCode)[keyof typeof LinkErrorCode];
21
+ /** The `error` member of an error response envelope (spec §4). */
22
+ export interface LinkErrorObject {
23
+ code: number;
24
+ message: string;
25
+ data?: unknown;
26
+ }
27
+ /** Error thrown by the v5 client and carried over the wire as {@link LinkErrorObject}.
28
+ * Keeping a dedicated class lets callers branch on the numeric `code` instead of parsing
29
+ * message text. */
30
+ export declare class LinkError extends Error {
31
+ readonly code: number;
32
+ readonly data?: unknown;
33
+ constructor(code: number, message: string, data?: unknown);
34
+ toObject(): LinkErrorObject;
35
+ /** Reconstruct a {@link LinkError} from a received error object, tolerating malformed
36
+ * inputs (a peer may send a non-conforming shape). */
37
+ static fromObject(obj: unknown): LinkError;
38
+ }
39
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../../src/link/v5/errors.ts"],"names":[],"mappings":"AAGA;8DAC8D;AAC9D,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;CAmBhB,CAAC;AACX,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,OAAO,aAAa,CAAC,CAAC;AAE/E,kEAAkE;AAClE,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;mBAEmB;AACnB,qBAAa,SAAU,SAAQ,KAAK;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;gBAEZ,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO;IASzD,QAAQ,IAAI,eAAe;IAO3B;0DACsD;IACtD,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,SAAS;CAY3C"}
@@ -0,0 +1,15 @@
1
+ export * from './protocol.js';
2
+ export * from './errors.js';
3
+ export * from './encoding.js';
4
+ export * from './envelope.js';
5
+ export * from './capabilities.js';
6
+ export * from './methods.js';
7
+ export * from './session-crypto.js';
8
+ export * from './pairing.js';
9
+ export * from './transport.js';
10
+ export * from './loopback-transport.js';
11
+ export * from './deeplink.js';
12
+ export * from './relay-transport.js';
13
+ export * from './web-deeplink.js';
14
+ export * from './client.js';
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/link/v5/index.ts"],"names":[],"mappings":"AAIA,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC;AACpC,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,yBAAyB,CAAC;AACxC,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC"}
@@ -0,0 +1,43 @@
1
+ import { LinkTransport } from './transport.js';
2
+ /** Minimal WebSocket surface the transport needs - satisfied by the browser `WebSocket`,
3
+ * the Node `ws` package, or a test double. */
4
+ export interface WebSocketLike {
5
+ readonly readyState: number;
6
+ send(data: string): void;
7
+ close(code?: number, reason?: string): void;
8
+ onopen: ((event: unknown) => void) | null;
9
+ onmessage: ((event: {
10
+ data: unknown;
11
+ }) => void) | null;
12
+ onclose: ((event: {
13
+ reason?: string;
14
+ wasClean?: boolean;
15
+ }) => void) | null;
16
+ onerror: ((event: unknown) => void) | null;
17
+ }
18
+ export type WebSocketFactory = (url: string) => WebSocketLike;
19
+ export interface LoopbackTransportOptions {
20
+ /** Default `localhost`. */
21
+ host?: string;
22
+ /** Default `7090` (the wallet link port). */
23
+ port?: number;
24
+ /** Default `/phantasma/v5` (separate from the legacy `/phantasma`). */
25
+ path?: string;
26
+ /** Override the WebSocket implementation (Node / tests). Defaults to global `WebSocket`. */
27
+ webSocketFactory?: WebSocketFactory;
28
+ }
29
+ /** A {@link LinkTransport} over a local WebSocket to the wallet. Sends are buffered until the
30
+ * socket opens, then flushed, so callers can issue requests immediately after construction. */
31
+ export declare class LoopbackTransport implements LinkTransport {
32
+ private readonly socket;
33
+ private messageHandler?;
34
+ private closeHandler?;
35
+ private readonly outbox;
36
+ private isOpen;
37
+ constructor(options?: LoopbackTransportOptions);
38
+ send(frame: string): void;
39
+ onMessage(handler: (frame: string) => void): void;
40
+ onClose(handler: (reason?: string) => void): void;
41
+ close(): void;
42
+ }
43
+ //# sourceMappingURL=loopback-transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loopback-transport.d.ts","sourceRoot":"","sources":["../../../../src/link/v5/loopback-transport.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAG/C;8CAC8C;AAC9C,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,MAAM,EAAE,CAAC,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1C,SAAS,EAAE,CAAC,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IACvD,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IAC3E,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;CAC5C;AAED,MAAM,MAAM,gBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,aAAa,CAAC;AAE9D,MAAM,WAAW,wBAAwB;IACvC,2BAA2B;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4FAA4F;IAC5F,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CACrC;AAaD;+FAC+F;AAC/F,qBAAa,iBAAkB,YAAW,aAAa;IACrD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,cAAc,CAAC,CAA0B;IACjD,OAAO,CAAC,YAAY,CAAC,CAA4B;IACjD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,MAAM,CAAS;gBAEX,OAAO,GAAE,wBAA6B;IA4BlD,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAQzB,SAAS,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAIjD,OAAO,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAIjD,KAAK,IAAI,IAAI;CAOd"}
@@ -0,0 +1,83 @@
1
+ import { ProofOfWork } from '../interfaces/proof-of-work.js';
2
+ import { TxFormat, SignatureKind } from './protocol.js';
3
+ import { LinkAccountV5, WalletInfo } from './capabilities.js';
4
+ export type Base64 = string;
5
+ /** {@link LinkMethod.Disconnect}: idempotent - closing an unknown session still succeeds. */
6
+ export type DisconnectParams = Record<string, never>;
7
+ export interface DisconnectResult {
8
+ ok: true;
9
+ }
10
+ /** {@link LinkMethod.GetAccounts}: only the account(s) authorized for THIS session. */
11
+ export type GetAccountsParams = Record<string, never>;
12
+ export interface GetAccountsResult {
13
+ accounts: LinkAccountV5[];
14
+ }
15
+ /** {@link LinkMethod.GetChains}. */
16
+ export type GetChainsParams = Record<string, never>;
17
+ export interface GetChainsResult {
18
+ /** Supported chains as CAIP-2-like ids. */
19
+ chains: string[];
20
+ /** Currently selected chain id. */
21
+ current: string;
22
+ /** The Phantasma nexus name (domain term kept as a field). */
23
+ nexus: string;
24
+ }
25
+ /** {@link LinkMethod.GetWalletInfo}. */
26
+ export type GetWalletInfoParams = Record<string, never>;
27
+ export type GetWalletInfoResult = WalletInfo;
28
+ /** {@link LinkMethod.SignMessage}: non-transaction-forgeable (spec §8). */
29
+ export interface SignMessageParams {
30
+ /** The message bytes to sign, base64. */
31
+ message: Base64;
32
+ /** Optional human-readable hint the wallet may show instead of raw bytes. */
33
+ display?: string;
34
+ signatureKind?: SignatureKind;
35
+ }
36
+ export interface SignMessageResult {
37
+ /** The signature, base64. */
38
+ signature: Base64;
39
+ /** The 32 random bytes the wallet prepended (base64); needed to reconstruct the signed
40
+ * payload `DOMAIN_TAG || random || message` for verification. */
41
+ random: Base64;
42
+ }
43
+ /** Common fields for the two transaction methods. `format` selects the RPC endpoint
44
+ * (spec §9.4); `pow` is meaningful only for `format: "script"` (spec §9.5). */
45
+ export interface TransactionParams {
46
+ format: TxFormat;
47
+ /** The serialized (unsigned) transaction bytes, base64. */
48
+ tx: Base64;
49
+ signatureKind?: SignatureKind;
50
+ pow?: ProofOfWork;
51
+ }
52
+ /** {@link LinkMethod.SignTransaction}: sign only, return the assembled signed tx. */
53
+ export type SignTransactionParams = TransactionParams;
54
+ export interface SignTransactionResult {
55
+ /** The signed transaction bytes, base64; the dApp broadcasts it itself. */
56
+ signedTx: Base64;
57
+ }
58
+ /** {@link LinkMethod.SendTransaction}: sign AND broadcast via the format's RPC endpoint. */
59
+ export type SendTransactionParams = TransactionParams;
60
+ export interface SendTransactionResult {
61
+ /** The broadcast transaction hash. */
62
+ hash: string;
63
+ }
64
+ /** {@link LinkMethod.InvokeScript}: read-only VM invoke (no keys, no approval). */
65
+ export interface InvokeScriptParams {
66
+ chain: string;
67
+ /** The raw VM script bytes, base64. */
68
+ script: Base64;
69
+ }
70
+ export interface InvokeScriptResult {
71
+ /** Decoded VM result objects (hex/encoded values, as the node returns them). */
72
+ results: string[];
73
+ }
74
+ export interface AccountsChangedData {
75
+ accounts: LinkAccountV5[];
76
+ }
77
+ export interface ChainChangedData {
78
+ chain: string;
79
+ }
80
+ export interface SessionLifecycleData {
81
+ session: string;
82
+ }
83
+ //# sourceMappingURL=methods.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"methods.d.ts","sourceRoot":"","sources":["../../../../src/link/v5/methods.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE9D,MAAM,MAAM,MAAM,GAAG,MAAM,CAAC;AAI5B,6FAA6F;AAC7F,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AACrD,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,IAAI,CAAC;CACV;AAED,uFAAuF;AACvF,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AACtD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC3B;AAED,oCAAoC;AACpC,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AACpD,MAAM,WAAW,eAAe;IAC9B,2CAA2C;IAC3C,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wCAAwC;AACxC,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AACxD,MAAM,MAAM,mBAAmB,GAAG,UAAU,CAAC;AAE7C,2EAA2E;AAC3E,MAAM,WAAW,iBAAiB;IAChC,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,6EAA6E;IAC7E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B;AACD,MAAM,WAAW,iBAAiB;IAChC,6BAA6B;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB;qEACiE;IACjE,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;+EAC+E;AAC/E,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,QAAQ,CAAC;IACjB,2DAA2D;IAC3D,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,GAAG,CAAC,EAAE,WAAW,CAAC;CACnB;AAED,qFAAqF;AACrF,MAAM,MAAM,qBAAqB,GAAG,iBAAiB,CAAC;AACtD,MAAM,WAAW,qBAAqB;IACpC,2EAA2E;IAC3E,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,4FAA4F;AAC5F,MAAM,MAAM,qBAAqB,GAAG,iBAAiB,CAAC;AACtD,MAAM,WAAW,qBAAqB;IACpC,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,mFAAmF;AACnF,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;CAChB;AACD,MAAM,WAAW,kBAAkB;IACjC,gFAAgF;IAChF,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAID,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC3B;AACD,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;CACf;AACD,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;CACjB"}
@@ -0,0 +1,37 @@
1
+ import { DappMetadata } from './capabilities.js';
2
+ export type PairingMode = 'sym' | 'ecdh';
3
+ /** Parsed pairing material. */
4
+ export interface PairingParams {
5
+ version: number;
6
+ topic: string;
7
+ relay?: string;
8
+ mode: PairingMode;
9
+ /** Present when `mode === 'sym'`. */
10
+ symKey?: Uint8Array;
11
+ /** Present when `mode === 'ecdh'`. */
12
+ dappPublicKey?: Uint8Array;
13
+ /** Where the wallet opens response deeplinks for this pairing (spec §17). */
14
+ callback?: string;
15
+ meta?: DappMetadata;
16
+ }
17
+ /** Input to {@link buildPairingUri}. */
18
+ export interface BuildPairingUriInput {
19
+ topic: string;
20
+ mode: PairingMode;
21
+ symKey?: Uint8Array;
22
+ dappPublicKey?: Uint8Array;
23
+ relay?: string;
24
+ /** dApp URL the wallet opens to deliver deeplink responses (required for deeplink use). */
25
+ callback?: string;
26
+ meta?: DappMetadata;
27
+ /** `universal` (default) => `https://<host>/v5/pair`; `scheme` => `phantasma://v5/pair`. */
28
+ scheme?: 'universal' | 'scheme';
29
+ /** Universal-link host; defaults to {@link DEFAULT_LINK_HOST}. */
30
+ host?: string;
31
+ }
32
+ /** Build a pairing URI. Enforces the security rule that a symmetric key (a secret) must
33
+ * NOT be placed in a hijackable custom-scheme URL (spec §15/§18). */
34
+ export declare function buildPairingUri(input: BuildPairingUriInput): string;
35
+ /** Parse a pairing URI (universal-link or custom-scheme) into {@link PairingParams}. */
36
+ export declare function parsePairingUri(uri: string): PairingParams;
37
+ //# sourceMappingURL=pairing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pairing.d.ts","sourceRoot":"","sources":["../../../../src/link/v5/pairing.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGjD,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,MAAM,CAAC;AAEzC,+BAA+B;AAC/B,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,WAAW,CAAC;IAClB,qCAAqC;IACrC,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,sCAAsC;IACtC,aAAa,CAAC,EAAE,UAAU,CAAC;IAC3B,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,YAAY,CAAC;CACrB;AAED,wCAAwC;AACxC,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,WAAW,CAAC;IAClB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,aAAa,CAAC,EAAE,UAAU,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2FAA2F;IAC3F,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,4FAA4F;IAC5F,MAAM,CAAC,EAAE,WAAW,GAAG,QAAQ,CAAC;IAChC,kEAAkE;IAClE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;qEACqE;AACrE,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,MAAM,CA0CnE;AAED,wFAAwF;AACxF,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAkD1D"}
@@ -0,0 +1,60 @@
1
+ /** Protocol version carried in every v5 envelope (`plv`). A peer that does not recognize
2
+ * this value rejects the message with {@link LinkErrorCode.InvalidRequest}. */
3
+ export declare const PLV: 5;
4
+ /** Default subdomain that hosts the universal links + AASA/assetlinks + relay (spec §17).
5
+ * NEVER `phantasma.io` (hostile). */
6
+ export declare const DEFAULT_LINK_HOST = "link.phantasma.info";
7
+ /** Request methods (dApp -> wallet). Namespaced `pha_*`, EIP-1193-aligned (spec §9). */
8
+ export declare const LinkMethod: {
9
+ /** Pair or resume a session; returns the capability handshake + account + session. */
10
+ readonly Connect: "pha_connect";
11
+ /** End the session. */
12
+ readonly Disconnect: "pha_disconnect";
13
+ /** Account(s) authorized for this session. */
14
+ readonly GetAccounts: "pha_getAccounts";
15
+ /** Supported chains (CAIP-2) + current; `nexus` as a field. */
16
+ readonly GetChains: "pha_getChains";
17
+ /** Wallet name/version/capabilities/rpc. */
18
+ readonly GetWalletInfo: "pha_getWalletInfo";
19
+ /** Sign an arbitrary, non-transaction-forgeable message. */
20
+ readonly SignMessage: "pha_signMessage";
21
+ /** Sign a transaction only (do NOT broadcast); the dApp submits it. */
22
+ readonly SignTransaction: "pha_signTransaction";
23
+ /** Sign AND broadcast a transaction via the format's RPC endpoint. */
24
+ readonly SendTransaction: "pha_sendTransaction";
25
+ /** Read-only VM invoke (no keys, no approval). */
26
+ readonly InvokeScript: "pha_invokeScript";
27
+ };
28
+ export type LinkMethod = (typeof LinkMethod)[keyof typeof LinkMethod];
29
+ /** Event names pushed wallet -> dApp on a persistent transport (spec §9.5 events caveat). */
30
+ export declare const LinkEvent: {
31
+ readonly AccountsChanged: "pha_accountsChanged";
32
+ readonly ChainChanged: "pha_chainChanged";
33
+ readonly SessionDeleted: "pha_sessionDeleted";
34
+ readonly SessionExpired: "pha_sessionExpired";
35
+ /** Unsolicited connect result pushed right after a pairing approval (spec §15 step 3),
36
+ * letting the first connection complete in one user gesture. Unlike the other events it
37
+ * also rides the deeplink transport: the wallet is foreground at the approval moment, so
38
+ * it CAN open the callback (this is a reply to the pairing, not a spontaneous push).
39
+ * `data` carries the same shape as a `pha_connect` result. */
40
+ readonly SessionEstablished: "pha_sessionEstablished";
41
+ };
42
+ export type LinkEvent = (typeof LinkEvent)[keyof typeof LinkEvent];
43
+ /** Transaction serialization format. Selects which RPC submission endpoint the wallet uses
44
+ * (spec §9.4): `script` -> SendRawTransaction (classic `Transaction`), `carbon` ->
45
+ * SendCarbonTransaction (Carbon `SignedTxMsg`). Routing is by serialization envelope, NOT
46
+ * by "contains a script" (a Carbon tx may also wrap a script). */
47
+ export declare const TxFormat: {
48
+ readonly Script: "script";
49
+ readonly Carbon: "carbon";
50
+ };
51
+ export type TxFormat = (typeof TxFormat)[keyof typeof TxFormat];
52
+ /** Signature scheme used to sign a Phantasma payload (spec §9.7). Selects the key:
53
+ * `Ed25519` = the Phantasma key, `ECDSA` = the secp256k1 (ETH/BSC-interop) key. This is
54
+ * NOT native foreign-chain signing - the wallet always targets Phantasma. */
55
+ export declare const SignatureKind: {
56
+ readonly Ed25519: "Ed25519";
57
+ readonly ECDSA: "ECDSA";
58
+ };
59
+ export type SignatureKind = (typeof SignatureKind)[keyof typeof SignatureKind];
60
+ //# sourceMappingURL=protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../../../src/link/v5/protocol.ts"],"names":[],"mappings":"AAIA;+EAC+E;AAC/E,eAAO,MAAM,GAAG,EAAG,CAAU,CAAC;AAE9B;qCACqC;AACrC,eAAO,MAAM,iBAAiB,wBAAwB,CAAC;AAEvD,wFAAwF;AACxF,eAAO,MAAM,UAAU;IACrB,sFAAsF;;IAEtF,uBAAuB;;IAEvB,8CAA8C;;IAE9C,+DAA+D;;IAE/D,4CAA4C;;IAE5C,4DAA4D;;IAE5D,uEAAuE;;IAEvE,sEAAsE;;IAEtE,kDAAkD;;CAE1C,CAAC;AACX,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,OAAO,UAAU,CAAC,CAAC;AAEtE,6FAA6F;AAC7F,eAAO,MAAM,SAAS;;;;;IAKpB;;;;kEAI8D;;CAEtD,CAAC;AACX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,OAAO,SAAS,CAAC,CAAC;AAEnE;;;kEAGkE;AAClE,eAAO,MAAM,QAAQ;;;CAGX,CAAC;AACX,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,OAAO,QAAQ,CAAC,CAAC;AAEhE;;6EAE6E;AAC7E,eAAO,MAAM,aAAa;;;CAGhB,CAAC;AACX,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,OAAO,aAAa,CAAC,CAAC"}
@@ -0,0 +1,73 @@
1
+ import { LinkTransport } from './transport.js';
2
+ import { WebSocketFactory } from './loopback-transport.js';
3
+ /** Default relay endpoint on the universal-link host (spec §17). */
4
+ export declare const DEFAULT_RELAY_URL = "wss://link.phantasma.info/relay";
5
+ /** Outgoing chunk threshold. The relay caps a whole frame at 1 MiB; this leaves room
6
+ * for the publish envelope around the payload. */
7
+ export declare const RELAY_CHUNK_BYTES = 900000;
8
+ export interface RelayTransportOptions {
9
+ /** The pairing topic both sides subscribe to (bearer capability, spec §16). */
10
+ topic: string;
11
+ /** Relay WebSocket URL; default {@link DEFAULT_RELAY_URL}. */
12
+ url?: string;
13
+ /** Override the WebSocket implementation (Node / tests). Defaults to global WebSocket. */
14
+ webSocketFactory?: WebSocketFactory;
15
+ /** Chunking threshold for outgoing frames; default {@link RELAY_CHUNK_BYTES}. */
16
+ maxPayloadBytes?: number;
17
+ /** Ceiling for one reassembled incoming message; default 64 MB of frame text. */
18
+ maxAssembledBytes?: number;
19
+ /** How long to wait for the relay's ack of one publish; default 15 s. */
20
+ publishAckTimeoutMs?: number;
21
+ /** Reconnect backoff ladder; the last entry repeats. Default 0.5/1/2/5/15 s. */
22
+ reconnectDelaysMs?: number[];
23
+ /** ecdh pairing (spec §18.1): called ONCE with the wallet's ephemeral X25519 public key
24
+ * (base64url) when the key hop arrives; the caller derives the session key before any
25
+ * sealed frame embedded in the same payload is forwarded. */
26
+ onWalletKey?: (publicKeyB64Url: string) => void;
27
+ /** Optional sink for diagnostics the transport cannot attribute to a caller - notably relay
28
+ * `error` frames that match no in-flight publish (spec §16: clients MUST surface error frames,
29
+ * not drop them). Defaults to console.warn; wire this to redirect or silence. */
30
+ log?: (message: string) => void;
31
+ }
32
+ /**
33
+ * {@link LinkTransport} over the Phantasma Link relay. `send` resolves once the relay
34
+ * acknowledged the publish (or rejects on timeout/close); incoming `deliver` frames are
35
+ * surfaced to the session client after chunk reassembly. Transient socket drops are
36
+ * absorbed by reconnection - the session layer only learns about an explicit close().
37
+ */
38
+ export declare class RelayTransport implements LinkTransport {
39
+ private readonly topic;
40
+ private readonly url;
41
+ private readonly factory;
42
+ private readonly maxPayloadBytes;
43
+ private readonly maxAssembledBytes;
44
+ private readonly publishAckTimeoutMs;
45
+ private readonly reconnectDelaysMs;
46
+ private socket?;
47
+ private messageHandler?;
48
+ private closeHandler?;
49
+ private readonly onWalletKey?;
50
+ private readonly log?;
51
+ private walletKeySeen;
52
+ private readonly pending;
53
+ private readonly partials;
54
+ private publishSeq;
55
+ private reconnectAttempt;
56
+ private reconnectTimer?;
57
+ private closed;
58
+ constructor(options: RelayTransportOptions);
59
+ send(frame: string): Promise<void>;
60
+ onMessage(handler: (frame: string) => void): void;
61
+ onClose(handler: (reason?: string) => void): void;
62
+ close(): void;
63
+ private connect;
64
+ private scheduleReconnect;
65
+ private publish;
66
+ private rejectAllPending;
67
+ private handleRaw;
68
+ /** Collect one chunk; emit the reassembled frame when complete. Bounds: chunk count,
69
+ * total bytes, concurrent partial messages, and a staleness GC - a hostile peer can
70
+ * waste its own topic, but not this client's memory (spec §16). */
71
+ private acceptChunk;
72
+ }
73
+ //# sourceMappingURL=relay-transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relay-transport.d.ts","sourceRoot":"","sources":["../../../../src/link/v5/relay-transport.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,EAAiB,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAG1E,oEAAoE;AACpE,eAAO,MAAM,iBAAiB,oCAAqC,CAAC;AAEpE;kDACkD;AAClD,eAAO,MAAM,iBAAiB,SAAU,CAAC;AAQzC,MAAM,WAAW,qBAAqB;IACpC,+EAA+E;IAC/E,KAAK,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0FAA0F;IAC1F,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,iFAAiF;IACjF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iFAAiF;IACjF,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,yEAAyE;IACzE,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,gFAAgF;IAChF,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B;;iEAE6D;IAC7D,WAAW,CAAC,EAAE,CAAC,eAAe,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD;;qFAEiF;IACjF,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC;AA4BD;;;;;GAKG;AACH,qBAAa,cAAe,YAAW,aAAa;IAClD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmB;IAC3C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAS;IAC7C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAW;IAE7C,OAAO,CAAC,MAAM,CAAC,CAAgB;IAC/B,OAAO,CAAC,cAAc,CAAC,CAA0B;IACjD,OAAO,CAAC,YAAY,CAAC,CAA4B;IACjD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAoC;IACjE,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAA4B;IACjD,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqC;IAC7D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA8B;IACvD,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,cAAc,CAAC,CAAgC;IACvD,OAAO,CAAC,MAAM,CAAS;gBAEX,OAAO,EAAE,qBAAqB;IAgBpC,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BxC,SAAS,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAIjD,OAAO,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAIjD,KAAK,IAAI,IAAI;IAqBb,OAAO,CAAC,OAAO;IAsCf,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,OAAO;IAkBf,OAAO,CAAC,gBAAgB;IAUxB,OAAO,CAAC,SAAS;IA2EjB;;uEAEmE;IACnE,OAAO,CAAC,WAAW;CAwDpB"}
@@ -0,0 +1,51 @@
1
+ /** Session/channel key length (32 bytes). */
2
+ export declare const SESSION_KEY_LENGTH: number;
3
+ /** Per-message nonce length (24 bytes). */
4
+ export declare const NONCE_LENGTH: number;
5
+ /** X25519 public-key length (32 bytes). */
6
+ export declare const PUBLIC_KEY_LENGTH: number;
7
+ /** Domain separator prepended before signing a message. It can never be the prefix of a
8
+ * valid serialized Phantasma transaction, so a `signMessage` signature can never be
9
+ * replayed as a transaction signature (spec §8). */
10
+ export declare const SIGN_MESSAGE_DOMAIN_TAG: Uint8Array;
11
+ /** Length of the CSPRNG random the wallet prepends in `signMessage` (spec §8). */
12
+ export declare const SIGN_MESSAGE_RANDOM_LENGTH = 32;
13
+ /** An encrypted, on-the-wire frame: the nonce + ciphertext, both base64. */
14
+ export interface EncryptedFrame {
15
+ nonce: string;
16
+ ct: string;
17
+ }
18
+ /** An X25519 keypair for the custom-scheme ECDH pairing path. */
19
+ export interface EphemeralKeyPair {
20
+ publicKey: Uint8Array;
21
+ secretKey: Uint8Array;
22
+ }
23
+ /** Generate a fresh 32-byte symmetric session key (primary universal-link / QR path). */
24
+ export declare function generateSessionKey(): Uint8Array;
25
+ /** Generate a random url-safe token (default 16 bytes), used for request `id`s and pairing
26
+ * topics. Crypto-random so ids are unguessable as well as unique. */
27
+ export declare function randomToken(byteLength?: number): string;
28
+ /** Generate an ephemeral X25519 keypair (custom-scheme ECDH fallback path). */
29
+ export declare function generateEphemeralKeyPair(): EphemeralKeyPair;
30
+ /** Derive the 32-byte session key from the peer's X25519 public key and our secret key
31
+ * (ECDH; NaCl `box.before`). The result is directly usable as a `secretbox` key. */
32
+ export declare function deriveSessionKey(theirPublicKey: Uint8Array, mySecretKey: Uint8Array): Uint8Array;
33
+ /** Encrypt arbitrary plaintext bytes into a frame with a fresh random nonce. */
34
+ export declare function seal(plaintext: Uint8Array, key: Uint8Array): EncryptedFrame;
35
+ /** Decrypt a frame back to plaintext bytes. Throws on any tampering/wrong-key (authenticated
36
+ * encryption: `secretbox.open` returns null, which we surface as an error). */
37
+ export declare function open(frame: EncryptedFrame, key: Uint8Array): Uint8Array;
38
+ /** Encrypt an envelope's JSON text into a frame. */
39
+ export declare function sealEnvelopeText(json: string, key: Uint8Array): EncryptedFrame;
40
+ /** Decrypt a frame back into the envelope's JSON text. */
41
+ export declare function openEnvelopeText(frame: EncryptedFrame, key: Uint8Array): string;
42
+ /** Generate the 32 random bytes a wallet prepends in `signMessage`. */
43
+ export declare function generateSignMessageRandom(): Uint8Array;
44
+ /**
45
+ * Build the exact byte string a wallet signs for `pha_signMessage`:
46
+ * `DOMAIN_TAG || random || message` (spec §8). A verifier reconstructs the same bytes from
47
+ * the returned `random` + the original `message`. Keeping this in one place guarantees the
48
+ * wallet and any verifier agree on the layout.
49
+ */
50
+ export declare function buildSignMessagePayload(message: Uint8Array, random: Uint8Array): Uint8Array;
51
+ //# sourceMappingURL=session-crypto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-crypto.d.ts","sourceRoot":"","sources":["../../../../src/link/v5/session-crypto.ts"],"names":[],"mappings":"AAuBA,6CAA6C;AAC7C,eAAO,MAAM,kBAAkB,QAA2B,CAAC;AAC3D,2CAA2C;AAC3C,eAAO,MAAM,YAAY,QAA6B,CAAC;AACvD,2CAA2C;AAC3C,eAAO,MAAM,iBAAiB,QAA2B,CAAC;AAE1D;;oDAEoD;AACpD,eAAO,MAAM,uBAAuB,EAAE,UAAmD,CAAC;AAC1F,kFAAkF;AAClF,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAE7C,4EAA4E;AAC5E,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,iEAAiE;AACjE,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,UAAU,CAAC;IACtB,SAAS,EAAE,UAAU,CAAC;CACvB;AAED,yFAAyF;AACzF,wBAAgB,kBAAkB,IAAI,UAAU,CAE/C;AAED;qEACqE;AACrE,wBAAgB,WAAW,CAAC,UAAU,SAAK,GAAG,MAAM,CAEnD;AAED,+EAA+E;AAC/E,wBAAgB,wBAAwB,IAAI,gBAAgB,CAG3D;AAED;oFACoF;AACpF,wBAAgB,gBAAgB,CAAC,cAAc,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,GAAG,UAAU,CAKhG;AAQD,gFAAgF;AAChF,wBAAgB,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,GAAG,cAAc,CAK3E;AAED;+EAC+E;AAC/E,wBAAgB,IAAI,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,UAAU,GAAG,UAAU,CAYvE;AAED,oDAAoD;AACpD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,cAAc,CAE9E;AAED,0DAA0D;AAC1D,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,UAAU,GAAG,MAAM,CAE/E;AAED,uEAAuE;AACvE,wBAAgB,yBAAyB,IAAI,UAAU,CAEtD;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,GAAG,UAAU,CAY3F"}
@@ -0,0 +1,77 @@
1
+ /** A duplex channel that carries opaque frame strings between dApp and wallet. */
2
+ export interface LinkTransport {
3
+ send(frame: string): void | Promise<void>;
4
+ onMessage(handler: (frame: string) => void): void;
5
+ onClose?(handler: (reason?: string) => void): void;
6
+ close(): void;
7
+ }
8
+ export type LinkEventHandler = (event: string, data: unknown, session?: string) => void;
9
+ export interface LinkSessionClientOptions {
10
+ /** 32-byte session key. When omitted, frames are PLAINTEXT envelope JSON - appropriate
11
+ * ONLY for a trusted local transport (loopback/injected); deeplink and relay MUST set a
12
+ * key (spec §8). */
13
+ sessionKey?: Uint8Array;
14
+ /** Refuse to SEND until a session key is set (see {@link LinkSessionClient.setSessionKey}).
15
+ * Used by the ecdh pairing flow, where the key is derived only after the wallet's
16
+ * public key arrives - plaintext must never leave the client in the meantime. */
17
+ requireSessionKey?: boolean;
18
+ /** Session id attached to outgoing requests after connect/pairing. */
19
+ sessionId?: string;
20
+ /** Per-request timeout in ms; 0 disables. Default 60000. */
21
+ requestTimeoutMs?: number;
22
+ /** Sink for responses with no matching in-flight request (the deeplink page reloaded while
23
+ * the wallet was open, discarding the original request promise). Without it such responses
24
+ * are dropped. Never fires on same-page flows - those always have a pending entry. */
25
+ onUnmatchedResponse?: (response: UnmatchedResponse) => void;
26
+ }
27
+ /** A wallet response that arrived with no in-flight request to match it - the deeplink reload
28
+ * case, where the page that issued the request was discarded before the answer came back.
29
+ * Surfaced via {@link LinkSessionClientOptions.onUnmatchedResponse} so a persistence layer can
30
+ * still present the result instead of dropping it. */
31
+ export interface UnmatchedResponse {
32
+ id: string;
33
+ ok: boolean;
34
+ result?: unknown;
35
+ error?: unknown;
36
+ }
37
+ /**
38
+ * Drives a v5 session over a {@link LinkTransport}. `request()` sends a typed envelope and
39
+ * resolves with the wallet's `result` (or rejects with a {@link LinkError}); incoming events
40
+ * are dispatched to {@link onEvent} handlers. Encryption is transparent: when a session key
41
+ * is set, every outgoing envelope is sealed and every incoming frame is opened.
42
+ */
43
+ export declare class LinkSessionClient {
44
+ private readonly transport;
45
+ private sessionKey?;
46
+ private readonly requireSessionKey;
47
+ private sessionId?;
48
+ private readonly requestTimeoutMs;
49
+ private readonly onUnmatchedResponse?;
50
+ private readonly pending;
51
+ private readonly eventHandlers;
52
+ private closed;
53
+ constructor(transport: LinkTransport, options?: LinkSessionClientOptions);
54
+ /** Set/refresh the session id sent on subsequent requests (e.g. after `pha_connect`),
55
+ * or clear it with `undefined` (e.g. after `pha_disconnect`). */
56
+ setSessionId(id: string | undefined): void;
57
+ /** The current session id, if a session is established. */
58
+ getSessionId(): string | undefined;
59
+ /** Install the channel key once it is established (ecdh pairing derives it only after
60
+ * the wallet's ephemeral public key arrives, spec §18.1). From here on every frame is
61
+ * sealed/opened with it, exactly as if it had been passed at construction. */
62
+ setSessionKey(key: Uint8Array): void;
63
+ /** Subscribe to wallet->dApp events; returns an unsubscribe function. */
64
+ onEvent(handler: LinkEventHandler): () => void;
65
+ /** Send a request and await its result. Rejects with {@link LinkError}. */
66
+ request(method: string, params?: Record<string, unknown>): Promise<unknown>;
67
+ /** Close the session, rejecting all in-flight requests. */
68
+ close(): void;
69
+ private encodeOutgoing;
70
+ private decodeIncoming;
71
+ private handleFrame;
72
+ private emitEvent;
73
+ private handleClose;
74
+ private settleError;
75
+ private rejectAll;
76
+ }
77
+ //# sourceMappingURL=transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../../../src/link/v5/transport.ts"],"names":[],"mappings":"AA0BA,kFAAkF;AAClF,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,SAAS,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;IAClD,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;IACnD,KAAK,IAAI,IAAI,CAAC;CACf;AAED,MAAM,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;AAExF,MAAM,WAAW,wBAAwB;IACvC;;wBAEoB;IACpB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB;;qFAEiF;IACjF,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4DAA4D;IAC5D,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;0FAEsF;IACtF,mBAAmB,CAAC,EAAE,CAAC,QAAQ,EAAE,iBAAiB,KAAK,IAAI,CAAC;CAC7D;AAQD;;;sDAGsD;AACtD,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;;;GAKG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgB;IAC1C,OAAO,CAAC,UAAU,CAAC,CAAa;IAChC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAU;IAC5C,OAAO,CAAC,SAAS,CAAC,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAwC;IAC7E,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA8B;IACtD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA+B;IAC7D,OAAO,CAAC,MAAM,CAAS;gBAEX,SAAS,EAAE,aAAa,EAAE,OAAO,GAAE,wBAA6B;IAW5E;qEACiE;IACjE,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAI1C,2DAA2D;IAC3D,YAAY,IAAI,MAAM,GAAG,SAAS;IAIlC;;kFAE8E;IAC9E,aAAa,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI;IAOpC,yEAAyE;IACzE,OAAO,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,IAAI;IAO9C,2EAA2E;IAC3E,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAwD3E,2DAA2D;IAC3D,KAAK,IAAI,IAAI;IASb,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,cAAc;IAkBtB,OAAO,CAAC,WAAW;IAiDnB,OAAO,CAAC,SAAS;IAUjB,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,WAAW;IAYnB,OAAO,CAAC,SAAS;CASlB"}