@llayer-network/wallet-standard-util 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +0 -0
  3. package/lib/cjs/commitment.js +26 -0
  4. package/lib/cjs/commitment.js.map +1 -0
  5. package/lib/cjs/endpoint.js +45 -0
  6. package/lib/cjs/endpoint.js.map +1 -0
  7. package/lib/cjs/index.js +21 -0
  8. package/lib/cjs/index.js.map +1 -0
  9. package/lib/cjs/package.json +1 -0
  10. package/lib/cjs/signIn.js +186 -0
  11. package/lib/cjs/signIn.js.map +1 -0
  12. package/lib/cjs/signMessage.js +22 -0
  13. package/lib/cjs/signMessage.js.map +1 -0
  14. package/lib/cjs/tsconfig.cjs.tsbuildinfo +1 -0
  15. package/lib/cjs/util.js +44 -0
  16. package/lib/cjs/util.js.map +1 -0
  17. package/lib/esm/commitment.js +23 -0
  18. package/lib/esm/commitment.js.map +1 -0
  19. package/lib/esm/endpoint.js +40 -0
  20. package/lib/esm/endpoint.js.map +1 -0
  21. package/lib/esm/index.js +5 -0
  22. package/lib/esm/index.js.map +1 -0
  23. package/lib/esm/signIn.js +176 -0
  24. package/lib/esm/signIn.js.map +1 -0
  25. package/lib/esm/signMessage.js +18 -0
  26. package/lib/esm/signMessage.js.map +1 -0
  27. package/lib/esm/tsconfig.esm.tsbuildinfo +1 -0
  28. package/lib/esm/util.js +40 -0
  29. package/lib/esm/util.js.map +1 -0
  30. package/lib/types/commitment.d.ts +8 -0
  31. package/lib/types/commitment.d.ts.map +1 -0
  32. package/lib/types/endpoint.d.ts +18 -0
  33. package/lib/types/endpoint.d.ts.map +1 -0
  34. package/lib/types/index.d.ts +5 -0
  35. package/lib/types/index.d.ts.map +1 -0
  36. package/lib/types/signIn.d.ts +34 -0
  37. package/lib/types/signIn.d.ts.map +1 -0
  38. package/lib/types/signMessage.d.ts +15 -0
  39. package/lib/types/signMessage.d.ts.map +1 -0
  40. package/lib/types/util.d.ts +2 -0
  41. package/lib/types/util.d.ts.map +1 -0
  42. package/package.json +44 -0
  43. package/src/__tests__/signIn.ts +89 -0
  44. package/src/commitment.ts +27 -0
  45. package/src/endpoint.ts +39 -0
  46. package/src/index.ts +4 -0
  47. package/src/signIn.ts +185 -0
  48. package/src/signMessage.ts +33 -0
  49. package/src/util.ts +54 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"endpoint.js","sourceRoot":"","sources":["../../src/endpoint.ts"],"names":[],"mappings":"AACA,OAAO,EACH,mBAAmB,EACnB,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,GACvB,MAAM,wCAAwC,CAAC;AAEhD,iBAAiB;AACjB,MAAM,CAAC,MAAM,gBAAgB,GAAG,qCAAqC,CAAC;AACtE,iBAAiB;AACjB,MAAM,CAAC,MAAM,eAAe,GAAG,+BAA+B,CAAC;AAC/D,iBAAiB;AACjB,MAAM,CAAC,MAAM,gBAAgB,GAAG,gCAAgC,CAAC;AACjE,iBAAiB;AACjB,MAAM,CAAC,MAAM,iBAAiB,GAAG,uBAAuB,CAAC;AAEzD;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,QAAgB;IAChD,IAAI,QAAQ,CAAC,QAAQ,CAAC,gBAAgB,CAAC;QAAE,OAAO,oBAAoB,CAAC;IACrE,IAAI,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC;QAAE,OAAO,mBAAmB,CAAC;IAC7D,IAAI,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC;QAAE,OAAO,oBAAoB,CAAC;IAC/D,IAAI,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC;QAAE,OAAO,qBAAqB,CAAC;IACvG,OAAO,oBAAoB,CAAC;AAChC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAkB,EAAE,QAAiB;IACrE,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC9B,IAAI,KAAK,KAAK,oBAAoB;QAAE,OAAO,gBAAgB,CAAC;IAC5D,IAAI,KAAK,KAAK,mBAAmB;QAAE,OAAO,eAAe,CAAC;IAC1D,IAAI,KAAK,KAAK,oBAAoB;QAAE,OAAO,gBAAgB,CAAC;IAC5D,IAAI,KAAK,KAAK,qBAAqB;QAAE,OAAO,iBAAiB,CAAC;IAC9D,OAAO,gBAAgB,CAAC;AAC5B,CAAC"}
@@ -0,0 +1,5 @@
1
+ export * from './commitment.js';
2
+ export * from './endpoint.js';
3
+ export * from './signIn.js';
4
+ export * from './signMessage.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,176 @@
1
+ import { verifyMessageSignature } from './signMessage.js';
2
+ import { arraysEqual } from './util.js';
3
+ /**
4
+ * TODO: docs
5
+ */
6
+ export function verifySignIn(input, output) {
7
+ const { signedMessage, signature, account: { publicKey }, } = output;
8
+ const message = deriveSignInMessage(input, output);
9
+ return (!!message && verifyMessageSignature({ message, signedMessage, signature, publicKey: publicKey }));
10
+ }
11
+ /**
12
+ * TODO: docs
13
+ */
14
+ export function deriveSignInMessage(input, output) {
15
+ const text = deriveSignInMessageText(input, output);
16
+ if (!text)
17
+ return null;
18
+ return new TextEncoder().encode(text);
19
+ }
20
+ /**
21
+ * TODO: docs
22
+ */
23
+ export function deriveSignInMessageText(input, output) {
24
+ const parsed = parseSignInMessage(output.signedMessage);
25
+ if (!parsed)
26
+ return null;
27
+ if (input.domain && input.domain !== parsed.domain)
28
+ return null;
29
+ if (input.address && input.address !== parsed.address)
30
+ return null;
31
+ if (input.statement !== parsed.statement)
32
+ return null;
33
+ if (input.uri !== parsed.uri)
34
+ return null;
35
+ if (input.version !== parsed.version)
36
+ return null;
37
+ if (input.chainId !== parsed.chainId)
38
+ return null;
39
+ if (input.nonce !== parsed.nonce)
40
+ return null;
41
+ if (input.issuedAt !== parsed.issuedAt)
42
+ return null;
43
+ if (input.expirationTime !== parsed.expirationTime)
44
+ return null;
45
+ if (input.notBefore !== parsed.notBefore)
46
+ return null;
47
+ if (input.requestId !== parsed.requestId)
48
+ return null;
49
+ if (input.resources) {
50
+ if (!parsed.resources)
51
+ return null;
52
+ if (!arraysEqual(input.resources, parsed.resources))
53
+ return null;
54
+ }
55
+ else if (parsed.resources)
56
+ return null;
57
+ return createSignInMessageText(parsed);
58
+ }
59
+ /**
60
+ * TODO: docs
61
+ */
62
+ export function parseSignInMessage(message) {
63
+ const text = new TextDecoder().decode(message);
64
+ return parseSignInMessageText(text);
65
+ }
66
+ // TODO: implement https://github.com/solana-labs/solana/blob/master/docs/src/proposals/off-chain-message-signing.md
67
+ const DOMAIN = '(?<domain>[^\\n]+?) wants you to sign in with your Solana account:\\n';
68
+ const ADDRESS = '(?<address>[^\\n]+)(?:\\n|$)';
69
+ const STATEMENT = '(?:\\n(?<statement>[\\S\\s]*?)(?:\\n|$))??';
70
+ const URI = '(?:\\nURI: (?<uri>[^\\n]+))?';
71
+ const VERSION = '(?:\\nVersion: (?<version>[^\\n]+))?';
72
+ const CHAIN_ID = '(?:\\nChain ID: (?<chainId>[^\\n]+))?';
73
+ const NONCE = '(?:\\nNonce: (?<nonce>[^\\n]+))?';
74
+ const ISSUED_AT = '(?:\\nIssued At: (?<issuedAt>[^\\n]+))?';
75
+ const EXPIRATION_TIME = '(?:\\nExpiration Time: (?<expirationTime>[^\\n]+))?';
76
+ const NOT_BEFORE = '(?:\\nNot Before: (?<notBefore>[^\\n]+))?';
77
+ const REQUEST_ID = '(?:\\nRequest ID: (?<requestId>[^\\n]+))?';
78
+ const RESOURCES = '(?:\\nResources:(?<resources>(?:\\n- [^\\n]+)*))?';
79
+ const FIELDS = `${URI}${VERSION}${CHAIN_ID}${NONCE}${ISSUED_AT}${EXPIRATION_TIME}${NOT_BEFORE}${REQUEST_ID}${RESOURCES}`;
80
+ const MESSAGE = new RegExp(`^${DOMAIN}${ADDRESS}${STATEMENT}${FIELDS}\\n*$`);
81
+ /**
82
+ * TODO: docs
83
+ */
84
+ export function parseSignInMessageText(text) {
85
+ const match = MESSAGE.exec(text);
86
+ if (!match)
87
+ return null;
88
+ const groups = match.groups;
89
+ if (!groups)
90
+ return null;
91
+ return {
92
+ domain: groups.domain,
93
+ address: groups.address,
94
+ statement: groups.statement,
95
+ uri: groups.uri,
96
+ version: groups.version,
97
+ nonce: groups.nonce,
98
+ chainId: groups.chainId,
99
+ issuedAt: groups.issuedAt,
100
+ expirationTime: groups.expirationTime,
101
+ notBefore: groups.notBefore,
102
+ requestId: groups.requestId,
103
+ resources: groups.resources?.split('\n- ').slice(1),
104
+ };
105
+ }
106
+ /**
107
+ * TODO: docs
108
+ */
109
+ export function createSignInMessage(input) {
110
+ const text = createSignInMessageText(input);
111
+ return new TextEncoder().encode(text);
112
+ }
113
+ /**
114
+ * TODO: docs
115
+ */
116
+ export function createSignInMessageText(input) {
117
+ // ${domain} wants you to sign in with your Solana account:
118
+ // ${address}
119
+ //
120
+ // ${statement}
121
+ //
122
+ // URI: ${uri}
123
+ // Version: ${version}
124
+ // Chain ID: ${chain}
125
+ // Nonce: ${nonce}
126
+ // Issued At: ${issued-at}
127
+ // Expiration Time: ${expiration-time}
128
+ // Not Before: ${not-before}
129
+ // Request ID: ${request-id}
130
+ // Resources:
131
+ // - ${resources[0]}
132
+ // - ${resources[1]}
133
+ // ...
134
+ // - ${resources[n]}
135
+ let message = `${input.domain} wants you to sign in with your Solana account:\n`;
136
+ message += `${input.address}`;
137
+ if (input.statement) {
138
+ message += `\n\n${input.statement}`;
139
+ }
140
+ const fields = [];
141
+ if (input.uri) {
142
+ fields.push(`URI: ${input.uri}`);
143
+ }
144
+ if (input.version) {
145
+ fields.push(`Version: ${input.version}`);
146
+ }
147
+ if (input.chainId) {
148
+ fields.push(`Chain ID: ${input.chainId}`);
149
+ }
150
+ if (input.nonce) {
151
+ fields.push(`Nonce: ${input.nonce}`);
152
+ }
153
+ if (input.issuedAt) {
154
+ fields.push(`Issued At: ${input.issuedAt}`);
155
+ }
156
+ if (input.expirationTime) {
157
+ fields.push(`Expiration Time: ${input.expirationTime}`);
158
+ }
159
+ if (input.notBefore) {
160
+ fields.push(`Not Before: ${input.notBefore}`);
161
+ }
162
+ if (input.requestId) {
163
+ fields.push(`Request ID: ${input.requestId}`);
164
+ }
165
+ if (input.resources) {
166
+ fields.push(`Resources:`);
167
+ for (const resource of input.resources) {
168
+ fields.push(`- ${resource}`);
169
+ }
170
+ }
171
+ if (fields.length) {
172
+ message += `\n\n${fields.join('\n')}`;
173
+ }
174
+ return message;
175
+ }
176
+ //# sourceMappingURL=signIn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signIn.js","sourceRoot":"","sources":["../../src/signIn.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { ed25519 } from '@noble/curves/ed25519';
2
+ import { bytesEqual } from './util.js';
3
+ /**
4
+ * TODO: docs
5
+ */
6
+ export function verifyMessageSignature({ message, signedMessage, signature, publicKey, }) {
7
+ // TODO: implement https://github.com/solana-labs/solana/blob/master/docs/src/proposals/off-chain-message-signing.md
8
+ return bytesEqual(message, signedMessage) && ed25519.verify(signature, signedMessage, publicKey);
9
+ }
10
+ /**
11
+ * TODO: docs
12
+ */
13
+ export function verifySignMessage(input, output) {
14
+ const { message, account: { publicKey }, } = input;
15
+ const { signedMessage, signature } = output;
16
+ return verifyMessageSignature({ message, signedMessage, signature, publicKey: publicKey });
17
+ }
18
+ //# sourceMappingURL=signMessage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signMessage.js","sourceRoot":"","sources":["../../src/signMessage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAEhD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,EACnC,OAAO,EACP,aAAa,EACb,SAAS,EACT,SAAS,GAMZ;IACG,oHAAoH;IACpH,OAAO,UAAU,CAAC,OAAO,EAAE,aAAa,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,aAAa,EAAE,SAAS,CAAC,CAAC;AACrG,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAA6B,EAAE,MAA+B;IAC5F,MAAM,EACF,OAAO,EACP,OAAO,EAAE,EAAE,SAAS,EAAE,GACzB,GAAG,KAAK,CAAC;IACV,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC;IAC5C,OAAO,sBAAsB,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE,SAAuB,EAAE,CAAC,CAAC;AAC7G,CAAC"}
@@ -0,0 +1 @@
1
+ {"root":["../../src/commitment.ts","../../src/endpoint.ts","../../src/index.ts","../../src/signin.ts","../../src/signmessage.ts","../../src/util.ts"],"version":"5.9.3"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * @internal
3
+ *
4
+ * Efficiently compare {@link Indexed} arrays (e.g. `Array` and `Uint8Array`).
5
+ *
6
+ * @param a An array.
7
+ * @param b Another array.
8
+ *
9
+ * @return `true` if the arrays have the same length and elements, `false` otherwise.
10
+ *
11
+ * @group Internal
12
+ */
13
+ export function arraysEqual(a, b) {
14
+ if (a === b)
15
+ return true;
16
+ const length = a.length;
17
+ if (length !== b.length)
18
+ return false;
19
+ for (let i = 0; i < length; i++) {
20
+ if (a[i] !== b[i])
21
+ return false;
22
+ }
23
+ return true;
24
+ }
25
+ /**
26
+ * @internal
27
+ *
28
+ * Efficiently compare byte arrays, using {@link arraysEqual}.
29
+ *
30
+ * @param a A byte array.
31
+ * @param b Another byte array.
32
+ *
33
+ * @return `true` if the byte arrays have the same length and bytes, `false` otherwise.
34
+ *
35
+ * @group Internal
36
+ */
37
+ export function bytesEqual(a, b) {
38
+ return arraysEqual(a, b);
39
+ }
40
+ //# sourceMappingURL=util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/util.ts"],"names":[],"mappings":"AAcA;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,WAAW,CAAI,CAAa,EAAE,CAAa;IACvD,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEzB,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;IACxB,IAAI,MAAM,KAAK,CAAC,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAEtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9B,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;IACpC,CAAC;IAED,OAAO,IAAI,CAAC;AAChB,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,UAAU,CAAC,CAAa,EAAE,CAAa;IACnD,OAAO,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { SolanaTransactionCommitment } from '@llayer-network/wallet-standard-features';
2
+ type Commitment = 'processed' | 'confirmed' | 'finalized' | 'recent' | 'single' | 'singleGossip' | 'root' | 'max';
3
+ /**
4
+ * TODO: docs
5
+ */
6
+ export declare function getCommitment(commitment?: Commitment): SolanaTransactionCommitment | undefined;
7
+ export {};
8
+ //# sourceMappingURL=commitment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commitment.d.ts","sourceRoot":"","sources":["../../src/commitment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,0CAA0C,CAAC;AAG5F,KAAK,UAAU,GAAG,WAAW,GAAG,WAAW,GAAG,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,cAAc,GAAG,MAAM,GAAG,KAAK,CAAC;AAElH;;GAEG;AACH,wBAAgB,aAAa,CAAC,UAAU,CAAC,EAAE,UAAU,GAAG,2BAA2B,GAAG,SAAS,CAkB9F"}
@@ -0,0 +1,18 @@
1
+ import type { SolanaChain } from '@llayer-network/wallet-standard-chains';
2
+ /** TODO: docs */
3
+ export declare const MAINNET_ENDPOINT = "https://api.mainnet-beta.solana.com";
4
+ /** TODO: docs */
5
+ export declare const DEVNET_ENDPOINT = "https://api.devnet.solana.com";
6
+ /** TODO: docs */
7
+ export declare const TESTNET_ENDPOINT = "https://api.testnet.solana.com";
8
+ /** TODO: docs */
9
+ export declare const LOCALNET_ENDPOINT = "http://localhost:8899";
10
+ /**
11
+ * TODO: docs
12
+ */
13
+ export declare function getChainForEndpoint(endpoint: string): SolanaChain;
14
+ /**
15
+ * TODO: docs
16
+ */
17
+ export declare function getEndpointForChain(chain: SolanaChain, endpoint?: string): string;
18
+ //# sourceMappingURL=endpoint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"endpoint.d.ts","sourceRoot":"","sources":["../../src/endpoint.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wCAAwC,CAAC;AAQ1E,iBAAiB;AACjB,eAAO,MAAM,gBAAgB,wCAAwC,CAAC;AACtE,iBAAiB;AACjB,eAAO,MAAM,eAAe,kCAAkC,CAAC;AAC/D,iBAAiB;AACjB,eAAO,MAAM,gBAAgB,mCAAmC,CAAC;AACjE,iBAAiB;AACjB,eAAO,MAAM,iBAAiB,0BAA0B,CAAC;AAEzD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,CAMjE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAOjF"}
@@ -0,0 +1,5 @@
1
+ export * from './commitment.js';
2
+ export * from './endpoint.js';
3
+ export * from './signIn.js';
4
+ export * from './signMessage.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,34 @@
1
+ import type { SolanaSignInInput, SolanaSignInOutput } from '@llayer-network/wallet-standard-features';
2
+ /**
3
+ * TODO: docs
4
+ */
5
+ export declare function verifySignIn(input: SolanaSignInInput, output: SolanaSignInOutput): boolean;
6
+ /**
7
+ * TODO: docs
8
+ */
9
+ export declare function deriveSignInMessage(input: SolanaSignInInput, output: SolanaSignInOutput): Uint8Array | null;
10
+ /**
11
+ * TODO: docs
12
+ */
13
+ export declare function deriveSignInMessageText(input: SolanaSignInInput, output: SolanaSignInOutput): string | null;
14
+ /**
15
+ * TODO: docs
16
+ */
17
+ export type SolanaSignInInputWithRequiredFields = SolanaSignInInput & Required<Pick<SolanaSignInInput, 'domain' | 'address'>>;
18
+ /**
19
+ * TODO: docs
20
+ */
21
+ export declare function parseSignInMessage(message: Uint8Array): SolanaSignInInputWithRequiredFields | null;
22
+ /**
23
+ * TODO: docs
24
+ */
25
+ export declare function parseSignInMessageText(text: string): SolanaSignInInputWithRequiredFields | null;
26
+ /**
27
+ * TODO: docs
28
+ */
29
+ export declare function createSignInMessage(input: SolanaSignInInputWithRequiredFields): Uint8Array;
30
+ /**
31
+ * TODO: docs
32
+ */
33
+ export declare function createSignInMessageText(input: SolanaSignInInputWithRequiredFields): string;
34
+ //# sourceMappingURL=signIn.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signIn.d.ts","sourceRoot":"","sources":["../../src/signIn.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,0CAA0C,CAAC;AAItG;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,EAAE,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAU1F;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,iBAAiB,EAAE,MAAM,EAAE,kBAAkB,GAAG,UAAU,GAAG,IAAI,CAI3G;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,iBAAiB,EAAE,MAAM,EAAE,kBAAkB,GAAG,MAAM,GAAG,IAAI,CAqB3G;AAED;;GAEG;AACH,MAAM,MAAM,mCAAmC,GAAG,iBAAiB,GAC/D,QAAQ,CAAC,IAAI,CAAC,iBAAiB,EAAE,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC;AAE5D;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,UAAU,GAAG,mCAAmC,GAAG,IAAI,CAGlG;AAkBD;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,mCAAmC,GAAG,IAAI,CAqB/F;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,mCAAmC,GAAG,UAAU,CAG1F;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,mCAAmC,GAAG,MAAM,CA+D1F"}
@@ -0,0 +1,15 @@
1
+ import type { SolanaSignMessageInput, SolanaSignMessageOutput } from '@llayer-network/wallet-standard-features';
2
+ /**
3
+ * TODO: docs
4
+ */
5
+ export declare function verifyMessageSignature({ message, signedMessage, signature, publicKey, }: {
6
+ message: Uint8Array;
7
+ signedMessage: Uint8Array;
8
+ signature: Uint8Array;
9
+ publicKey: Uint8Array;
10
+ }): boolean;
11
+ /**
12
+ * TODO: docs
13
+ */
14
+ export declare function verifySignMessage(input: SolanaSignMessageInput, output: SolanaSignMessageOutput): boolean;
15
+ //# sourceMappingURL=signMessage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signMessage.d.ts","sourceRoot":"","sources":["../../src/signMessage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,0CAA0C,CAAC;AAGhH;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,EACnC,OAAO,EACP,aAAa,EACb,SAAS,EACT,SAAS,GACZ,EAAE;IACC,OAAO,EAAE,UAAU,CAAC;IACpB,aAAa,EAAE,UAAU,CAAC;IAC1B,SAAS,EAAE,UAAU,CAAC;IACtB,SAAS,EAAE,UAAU,CAAC;CACzB,GAAG,OAAO,CAGV;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,EAAE,MAAM,EAAE,uBAAuB,GAAG,OAAO,CAOzG"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=util.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/util.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@llayer-network/wallet-standard-util",
3
+ "version": "1.1.2",
4
+ "author": "Solana Maintainers <maintainers@solana.foundation>",
5
+ "repository": "https://github.com/solana-labs/wallet-standard",
6
+ "license": "Apache-2.0",
7
+ "publishConfig": {
8
+ "access": "public"
9
+ },
10
+ "files": [
11
+ "lib",
12
+ "src",
13
+ "LICENSE"
14
+ ],
15
+ "engines": {
16
+ "node": "22"
17
+ },
18
+ "type": "module",
19
+ "sideEffects": false,
20
+ "main": "./lib/cjs/index.js",
21
+ "module": "./lib/esm/index.js",
22
+ "types": "./lib/types/index.d.ts",
23
+ "exports": {
24
+ "require": "./lib/cjs/index.js",
25
+ "import": "./lib/esm/index.js",
26
+ "types": "./lib/types/index.d.ts"
27
+ },
28
+ "dependencies": {
29
+ "@noble/curves": "^1.8.2",
30
+ "@llayer-network/wallet-standard-chains": "^1.1.1",
31
+ "@llayer-network/wallet-standard-features": "^1.3.0"
32
+ },
33
+ "devDependencies": {
34
+ "@types/jest": "^29.5.14",
35
+ "jest": "^29.7.0",
36
+ "shx": "^0.4.0",
37
+ "ts-jest": "^29.3.2"
38
+ },
39
+ "scripts": {
40
+ "clean": "shx mkdir -p lib && shx rm -rf lib",
41
+ "package": "shx mkdir -p lib/cjs && shx echo '{ \"type\": \"commonjs\" }' > lib/cjs/package.json",
42
+ "test": "jest"
43
+ }
44
+ }
@@ -0,0 +1,89 @@
1
+ import {
2
+ createSignInMessage,
3
+ createSignInMessageText,
4
+ deriveSignInMessage,
5
+ deriveSignInMessageText,
6
+ parseSignInMessage,
7
+ parseSignInMessageText,
8
+ verifySignIn,
9
+ } from '../signIn.js';
10
+
11
+ const signInMessageTests = {
12
+ 'with `domain` and `address`': {
13
+ parsed: {
14
+ domain: 'solana.com',
15
+ address: 'A',
16
+ },
17
+ text: 'solana.com wants you to sign in with your Solana account:\nA',
18
+ },
19
+ 'with `statement`': {
20
+ parsed: {
21
+ domain: 'solana.com',
22
+ address: 'A',
23
+ statement: 'S',
24
+ },
25
+ text: 'solana.com wants you to sign in with your Solana account:\nA\n\nS',
26
+ },
27
+ 'with multi-line `statement`': {
28
+ parsed: {
29
+ domain: 'solana.com',
30
+ address: 'A',
31
+ statement: 'S\n\nS',
32
+ },
33
+ text: 'solana.com wants you to sign in with your Solana account:\nA\n\nS\n\nS',
34
+ },
35
+ 'with fields': {
36
+ parsed: {
37
+ domain: 'solana.com',
38
+ address: 'A',
39
+ uri: 'https://solana.com',
40
+ },
41
+ text: 'solana.com wants you to sign in with your Solana account:\nA\n\nURI: https://solana.com',
42
+ },
43
+ 'with `statement` and fields': {
44
+ parsed: {
45
+ domain: 'solana.com',
46
+ address: 'A',
47
+ statement: 'S',
48
+ uri: 'https://solana.com',
49
+ },
50
+ text: 'solana.com wants you to sign in with your Solana account:\nA\n\nS\n\nURI: https://solana.com',
51
+ },
52
+ 'with multi-line `statement` and fields': {
53
+ parsed: {
54
+ domain: 'solana.com',
55
+ address: 'A',
56
+ statement: 'S\n\nS',
57
+ uri: 'https://solana.com',
58
+ },
59
+ text: 'solana.com wants you to sign in with your Solana account:\nA\n\nS\n\nS\n\nURI: https://solana.com',
60
+ },
61
+ };
62
+
63
+ describe.skip('verifySignIn()', () => {});
64
+
65
+ describe.skip('deriveSignInMessage()', () => {});
66
+
67
+ describe.skip('deriveSignInMessageText()', () => {});
68
+
69
+ describe.skip('parseSignInMessage()', () => {});
70
+
71
+ describe('parseSignInMessageText()', () => {
72
+ for (const [name, test] of Object.entries(signInMessageTests)) {
73
+ it(name, () => {
74
+ const parsed = parseSignInMessageText(test.text);
75
+ expect(parsed).toEqual(test.parsed);
76
+ });
77
+ }
78
+ });
79
+
80
+ describe.skip('createSignInMessage()', () => {});
81
+
82
+ describe('createSignInMessageText()', () => {
83
+ for (const [name, test] of Object.entries(signInMessageTests)) {
84
+ it(name, () => {
85
+ const text = createSignInMessageText(test.parsed);
86
+ expect(text).toBe(test.text);
87
+ });
88
+ }
89
+ });
@@ -0,0 +1,27 @@
1
+ import type { SolanaTransactionCommitment } from '@llayer-network/wallet-standard-features';
2
+
3
+ // Copied from @solana/web3.js
4
+ type Commitment = 'processed' | 'confirmed' | 'finalized' | 'recent' | 'single' | 'singleGossip' | 'root' | 'max';
5
+
6
+ /**
7
+ * TODO: docs
8
+ */
9
+ export function getCommitment(commitment?: Commitment): SolanaTransactionCommitment | undefined {
10
+ switch (commitment) {
11
+ case 'processed':
12
+ case 'confirmed':
13
+ case 'finalized':
14
+ case undefined:
15
+ return commitment;
16
+ case 'recent':
17
+ return 'processed';
18
+ case 'single':
19
+ case 'singleGossip':
20
+ return 'confirmed';
21
+ case 'max':
22
+ case 'root':
23
+ return 'finalized';
24
+ default:
25
+ return undefined;
26
+ }
27
+ }
@@ -0,0 +1,39 @@
1
+ import type { SolanaChain } from '@llayer-network/wallet-standard-chains';
2
+ import {
3
+ SOLANA_DEVNET_CHAIN,
4
+ SOLANA_LOCALNET_CHAIN,
5
+ SOLANA_MAINNET_CHAIN,
6
+ SOLANA_TESTNET_CHAIN,
7
+ } from '@llayer-network/wallet-standard-chains';
8
+
9
+ /** TODO: docs */
10
+ export const MAINNET_ENDPOINT = 'https://api.mainnet-beta.solana.com';
11
+ /** TODO: docs */
12
+ export const DEVNET_ENDPOINT = 'https://api.devnet.solana.com';
13
+ /** TODO: docs */
14
+ export const TESTNET_ENDPOINT = 'https://api.testnet.solana.com';
15
+ /** TODO: docs */
16
+ export const LOCALNET_ENDPOINT = 'http://localhost:8899';
17
+
18
+ /**
19
+ * TODO: docs
20
+ */
21
+ export function getChainForEndpoint(endpoint: string): SolanaChain {
22
+ if (endpoint.includes(MAINNET_ENDPOINT)) return SOLANA_MAINNET_CHAIN;
23
+ if (/\bdevnet\b/i.test(endpoint)) return SOLANA_DEVNET_CHAIN;
24
+ if (/\btestnet\b/i.test(endpoint)) return SOLANA_TESTNET_CHAIN;
25
+ if (/\blocalhost\b/i.test(endpoint) || /\b127\.0\.0\.1\b/.test(endpoint)) return SOLANA_LOCALNET_CHAIN;
26
+ return SOLANA_MAINNET_CHAIN;
27
+ }
28
+
29
+ /**
30
+ * TODO: docs
31
+ */
32
+ export function getEndpointForChain(chain: SolanaChain, endpoint?: string): string {
33
+ if (endpoint) return endpoint;
34
+ if (chain === SOLANA_MAINNET_CHAIN) return MAINNET_ENDPOINT;
35
+ if (chain === SOLANA_DEVNET_CHAIN) return DEVNET_ENDPOINT;
36
+ if (chain === SOLANA_TESTNET_CHAIN) return TESTNET_ENDPOINT;
37
+ if (chain === SOLANA_LOCALNET_CHAIN) return LOCALNET_ENDPOINT;
38
+ return MAINNET_ENDPOINT;
39
+ }
package/src/index.ts ADDED
@@ -0,0 +1,4 @@
1
+ export * from './commitment.js';
2
+ export * from './endpoint.js';
3
+ export * from './signIn.js';
4
+ export * from './signMessage.js';