@tuwaio/siwx-solana 0.2.0 → 0.3.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.
- package/README.md +5 -5
- package/dist/index.d.mts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +9 -9
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
## 🏛️ Core Capabilities
|
|
11
11
|
|
|
12
12
|
- **ed25519 Verification**: Verifies Solana wallet signatures against CAIP-122 messages using the native `SubtleCrypto` API (no native module dependencies).
|
|
13
|
-
- Extracts and validates Solana addresses from CAIP-10 strings using
|
|
13
|
+
- Extracts and validates Solana addresses from CAIP-10 strings using `@solana/kit`.
|
|
14
14
|
- Compatible with Node.js (v19+), browsers, and Edge runtimes (Cloudflare Workers, Vercel Edge).
|
|
15
15
|
|
|
16
16
|
---
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
## 💾 Installation
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
|
-
pnpm add @tuwaio/siwx-solana @tuwaio/siwx-core
|
|
21
|
+
pnpm add @tuwaio/siwx-solana @tuwaio/siwx-core @solana/kit @wallet-standard/base
|
|
22
22
|
```
|
|
23
23
|
|
|
24
24
|
---
|
|
@@ -46,7 +46,7 @@ if (result.success) {
|
|
|
46
46
|
|
|
47
47
|
### `createSolanaSiwxSigner(signer)`
|
|
48
48
|
|
|
49
|
-
Creates a standard SIWX signer callback for Solana chains. Automatically adapts to Wallet Standard, Web3 v2 (
|
|
49
|
+
Creates a standard SIWX signer callback for Solana chains. Automatically adapts to Wallet Standard, Web3 v2 (@solana/kit), or legacy Solana signers.
|
|
50
50
|
|
|
51
51
|
```ts
|
|
52
52
|
import { createSolanaSiwxSigner } from '@tuwaio/siwx-solana';
|
|
@@ -80,8 +80,8 @@ await signIn({ signer, verifier, fields: { ... } });
|
|
|
80
80
|
| Package | Version |
|
|
81
81
|
| ----------------------- | ------------- |
|
|
82
82
|
| `@tuwaio/siwx-core` | `workspace:*` |
|
|
83
|
-
| `
|
|
84
|
-
| `@wallet-standard/base` | `^1.
|
|
83
|
+
| `@solana/kit` | `>=8.2.0` |
|
|
84
|
+
| `@wallet-standard/base` | `^1.1.1` |
|
|
85
85
|
|
|
86
86
|
---
|
|
87
87
|
|
package/dist/index.d.mts
CHANGED
|
@@ -5,13 +5,13 @@ import { SiwxVerifyPayload, SiwxVerifyResult } from '@tuwaio/siwx-core';
|
|
|
5
5
|
* Accepts raw wallet and account objects, or a unified signer object.
|
|
6
6
|
*/
|
|
7
7
|
interface SolanaSiwxSignerTarget {
|
|
8
|
-
account?:
|
|
9
|
-
wallet?:
|
|
10
|
-
[key: string]:
|
|
8
|
+
account?: Record<string, unknown>;
|
|
9
|
+
wallet?: Record<string, unknown>;
|
|
10
|
+
[key: string]: unknown;
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
13
13
|
* Creates a standard SIWX signer callback for Solana chains.
|
|
14
|
-
* Automatically adapts to Wallet Standard, Web3 v2 (
|
|
14
|
+
* Automatically adapts to Wallet Standard, Web3 v2 (@solana/kit), or legacy Solana signers.
|
|
15
15
|
*
|
|
16
16
|
* @param target - A Solana signer target containing raw wallet and account, or a direct signer instance.
|
|
17
17
|
* @returns A standardized signer function accepting a message string and returning a promise with the base58 signature.
|
package/dist/index.d.ts
CHANGED
|
@@ -5,13 +5,13 @@ import { SiwxVerifyPayload, SiwxVerifyResult } from '@tuwaio/siwx-core';
|
|
|
5
5
|
* Accepts raw wallet and account objects, or a unified signer object.
|
|
6
6
|
*/
|
|
7
7
|
interface SolanaSiwxSignerTarget {
|
|
8
|
-
account?:
|
|
9
|
-
wallet?:
|
|
10
|
-
[key: string]:
|
|
8
|
+
account?: Record<string, unknown>;
|
|
9
|
+
wallet?: Record<string, unknown>;
|
|
10
|
+
[key: string]: unknown;
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
13
13
|
* Creates a standard SIWX signer callback for Solana chains.
|
|
14
|
-
* Automatically adapts to Wallet Standard, Web3 v2 (
|
|
14
|
+
* Automatically adapts to Wallet Standard, Web3 v2 (@solana/kit), or legacy Solana signers.
|
|
15
15
|
*
|
|
16
16
|
* @param target - A Solana signer target containing raw wallet and account, or a direct signer instance.
|
|
17
17
|
* @returns A standardized signer function accepting a message string and returning a promise with the base58 signature.
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
'use strict';var
|
|
1
|
+
'use strict';var kit=require('@solana/kit'),siwxCore=require('@tuwaio/siwx-core');function v(e,n){if(e===n)return true;if(e.length!==n.length)return false;for(let s=0;s<e.length;s++)if(e[s]!==n[s])return false;return true}function P(e,n){if(typeof e?.modifyAndSignMessages=="function")return e;if(typeof n?.modifyAndSignMessages=="function")return n;let s=n?.features,a=e?.features,r;Array.isArray(s)&&s.includes("solana:signMessage"),a&&typeof a=="object"&&!Array.isArray(a)&&(r=a["solana:signMessage"]);let i=e?.adapter??n?.adapter,o=e?.signMessage??i?.signMessage??n?.signMessage,d=e?.signMessages??n?.signMessages;if(!r&&!o&&!d)throw new Error("[SIWX-SOLANA] Signer lacks known message signing capabilities.");let t=String(n?.address??e?.address??"solana:signer");return {address:t,async modifyAndSignMessages(g,y={}){if(y.abortSignal?.aborted)throw new Error("Aborted");if(g.length===0)return g;let M=[];for(let A=0;A<g.length;A++){let l=g[A],f,S;if(r){let u=[{account:n,message:l.content}],p=(await r.signMessage(...u))[0];if(!p||!p.signature)throw new Error("[SIWX-SOLANA] Wallet returned invalid signMessage output.");f=p.signature,S=p.signedMessage??l.content;}else if(typeof d=="function"){let c=(await d([{account:n,message:l.content}]))[0];if(!c||!c.signature)throw new Error("[SIWX-SOLANA] Wallet returned invalid signMessages output.");f=c.signature,S=c.signedMessage??l.content;}else if(typeof o=="function"){let u=await o.call(i??e??n,l.content);if(S=l.content,u instanceof Uint8Array||u&&u.buffer instanceof ArrayBuffer)f=u;else if(u&&typeof u=="object"&&"signature"in u)f=u.signature;else throw new Error("[SIWX-SOLANA] Unexpected legacy signMessage result format.")}else throw new Error("[SIWX-SOLANA] Missing signing implementation.");let m=l.content.length!==S.length||l.content.some((u,c)=>u!==S[c]),h=l.signatures[t];if(!(h===void 0||!v(h,f))&&!m){M.push(l);continue}let U=m?{[t]:f}:{...l.signatures,[t]:f};M.push(Object.freeze({content:S,signatures:Object.freeze(U)}));}return M}}}function N(e){return async n=>{try{if(!e)throw new Error("[SIWX-SOLANA] Invalid signer target.");let s=e.wallet??e,a=e.account??e,i=kit.getUtf8Encoder().encode(n),o=P(s,a),d=kit.createSignableMessage(i),g=(await o.modifyAndSignMessages([d]))[0];if(!g)throw new Error("[SIWX-SOLANA] No signed message returned.");let y=g.signatures[o.address];if(!y)throw new Error(`[SIWX-SOLANA] Signature missing for address: ${o.address}`);return kit.getBase58Decoder().decode(y)}catch(s){throw new Error(`[SIWX-SOLANA] Signing failed: ${s.message}`,{cause:s})}}}function b(e){let n="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz",s=new Map(n.split("").map((t,g)=>[t,BigInt(g)])),a=0n;for(let t of e){let g=s.get(t);if(g===void 0)throw new siwxCore.SiwxVerificationError(`Invalid base58 character: "${t}"`);a=a*58n+g;}let r=a.toString(16);r.length%2!==0&&(r="0"+r);let i=[];for(let t=0;t<r.length;t+=2)i.push(parseInt(r.slice(t,t+2),16));let o=0;for(let t of e)if(t==="1")o++;else break;let d=new Uint8Array(o+i.length);return d.set(i,o),d}function V(e){let n=e.split(":");if(n.length!==3||n[0]!=="solana")throw new siwxCore.SiwxVerificationError(`Expected solana CAIP-10 address format. Got: "${e}"`);return n[2]}function T(e){let n="output"in e?e.output:e,s="signedMessage"in n?n.signedMessage:n.message,a=n.signature,r,i;s instanceof Uint8Array?(i=s,r=new TextDecoder().decode(s)):(r=s,i=new TextEncoder().encode(s));let o;return a instanceof Uint8Array?o=a:o=b(a),{messageString:r,messageBytes:i,signatureBytes:o}}async function X(e,n){try{let{messageString:s,messageBytes:a,signatureBytes:r}=T(e),i=siwxCore.parseMessage(s);if(!i.chainId.startsWith("solana:"))throw new siwxCore.SiwxUnsupportedNamespaceError(i.chainId.split(":")[0]??"unknown");if(r.length!==64)throw new siwxCore.SiwxVerificationError(`Invalid Solana signature length: ${r.length} bytes (expected 64)`);let o=siwxCore.validateMessage(i,{skipExpiration:n?.skipExpiration,policy:{enforceNotBefore:!0}});if(!o.valid)throw new siwxCore.SiwxValidationError(o.errors);let d=V(i.address),t=kit.address(d),g=b(t),y=await globalThis.crypto.subtle.importKey("raw",g.buffer,{name:"Ed25519"},!1,["verify"]);if(!await globalThis.crypto.subtle.verify({name:"Ed25519"},y,r.buffer,a.buffer))throw new siwxCore.SiwxVerificationError(`ed25519 signature verification failed for address: ${d}`);return {success:!0,data:i}}catch(s){return s instanceof siwxCore.SiwxVerificationError||s instanceof siwxCore.SiwxValidationError?{success:false,error:s.message}:{success:false,error:`ed25519 verification failed: ${String(s)}`}}}exports.createSolanaSiwxSigner=N;exports.verifyEd25519=X;
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import {getUtf8Encoder,createSignableMessage,
|
|
1
|
+
import {getUtf8Encoder,createSignableMessage,getBase58Decoder,address}from'@solana/kit';import {parseMessage,SiwxUnsupportedNamespaceError,SiwxVerificationError,validateMessage,SiwxValidationError}from'@tuwaio/siwx-core';function v(e,n){if(e===n)return true;if(e.length!==n.length)return false;for(let s=0;s<e.length;s++)if(e[s]!==n[s])return false;return true}function P(e,n){if(typeof e?.modifyAndSignMessages=="function")return e;if(typeof n?.modifyAndSignMessages=="function")return n;let s=n?.features,a=e?.features,r;Array.isArray(s)&&s.includes("solana:signMessage"),a&&typeof a=="object"&&!Array.isArray(a)&&(r=a["solana:signMessage"]);let i=e?.adapter??n?.adapter,o=e?.signMessage??i?.signMessage??n?.signMessage,d=e?.signMessages??n?.signMessages;if(!r&&!o&&!d)throw new Error("[SIWX-SOLANA] Signer lacks known message signing capabilities.");let t=String(n?.address??e?.address??"solana:signer");return {address:t,async modifyAndSignMessages(g,y={}){if(y.abortSignal?.aborted)throw new Error("Aborted");if(g.length===0)return g;let M=[];for(let A=0;A<g.length;A++){let l=g[A],f,S;if(r){let u=[{account:n,message:l.content}],p=(await r.signMessage(...u))[0];if(!p||!p.signature)throw new Error("[SIWX-SOLANA] Wallet returned invalid signMessage output.");f=p.signature,S=p.signedMessage??l.content;}else if(typeof d=="function"){let c=(await d([{account:n,message:l.content}]))[0];if(!c||!c.signature)throw new Error("[SIWX-SOLANA] Wallet returned invalid signMessages output.");f=c.signature,S=c.signedMessage??l.content;}else if(typeof o=="function"){let u=await o.call(i??e??n,l.content);if(S=l.content,u instanceof Uint8Array||u&&u.buffer instanceof ArrayBuffer)f=u;else if(u&&typeof u=="object"&&"signature"in u)f=u.signature;else throw new Error("[SIWX-SOLANA] Unexpected legacy signMessage result format.")}else throw new Error("[SIWX-SOLANA] Missing signing implementation.");let m=l.content.length!==S.length||l.content.some((u,c)=>u!==S[c]),h=l.signatures[t];if(!(h===void 0||!v(h,f))&&!m){M.push(l);continue}let U=m?{[t]:f}:{...l.signatures,[t]:f};M.push(Object.freeze({content:S,signatures:Object.freeze(U)}));}return M}}}function N(e){return async n=>{try{if(!e)throw new Error("[SIWX-SOLANA] Invalid signer target.");let s=e.wallet??e,a=e.account??e,i=getUtf8Encoder().encode(n),o=P(s,a),d=createSignableMessage(i),g=(await o.modifyAndSignMessages([d]))[0];if(!g)throw new Error("[SIWX-SOLANA] No signed message returned.");let y=g.signatures[o.address];if(!y)throw new Error(`[SIWX-SOLANA] Signature missing for address: ${o.address}`);return getBase58Decoder().decode(y)}catch(s){throw new Error(`[SIWX-SOLANA] Signing failed: ${s.message}`,{cause:s})}}}function b(e){let n="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz",s=new Map(n.split("").map((t,g)=>[t,BigInt(g)])),a=0n;for(let t of e){let g=s.get(t);if(g===void 0)throw new SiwxVerificationError(`Invalid base58 character: "${t}"`);a=a*58n+g;}let r=a.toString(16);r.length%2!==0&&(r="0"+r);let i=[];for(let t=0;t<r.length;t+=2)i.push(parseInt(r.slice(t,t+2),16));let o=0;for(let t of e)if(t==="1")o++;else break;let d=new Uint8Array(o+i.length);return d.set(i,o),d}function V(e){let n=e.split(":");if(n.length!==3||n[0]!=="solana")throw new SiwxVerificationError(`Expected solana CAIP-10 address format. Got: "${e}"`);return n[2]}function T(e){let n="output"in e?e.output:e,s="signedMessage"in n?n.signedMessage:n.message,a=n.signature,r,i;s instanceof Uint8Array?(i=s,r=new TextDecoder().decode(s)):(r=s,i=new TextEncoder().encode(s));let o;return a instanceof Uint8Array?o=a:o=b(a),{messageString:r,messageBytes:i,signatureBytes:o}}async function X(e,n){try{let{messageString:s,messageBytes:a,signatureBytes:r}=T(e),i=parseMessage(s);if(!i.chainId.startsWith("solana:"))throw new SiwxUnsupportedNamespaceError(i.chainId.split(":")[0]??"unknown");if(r.length!==64)throw new SiwxVerificationError(`Invalid Solana signature length: ${r.length} bytes (expected 64)`);let o=validateMessage(i,{skipExpiration:n?.skipExpiration,policy:{enforceNotBefore:!0}});if(!o.valid)throw new SiwxValidationError(o.errors);let d=V(i.address),t=address(d),g=b(t),y=await globalThis.crypto.subtle.importKey("raw",g.buffer,{name:"Ed25519"},!1,["verify"]);if(!await globalThis.crypto.subtle.verify({name:"Ed25519"},y,r.buffer,a.buffer))throw new SiwxVerificationError(`ed25519 signature verification failed for address: ${d}`);return {success:!0,data:i}}catch(s){return s instanceof SiwxVerificationError||s instanceof SiwxValidationError?{success:false,error:s.message}:{success:false,error:`ed25519 verification failed: ${String(s)}`}}}export{N as createSolanaSiwxSigner,X as verifyEd25519};
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tuwaio/siwx-solana",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"author": "Oleksandr Tkach",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
|
-
"description": "Layer 2 (L2) of the TUWA Ecosystem. Solana adapter for @tuwaio/siwx. Signs and verifies CAIP-122 messages for Solana via
|
|
7
|
+
"description": "Layer 2 (L2) of the TUWA Ecosystem. Solana adapter for @tuwaio/siwx. Signs and verifies CAIP-122 messages for Solana via @solana/kit and @wallet-standard using ed25519 cryptography.",
|
|
8
8
|
"main": "./dist/index.js",
|
|
9
9
|
"module": "./dist/index.mjs",
|
|
10
10
|
"types": "./dist/index.d.ts",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"caip-122",
|
|
22
22
|
"solana",
|
|
23
23
|
"ed25519",
|
|
24
|
-
"
|
|
24
|
+
"@solana/kit",
|
|
25
25
|
"wallet-standard",
|
|
26
26
|
"sign-in-with-solana",
|
|
27
27
|
"authentication",
|
|
@@ -43,16 +43,16 @@
|
|
|
43
43
|
}
|
|
44
44
|
],
|
|
45
45
|
"peerDependencies": {
|
|
46
|
-
"@
|
|
47
|
-
"
|
|
48
|
-
"@
|
|
46
|
+
"@tuwaio/siwx-core": "0.3.0",
|
|
47
|
+
"@wallet-standard/base": ">=1.1.1",
|
|
48
|
+
"@solana/kit": ">=8.2"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
|
+
"@tuwaio/siwx-core": "0.3.0",
|
|
51
52
|
"@wallet-standard/base": "^1.1.1",
|
|
52
|
-
"
|
|
53
|
+
"@solana/kit": "^8.2.0",
|
|
53
54
|
"tsup": "^8.5.1",
|
|
54
|
-
"typescript": "^6.0.3"
|
|
55
|
-
"@tuwaio/siwx-core": "0.2.0"
|
|
55
|
+
"typescript": "^6.0.3"
|
|
56
56
|
},
|
|
57
57
|
"scripts": {
|
|
58
58
|
"start": "tsup src/index.ts --watch",
|