@tuwaio/siwx-solana 0.6.0 → 0.6.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/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { MessageModifyingSigner } from '@solana/kit';
2
- import { Wallet, WalletAccount } from '@wallet-standard/base';
2
+ import { Wallet, WalletAccount, ReadonlyUint8Array } from '@wallet-standard/base';
3
3
  import { SiwxVerifyPayload, SiwxVerifyResult } from '@tuwaio/siwx-core';
4
4
 
5
5
  /**
@@ -49,24 +49,64 @@ interface SolanaLegacyMessageSigner {
49
49
  signature: Uint8Array;
50
50
  }>;
51
51
  }
52
+ /**
53
+ * The value of `useWallet()` from `@solana/wallet-adapter-react` (v1) or `@solana/wallet-adapter` (v3), or any other
54
+ * `{ wallet, account }` objects with a signing capability, such as a wallet exposing an `adapter` or a `signMessages`
55
+ * method.
56
+ *
57
+ * Every field may be missing or `null`, as in `useWallet()` before a wallet connects: the signer looks for a signing
58
+ * capability only when it is called, and rejects when it finds none.
59
+ */
60
+ interface SolanaWalletAdapterSignerTarget {
61
+ /**
62
+ * The selected wallet. Its `solana:signMessage` and `solana:signOffchainMessage` features, its `adapter` and its
63
+ * `signMessages` and `signMessage` methods are used when present.
64
+ */
65
+ wallet?: object | null;
66
+ /** The connected account. Its `address`, `publicKey` and `features` are used when present. */
67
+ account?: object | null;
68
+ /** The base58 address of the connected account (v3). Used to check the bytes of a signed off-chain message. */
69
+ address?: string | null;
70
+ /**
71
+ * The public key of the connected account (`PublicKey` of `@solana/web3.js`). Used to check the bytes of a signed
72
+ * off-chain message when no address is given.
73
+ */
74
+ publicKey?: {
75
+ toBase58: () => string;
76
+ } | null;
77
+ /**
78
+ * Signs the UTF-8 bytes of the message.
79
+ * @param message - UTF-8 bytes of the message.
80
+ * @returns The 64-byte ed25519 signature, or an object that contains it.
81
+ */
82
+ signMessage?: (message: Uint8Array) => Promise<Uint8Array | {
83
+ signature: Uint8Array;
84
+ }>;
85
+ /**
86
+ * Signs the version 1 off-chain message of the text with the connected account as its only signer (v3).
87
+ * @param message - The message text.
88
+ * @returns The ed25519 signature and, optionally, the bytes the wallet signed.
89
+ */
90
+ signOffchainMessage?: (message: string) => Promise<{
91
+ signedOffchainMessage?: ReadonlyUint8Array;
92
+ signature: ReadonlyUint8Array;
93
+ }>;
94
+ }
52
95
  /**
53
96
  * What {@link createSolanaSiwxSigner} can sign with:
54
97
  *
55
98
  * - a Wallet Standard `{ wallet, account }` pair ({@link SolanaWalletStandardSignerTarget});
56
99
  * - an `@solana/kit` `MessageModifyingSigner`;
57
100
  * - a legacy adapter with `signMessage(bytes)` ({@link SolanaLegacyMessageSigner});
58
- * - any `{ wallet, account }` objects with one of these capabilities, such as a wallet exposing an `adapter` or a
59
- * `signMessages` method.
101
+ * - `useWallet()` of `@solana/wallet-adapter` v1 or v3, or any `{ wallet, account }` objects with one of these
102
+ * capabilities ({@link SolanaWalletAdapterSignerTarget}).
60
103
  *
61
104
  * The signer uses the first capability it finds: `modifyAndSignMessages`, the `solana:signMessage` feature of
62
105
  * `wallet.features`, a `signMessages` method, or a `signMessage` method (looked up on `wallet`, its `adapter`, `account`
63
106
  * and the target itself, so `useWallet()` of `@solana/wallet-adapter` v1 and v3 works as is). Off-chain messages use
64
107
  * the `solana:signOffchainMessage` feature of `wallet.features` or a `signOffchainMessage` method.
65
108
  */
66
- type SolanaSiwxSignerTarget = SolanaWalletStandardSignerTarget | MessageModifyingSigner | SolanaLegacyMessageSigner | {
67
- wallet?: object;
68
- account?: object;
69
- };
109
+ type SolanaSiwxSignerTarget = SolanaWalletStandardSignerTarget | MessageModifyingSigner | SolanaLegacyMessageSigner | SolanaWalletAdapterSignerTarget;
70
110
  /**
71
111
  * Creates a SIWX signer for Solana wallets: a function that signs a message with the wallet and returns the ed25519
72
112
  * signature as a base58 string. Pass it as `signer` to `useSiwx().signIn` from `@tuwaio/siwx-react`.
@@ -162,4 +202,4 @@ declare function verifyEd25519(payload: SolanaVerifyPayload, options?: {
162
202
  skipExpiration?: boolean;
163
203
  }): Promise<SiwxVerifyResult>;
164
204
 
165
- export { type SolanaLegacyMessageSigner, type SolanaSignInAccount, type SolanaSignInOutput, type SolanaSiwxMessageFormat, type SolanaSiwxSignerOptions, type SolanaSiwxSignerTarget, type SolanaVerifyPayload, type SolanaWalletStandardSignerTarget, createSolanaSiwxSigner, verifyEd25519 };
205
+ export { type SolanaLegacyMessageSigner, type SolanaSignInAccount, type SolanaSignInOutput, type SolanaSiwxMessageFormat, type SolanaSiwxSignerOptions, type SolanaSiwxSignerTarget, type SolanaVerifyPayload, type SolanaWalletAdapterSignerTarget, type SolanaWalletStandardSignerTarget, createSolanaSiwxSigner, verifyEd25519 };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { MessageModifyingSigner } from '@solana/kit';
2
- import { Wallet, WalletAccount } from '@wallet-standard/base';
2
+ import { Wallet, WalletAccount, ReadonlyUint8Array } from '@wallet-standard/base';
3
3
  import { SiwxVerifyPayload, SiwxVerifyResult } from '@tuwaio/siwx-core';
4
4
 
5
5
  /**
@@ -49,24 +49,64 @@ interface SolanaLegacyMessageSigner {
49
49
  signature: Uint8Array;
50
50
  }>;
51
51
  }
52
+ /**
53
+ * The value of `useWallet()` from `@solana/wallet-adapter-react` (v1) or `@solana/wallet-adapter` (v3), or any other
54
+ * `{ wallet, account }` objects with a signing capability, such as a wallet exposing an `adapter` or a `signMessages`
55
+ * method.
56
+ *
57
+ * Every field may be missing or `null`, as in `useWallet()` before a wallet connects: the signer looks for a signing
58
+ * capability only when it is called, and rejects when it finds none.
59
+ */
60
+ interface SolanaWalletAdapterSignerTarget {
61
+ /**
62
+ * The selected wallet. Its `solana:signMessage` and `solana:signOffchainMessage` features, its `adapter` and its
63
+ * `signMessages` and `signMessage` methods are used when present.
64
+ */
65
+ wallet?: object | null;
66
+ /** The connected account. Its `address`, `publicKey` and `features` are used when present. */
67
+ account?: object | null;
68
+ /** The base58 address of the connected account (v3). Used to check the bytes of a signed off-chain message. */
69
+ address?: string | null;
70
+ /**
71
+ * The public key of the connected account (`PublicKey` of `@solana/web3.js`). Used to check the bytes of a signed
72
+ * off-chain message when no address is given.
73
+ */
74
+ publicKey?: {
75
+ toBase58: () => string;
76
+ } | null;
77
+ /**
78
+ * Signs the UTF-8 bytes of the message.
79
+ * @param message - UTF-8 bytes of the message.
80
+ * @returns The 64-byte ed25519 signature, or an object that contains it.
81
+ */
82
+ signMessage?: (message: Uint8Array) => Promise<Uint8Array | {
83
+ signature: Uint8Array;
84
+ }>;
85
+ /**
86
+ * Signs the version 1 off-chain message of the text with the connected account as its only signer (v3).
87
+ * @param message - The message text.
88
+ * @returns The ed25519 signature and, optionally, the bytes the wallet signed.
89
+ */
90
+ signOffchainMessage?: (message: string) => Promise<{
91
+ signedOffchainMessage?: ReadonlyUint8Array;
92
+ signature: ReadonlyUint8Array;
93
+ }>;
94
+ }
52
95
  /**
53
96
  * What {@link createSolanaSiwxSigner} can sign with:
54
97
  *
55
98
  * - a Wallet Standard `{ wallet, account }` pair ({@link SolanaWalletStandardSignerTarget});
56
99
  * - an `@solana/kit` `MessageModifyingSigner`;
57
100
  * - a legacy adapter with `signMessage(bytes)` ({@link SolanaLegacyMessageSigner});
58
- * - any `{ wallet, account }` objects with one of these capabilities, such as a wallet exposing an `adapter` or a
59
- * `signMessages` method.
101
+ * - `useWallet()` of `@solana/wallet-adapter` v1 or v3, or any `{ wallet, account }` objects with one of these
102
+ * capabilities ({@link SolanaWalletAdapterSignerTarget}).
60
103
  *
61
104
  * The signer uses the first capability it finds: `modifyAndSignMessages`, the `solana:signMessage` feature of
62
105
  * `wallet.features`, a `signMessages` method, or a `signMessage` method (looked up on `wallet`, its `adapter`, `account`
63
106
  * and the target itself, so `useWallet()` of `@solana/wallet-adapter` v1 and v3 works as is). Off-chain messages use
64
107
  * the `solana:signOffchainMessage` feature of `wallet.features` or a `signOffchainMessage` method.
65
108
  */
66
- type SolanaSiwxSignerTarget = SolanaWalletStandardSignerTarget | MessageModifyingSigner | SolanaLegacyMessageSigner | {
67
- wallet?: object;
68
- account?: object;
69
- };
109
+ type SolanaSiwxSignerTarget = SolanaWalletStandardSignerTarget | MessageModifyingSigner | SolanaLegacyMessageSigner | SolanaWalletAdapterSignerTarget;
70
110
  /**
71
111
  * Creates a SIWX signer for Solana wallets: a function that signs a message with the wallet and returns the ed25519
72
112
  * signature as a base58 string. Pass it as `signer` to `useSiwx().signIn` from `@tuwaio/siwx-react`.
@@ -162,4 +202,4 @@ declare function verifyEd25519(payload: SolanaVerifyPayload, options?: {
162
202
  skipExpiration?: boolean;
163
203
  }): Promise<SiwxVerifyResult>;
164
204
 
165
- export { type SolanaLegacyMessageSigner, type SolanaSignInAccount, type SolanaSignInOutput, type SolanaSiwxMessageFormat, type SolanaSiwxSignerOptions, type SolanaSiwxSignerTarget, type SolanaVerifyPayload, type SolanaWalletStandardSignerTarget, createSolanaSiwxSigner, verifyEd25519 };
205
+ export { type SolanaLegacyMessageSigner, type SolanaSignInAccount, type SolanaSignInOutput, type SolanaSiwxMessageFormat, type SolanaSiwxSignerOptions, type SolanaSiwxSignerTarget, type SolanaVerifyPayload, type SolanaWalletAdapterSignerTarget, type SolanaWalletStandardSignerTarget, createSolanaSiwxSigner, verifyEd25519 };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- 'use strict';var kit=require('@solana/kit'),orbitCore=require('@tuwaio/orbit-core'),siwxCore=require('@tuwaio/siwx-core');function B(n,e){if(n===e)return true;if(n.length!==e.length)return false;for(let s=0;s<n.length;s++)if(n[s]!==e[s])return false;return true}function K(n,e,s){if(typeof n?.modifyAndSignMessages=="function")return n;if(typeof e?.modifyAndSignMessages=="function")return e;let t=e?.features,a=n?.features,i;Array.isArray(t)&&t.includes("solana:signMessage"),a&&typeof a=="object"&&!Array.isArray(a)&&(i=a["solana:signMessage"]);let o=n?.adapter??e?.adapter,g=[n,o,e,s].find(l=>typeof l?.signMessage=="function"),r=g?.signMessage,f=n?.signMessages??e?.signMessages;if(!i&&!r&&!f)throw new Error("[SIWX-SOLANA] Signer lacks known message signing capabilities.");let c=String(e?.address??n?.address??"solana:signer");return {address:c,async modifyAndSignMessages(l,m={}){if(m.abortSignal?.aborted)throw new Error("Aborted");if(l.length===0)return l;let y=[];for(let M=0;M<l.length;M++){let u=l[M],S,p;if(i){let d=[{account:e,message:u.content}],O=(await i.signMessage(...d))[0];if(!O||!O.signature)throw new Error("[SIWX-SOLANA] Wallet returned invalid signMessage output.");S=O.signature,p=O.signedMessage??u.content;}else if(typeof f=="function"){let h=(await f([{account:e,message:u.content}]))[0];if(!h||!h.signature)throw new Error("[SIWX-SOLANA] Wallet returned invalid signMessages output.");S=h.signature,p=h.signedMessage??u.content;}else if(typeof r=="function"){let d=await r.call(g,u.content);if(p=u.content,d instanceof Uint8Array||d&&d.buffer instanceof ArrayBuffer)S=d;else if(d&&typeof d=="object"&&"signature"in d)S=d.signature;else throw new Error("[SIWX-SOLANA] Unexpected legacy signMessage result format.")}else throw new Error("[SIWX-SOLANA] Missing signing implementation.");let k=u.content.length!==p.length||u.content.some((d,h)=>d!==p[h]),x=u.signatures[c];if(!(x===void 0||!B(x,S))&&!k){y.push(u);continue}let F=k?{[c]:S}:{...u.signatures,[c]:S};y.push(Object.freeze({content:p,signatures:Object.freeze(F)}));}return y}}}function $(n,e,s){let t=n.features,a=t&&typeof t=="object"&&!Array.isArray(t)?t["solana:signOffchainMessage"]:void 0;if(a&&typeof a.signOffchainMessage=="function")return a.supportedMessageVersions?.includes(1)?{async sign(o){let r=(await a.signOffchainMessage({account:e,message:o,messageVersion:1,requiredSigners:[q(e)]}))[0];if(!r?.signature)throw new Error("[SIWX-SOLANA] Wallet returned invalid signOffchainMessage output.");return r}}:{error:"The wallet cannot sign version 1 off-chain messages."};let i=[n,e,s].find(o=>typeof o.signOffchainMessage=="function");if(i){let o=i.signOffchainMessage;return {async sign(g){let r=await o.call(i,g);if(!r?.signature)throw new Error("[SIWX-SOLANA] Wallet returned invalid signOffchainMessage output.");return r}}}}function q(n){let e=n.publicKey;return e instanceof Uint8Array?e:new Uint8Array(kit.getAddressEncoder().encode(kit.address(String(n.address))))}function U(n,e,s){for(let a of [e,n,s]){let i=a.address;if(typeof i=="string")return i}let t=s.publicKey;return typeof t?.toBase58=="function"?t.toBase58():void 0}async function E(n,e,s){if(!n.sign)throw new Error(`[SIWX-SOLANA] ${n.error}`);let t=await n.sign(e);if(t.signedOffchainMessage&&s){let a=kit.compileOffchainMessageV1Envelope({version:1,content:e,requiredSignatories:[{address:kit.address(s)}]}).content;if(!B(new Uint8Array(t.signedOffchainMessage),a))throw new Error("[SIWX-SOLANA] Wallet signed a different off-chain message than requested.")}return kit.getBase58Decoder().decode(new Uint8Array(t.signature))}function v(n,e){let s=n.features;return !Array.isArray(s)||s.includes(e)}function C(n,e={}){let s=e.messageFormat??"auto";return async t=>{try{if(!n)throw new Error("[SIWX-SOLANA] Invalid signer target.");let a=n,{wallet:i,account:o}=n,g=i??n,r=o??n,f=s==="message"?void 0:$(g,r,a);if(s==="offchainMessage"){if(!f)throw new Error("[SIWX-SOLANA] Signer cannot sign off-chain messages.");return await E(f,t,U(g,r,a))}let c;try{c=K(g,r,a);}catch(p){if(!f?.sign)throw p}if(f?.sign&&(!c||!v(r,"solana:signMessage")&&v(r,"solana:signOffchainMessage"))||!c)return await E(f,t,U(g,r,a));let A=kit.getUtf8Encoder().encode(t),y=kit.createSignableMessage(A),u=(await c.modifyAndSignMessages([y]))[0];if(!u)throw new Error("[SIWX-SOLANA] No signed message returned.");let S=u.signatures[c.address];if(!S)throw new Error(`[SIWX-SOLANA] Signature missing for address: ${c.address}`);return kit.getBase58Decoder().decode(S)}catch(a){throw new Error(`[SIWX-SOLANA] Signing failed: ${a.message}`,{cause:a})}}}function L(n){let e="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz",s=new Map(e.split("").map((r,f)=>[r,BigInt(f)])),t=0n;for(let r of n){let f=s.get(r);if(f===void 0)throw new siwxCore.SiwxVerificationError(`Invalid base58 character: "${r}"`);t=t*58n+f;}let a=t.toString(16);a.length%2!==0&&(a="0"+a);let i=[];for(let r=0;r<a.length;r+=2)i.push(parseInt(a.slice(r,r+2),16));let o=0;for(let r of n)if(r==="1")o++;else break;let g=new Uint8Array(o+i.length);return g.set(i,o),g}var P=new Uint8Array([255,...new TextEncoder().encode("solana offchain")]);function Q(n){return n.length>P.length&&P.every((e,s)=>n[s]===e)}function Y(n){let e;try{e=kit.getOffchainMessageDecoder().decode(n);}catch(s){throw new siwxCore.SiwxVerificationError(`Invalid off-chain message: ${String(s)}`)}if(e.version!==1)throw new siwxCore.SiwxVerificationError(`Unsupported off-chain message version: ${e.version} (expected 1)`);return {content:e.content,signatories:e.requiredSignatories.map(({address:s})=>s)}}function ee(n,e){try{return kit.compileOffchainMessageV1Envelope({version:1,content:n,requiredSignatories:[{address:kit.address(e)}]}).content}catch{return}}function ne(n){let e="output"in n?n.output:n,s="signedMessage"in e?e.signedMessage:e.message,t=e.signature,a,i,o;if(s instanceof Uint8Array)if(i=s,Q(s)){let r=Y(s);a=r.content,o=r.signatories;}else a=new TextDecoder().decode(s);else a=s,i=new TextEncoder().encode(s);let g;return t instanceof Uint8Array?g=t:g=L(t),{messageString:a,messageBytes:i,signatureBytes:g,offchainSignatories:o}}async function b(n,e,s){return globalThis.crypto.subtle.verify({name:"Ed25519"},n,e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength),s.buffer.slice(s.byteOffset,s.byteOffset+s.byteLength))}async function se(n,e){try{let{messageString:s,messageBytes:t,signatureBytes:a,offchainSignatories:i}=ne(n),o=siwxCore.parseMessage(s),g=orbitCore.parseCaip2ChainId(o.chainId)?.namespace;if(g!=="solana")throw new siwxCore.SiwxUnsupportedNamespaceError(g??"unknown");if(a.length!==64)throw new siwxCore.SiwxVerificationError(`Invalid Solana signature length: ${a.length} bytes (expected 64)`);let r=siwxCore.validateMessage(o,{skipExpiration:e?.skipExpiration,policy:{enforceNotBefore:!0}});if(!r.valid)throw new siwxCore.SiwxValidationError(r.errors);let f=orbitCore.parseCaip10AccountId(o.address);if(f?.namespace!=="solana")throw new siwxCore.SiwxVerificationError(`Expected solana CAIP-10 address format. Got: "${o.address}"`);let c=f.address,l=kit.address(c),m=L(l),A=await globalThis.crypto.subtle.importKey("raw",m.buffer,{name:"Ed25519"},!1,["verify"]),y;if(i){if(i.length!==1||i[0]!==l)throw new siwxCore.SiwxVerificationError(`Off-chain message signatory must be the message address only. Got: ${i.join(", ")}`);y=await b(A,a,t);}else if(y=await b(A,a,t),!y){let M=ee(s,l);M&&(y=await b(A,a,M));}if(!y)throw new siwxCore.SiwxVerificationError(`ed25519 signature verification failed for address: ${c}`);return {success:!0,data:o}}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=C;exports.verifyEd25519=se;
1
+ 'use strict';var kit=require('@solana/kit'),orbitCore=require('@tuwaio/orbit-core'),siwxCore=require('@tuwaio/siwx-core');function B(n,e){if(n===e)return true;if(n.length!==e.length)return false;for(let s=0;s<n.length;s++)if(n[s]!==e[s])return false;return true}function j(n,e,s){if(typeof n?.modifyAndSignMessages=="function")return n;if(typeof e?.modifyAndSignMessages=="function")return e;let t=e?.features,a=n?.features,i;Array.isArray(t)&&t.includes("solana:signMessage"),a&&typeof a=="object"&&!Array.isArray(a)&&(i=a["solana:signMessage"]);let o=n?.adapter??e?.adapter,g=[n,o,e,s].find(l=>typeof l?.signMessage=="function"),r=g?.signMessage,f=n?.signMessages??e?.signMessages;if(!i&&!r&&!f)throw new Error("[SIWX-SOLANA] Signer lacks known message signing capabilities.");let c=String(e?.address??n?.address??"solana:signer");return {address:c,async modifyAndSignMessages(l,m={}){if(m.abortSignal?.aborted)throw new Error("Aborted");if(l.length===0)return l;let y=[];for(let M=0;M<l.length;M++){let u=l[M],S,p;if(i){let d=[{account:e,message:u.content}],O=(await i.signMessage(...d))[0];if(!O||!O.signature)throw new Error("[SIWX-SOLANA] Wallet returned invalid signMessage output.");S=O.signature,p=O.signedMessage??u.content;}else if(typeof f=="function"){let A=(await f([{account:e,message:u.content}]))[0];if(!A||!A.signature)throw new Error("[SIWX-SOLANA] Wallet returned invalid signMessages output.");S=A.signature,p=A.signedMessage??u.content;}else if(typeof r=="function"){let d=await r.call(g,u.content);if(p=u.content,d instanceof Uint8Array||d&&d.buffer instanceof ArrayBuffer)S=d;else if(d&&typeof d=="object"&&"signature"in d)S=d.signature;else throw new Error("[SIWX-SOLANA] Unexpected legacy signMessage result format.")}else throw new Error("[SIWX-SOLANA] Missing signing implementation.");let k=u.content.length!==p.length||u.content.some((d,A)=>d!==p[A]),U=u.signatures[c];if(!(U===void 0||!B(U,S))&&!k){y.push(u);continue}let T=k?{[c]:S}:{...u.signatures,[c]:S};y.push(Object.freeze({content:p,signatures:Object.freeze(T)}));}return y}}}function $(n,e,s){let t=n.features,a=t&&typeof t=="object"&&!Array.isArray(t)?t["solana:signOffchainMessage"]:void 0;if(a&&typeof a.signOffchainMessage=="function")return a.supportedMessageVersions?.includes(1)?{async sign(o){let r=(await a.signOffchainMessage({account:e,message:o,messageVersion:1,requiredSigners:[q(e)]}))[0];if(!r?.signature)throw new Error("[SIWX-SOLANA] Wallet returned invalid signOffchainMessage output.");return r}}:{error:"The wallet cannot sign version 1 off-chain messages."};let i=[n,e,s].find(o=>typeof o.signOffchainMessage=="function");if(i){let o=i.signOffchainMessage;return {async sign(g){let r=await o.call(i,g);if(!r?.signature)throw new Error("[SIWX-SOLANA] Wallet returned invalid signOffchainMessage output.");return r}}}}function q(n){let e=n.publicKey;return e instanceof Uint8Array?e:new Uint8Array(kit.getAddressEncoder().encode(kit.address(String(n.address))))}function x(n,e,s){for(let a of [e,n,s]){let i=a.address;if(typeof i=="string")return i}let t=s.publicKey;return typeof t?.toBase58=="function"?t.toBase58():void 0}async function E(n,e,s){if(!n.sign)throw new Error(`[SIWX-SOLANA] ${n.error}`);let t=await n.sign(e);if(t.signedOffchainMessage&&s){let a=kit.compileOffchainMessageV1Envelope({version:1,content:e,requiredSignatories:[{address:kit.address(s)}]}).content;if(!B(new Uint8Array(t.signedOffchainMessage),a))throw new Error("[SIWX-SOLANA] Wallet signed a different off-chain message than requested.")}return kit.getBase58Decoder().decode(new Uint8Array(t.signature))}function v(n,e){let s=n.features;return !Array.isArray(s)||s.includes(e)}function C(n,e={}){let s=e.messageFormat??"auto";return async t=>{try{if(!n)throw new Error("[SIWX-SOLANA] Invalid signer target.");let a=n,{wallet:i,account:o}=n,g=i??n,r=o??n,f=s==="message"?void 0:$(g,r,a);if(s==="offchainMessage"){if(!f)throw new Error("[SIWX-SOLANA] Signer cannot sign off-chain messages.");return await E(f,t,x(g,r,a))}let c;try{c=j(g,r,a);}catch(p){if(!f?.sign)throw p}if(f?.sign&&(!c||!v(r,"solana:signMessage")&&v(r,"solana:signOffchainMessage"))||!c)return await E(f,t,x(g,r,a));let h=kit.getUtf8Encoder().encode(t),y=kit.createSignableMessage(h),u=(await c.modifyAndSignMessages([y]))[0];if(!u)throw new Error("[SIWX-SOLANA] No signed message returned.");let S=u.signatures[c.address];if(!S)throw new Error(`[SIWX-SOLANA] Signature missing for address: ${c.address}`);return kit.getBase58Decoder().decode(S)}catch(a){throw new Error(`[SIWX-SOLANA] Signing failed: ${a.message}`,{cause:a})}}}function L(n){let e="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz",s=new Map(e.split("").map((r,f)=>[r,BigInt(f)])),t=0n;for(let r of n){let f=s.get(r);if(f===void 0)throw new siwxCore.SiwxVerificationError(`Invalid base58 character: "${r}"`);t=t*58n+f;}let a=t.toString(16);a.length%2!==0&&(a="0"+a);let i=[];for(let r=0;r<a.length;r+=2)i.push(parseInt(a.slice(r,r+2),16));let o=0;for(let r of n)if(r==="1")o++;else break;let g=new Uint8Array(o+i.length);return g.set(i,o),g}var R=new Uint8Array([255,...new TextEncoder().encode("solana offchain")]);function Q(n){return n.length>R.length&&R.every((e,s)=>n[s]===e)}function Y(n){let e;try{e=kit.getOffchainMessageDecoder().decode(n);}catch(s){throw new siwxCore.SiwxVerificationError(`Invalid off-chain message: ${String(s)}`)}if(e.version!==1)throw new siwxCore.SiwxVerificationError(`Unsupported off-chain message version: ${e.version} (expected 1)`);return {content:e.content,signatories:e.requiredSignatories.map(({address:s})=>s)}}function ee(n,e){try{return kit.compileOffchainMessageV1Envelope({version:1,content:n,requiredSignatories:[{address:kit.address(e)}]}).content}catch{return}}function ne(n){let e="output"in n?n.output:n,s="signedMessage"in e?e.signedMessage:e.message,t=e.signature,a,i,o;if(s instanceof Uint8Array)if(i=s,Q(s)){let r=Y(s);a=r.content,o=r.signatories;}else a=new TextDecoder().decode(s);else a=s,i=new TextEncoder().encode(s);let g;return t instanceof Uint8Array?g=t:g=L(t),{messageString:a,messageBytes:i,signatureBytes:g,offchainSignatories:o}}async function b(n,e,s){return globalThis.crypto.subtle.verify({name:"Ed25519"},n,e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength),s.buffer.slice(s.byteOffset,s.byteOffset+s.byteLength))}async function se(n,e){try{let{messageString:s,messageBytes:t,signatureBytes:a,offchainSignatories:i}=ne(n),o=siwxCore.parseMessage(s),g=orbitCore.parseCaip2ChainId(o.chainId)?.namespace;if(g!=="solana")throw new siwxCore.SiwxUnsupportedNamespaceError(g??"unknown");if(a.length!==64)throw new siwxCore.SiwxVerificationError(`Invalid Solana signature length: ${a.length} bytes (expected 64)`);let r=siwxCore.validateMessage(o,{skipExpiration:e?.skipExpiration,policy:{enforceNotBefore:!0}});if(!r.valid)throw new siwxCore.SiwxValidationError(r.errors);let f=orbitCore.parseCaip10AccountId(o.address);if(f?.namespace!=="solana")throw new siwxCore.SiwxVerificationError(`Expected solana CAIP-10 address format. Got: "${o.address}"`);let c=f.address,l=kit.address(c),m=L(l),h=await globalThis.crypto.subtle.importKey("raw",m.buffer,{name:"Ed25519"},!1,["verify"]),y;if(i){if(i.length!==1||i[0]!==l)throw new siwxCore.SiwxVerificationError(`Off-chain message signatory must be the message address only. Got: ${i.join(", ")}`);y=await b(h,a,t);}else if(y=await b(h,a,t),!y){let M=ee(s,l);M&&(y=await b(h,a,M));}if(!y)throw new siwxCore.SiwxVerificationError(`ed25519 signature verification failed for address: ${c}`);return {success:!0,data:o}}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=C;exports.verifyEd25519=se;
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import {getUtf8Encoder,createSignableMessage,getBase58Decoder,address,compileOffchainMessageV1Envelope,getAddressEncoder,getOffchainMessageDecoder}from'@solana/kit';import {parseCaip2ChainId,parseCaip10AccountId}from'@tuwaio/orbit-core';import {parseMessage,SiwxUnsupportedNamespaceError,SiwxVerificationError,validateMessage,SiwxValidationError}from'@tuwaio/siwx-core';function B(n,e){if(n===e)return true;if(n.length!==e.length)return false;for(let s=0;s<n.length;s++)if(n[s]!==e[s])return false;return true}function K(n,e,s){if(typeof n?.modifyAndSignMessages=="function")return n;if(typeof e?.modifyAndSignMessages=="function")return e;let t=e?.features,a=n?.features,i;Array.isArray(t)&&t.includes("solana:signMessage"),a&&typeof a=="object"&&!Array.isArray(a)&&(i=a["solana:signMessage"]);let o=n?.adapter??e?.adapter,g=[n,o,e,s].find(l=>typeof l?.signMessage=="function"),r=g?.signMessage,f=n?.signMessages??e?.signMessages;if(!i&&!r&&!f)throw new Error("[SIWX-SOLANA] Signer lacks known message signing capabilities.");let c=String(e?.address??n?.address??"solana:signer");return {address:c,async modifyAndSignMessages(l,m={}){if(m.abortSignal?.aborted)throw new Error("Aborted");if(l.length===0)return l;let y=[];for(let M=0;M<l.length;M++){let u=l[M],S,p;if(i){let d=[{account:e,message:u.content}],O=(await i.signMessage(...d))[0];if(!O||!O.signature)throw new Error("[SIWX-SOLANA] Wallet returned invalid signMessage output.");S=O.signature,p=O.signedMessage??u.content;}else if(typeof f=="function"){let h=(await f([{account:e,message:u.content}]))[0];if(!h||!h.signature)throw new Error("[SIWX-SOLANA] Wallet returned invalid signMessages output.");S=h.signature,p=h.signedMessage??u.content;}else if(typeof r=="function"){let d=await r.call(g,u.content);if(p=u.content,d instanceof Uint8Array||d&&d.buffer instanceof ArrayBuffer)S=d;else if(d&&typeof d=="object"&&"signature"in d)S=d.signature;else throw new Error("[SIWX-SOLANA] Unexpected legacy signMessage result format.")}else throw new Error("[SIWX-SOLANA] Missing signing implementation.");let k=u.content.length!==p.length||u.content.some((d,h)=>d!==p[h]),x=u.signatures[c];if(!(x===void 0||!B(x,S))&&!k){y.push(u);continue}let F=k?{[c]:S}:{...u.signatures,[c]:S};y.push(Object.freeze({content:p,signatures:Object.freeze(F)}));}return y}}}function $(n,e,s){let t=n.features,a=t&&typeof t=="object"&&!Array.isArray(t)?t["solana:signOffchainMessage"]:void 0;if(a&&typeof a.signOffchainMessage=="function")return a.supportedMessageVersions?.includes(1)?{async sign(o){let r=(await a.signOffchainMessage({account:e,message:o,messageVersion:1,requiredSigners:[q(e)]}))[0];if(!r?.signature)throw new Error("[SIWX-SOLANA] Wallet returned invalid signOffchainMessage output.");return r}}:{error:"The wallet cannot sign version 1 off-chain messages."};let i=[n,e,s].find(o=>typeof o.signOffchainMessage=="function");if(i){let o=i.signOffchainMessage;return {async sign(g){let r=await o.call(i,g);if(!r?.signature)throw new Error("[SIWX-SOLANA] Wallet returned invalid signOffchainMessage output.");return r}}}}function q(n){let e=n.publicKey;return e instanceof Uint8Array?e:new Uint8Array(getAddressEncoder().encode(address(String(n.address))))}function U(n,e,s){for(let a of [e,n,s]){let i=a.address;if(typeof i=="string")return i}let t=s.publicKey;return typeof t?.toBase58=="function"?t.toBase58():void 0}async function E(n,e,s){if(!n.sign)throw new Error(`[SIWX-SOLANA] ${n.error}`);let t=await n.sign(e);if(t.signedOffchainMessage&&s){let a=compileOffchainMessageV1Envelope({version:1,content:e,requiredSignatories:[{address:address(s)}]}).content;if(!B(new Uint8Array(t.signedOffchainMessage),a))throw new Error("[SIWX-SOLANA] Wallet signed a different off-chain message than requested.")}return getBase58Decoder().decode(new Uint8Array(t.signature))}function v(n,e){let s=n.features;return !Array.isArray(s)||s.includes(e)}function C(n,e={}){let s=e.messageFormat??"auto";return async t=>{try{if(!n)throw new Error("[SIWX-SOLANA] Invalid signer target.");let a=n,{wallet:i,account:o}=n,g=i??n,r=o??n,f=s==="message"?void 0:$(g,r,a);if(s==="offchainMessage"){if(!f)throw new Error("[SIWX-SOLANA] Signer cannot sign off-chain messages.");return await E(f,t,U(g,r,a))}let c;try{c=K(g,r,a);}catch(p){if(!f?.sign)throw p}if(f?.sign&&(!c||!v(r,"solana:signMessage")&&v(r,"solana:signOffchainMessage"))||!c)return await E(f,t,U(g,r,a));let A=getUtf8Encoder().encode(t),y=createSignableMessage(A),u=(await c.modifyAndSignMessages([y]))[0];if(!u)throw new Error("[SIWX-SOLANA] No signed message returned.");let S=u.signatures[c.address];if(!S)throw new Error(`[SIWX-SOLANA] Signature missing for address: ${c.address}`);return getBase58Decoder().decode(S)}catch(a){throw new Error(`[SIWX-SOLANA] Signing failed: ${a.message}`,{cause:a})}}}function L(n){let e="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz",s=new Map(e.split("").map((r,f)=>[r,BigInt(f)])),t=0n;for(let r of n){let f=s.get(r);if(f===void 0)throw new SiwxVerificationError(`Invalid base58 character: "${r}"`);t=t*58n+f;}let a=t.toString(16);a.length%2!==0&&(a="0"+a);let i=[];for(let r=0;r<a.length;r+=2)i.push(parseInt(a.slice(r,r+2),16));let o=0;for(let r of n)if(r==="1")o++;else break;let g=new Uint8Array(o+i.length);return g.set(i,o),g}var P=new Uint8Array([255,...new TextEncoder().encode("solana offchain")]);function Q(n){return n.length>P.length&&P.every((e,s)=>n[s]===e)}function Y(n){let e;try{e=getOffchainMessageDecoder().decode(n);}catch(s){throw new SiwxVerificationError(`Invalid off-chain message: ${String(s)}`)}if(e.version!==1)throw new SiwxVerificationError(`Unsupported off-chain message version: ${e.version} (expected 1)`);return {content:e.content,signatories:e.requiredSignatories.map(({address:s})=>s)}}function ee(n,e){try{return compileOffchainMessageV1Envelope({version:1,content:n,requiredSignatories:[{address:address(e)}]}).content}catch{return}}function ne(n){let e="output"in n?n.output:n,s="signedMessage"in e?e.signedMessage:e.message,t=e.signature,a,i,o;if(s instanceof Uint8Array)if(i=s,Q(s)){let r=Y(s);a=r.content,o=r.signatories;}else a=new TextDecoder().decode(s);else a=s,i=new TextEncoder().encode(s);let g;return t instanceof Uint8Array?g=t:g=L(t),{messageString:a,messageBytes:i,signatureBytes:g,offchainSignatories:o}}async function b(n,e,s){return globalThis.crypto.subtle.verify({name:"Ed25519"},n,e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength),s.buffer.slice(s.byteOffset,s.byteOffset+s.byteLength))}async function se(n,e){try{let{messageString:s,messageBytes:t,signatureBytes:a,offchainSignatories:i}=ne(n),o=parseMessage(s),g=parseCaip2ChainId(o.chainId)?.namespace;if(g!=="solana")throw new SiwxUnsupportedNamespaceError(g??"unknown");if(a.length!==64)throw new SiwxVerificationError(`Invalid Solana signature length: ${a.length} bytes (expected 64)`);let r=validateMessage(o,{skipExpiration:e?.skipExpiration,policy:{enforceNotBefore:!0}});if(!r.valid)throw new SiwxValidationError(r.errors);let f=parseCaip10AccountId(o.address);if(f?.namespace!=="solana")throw new SiwxVerificationError(`Expected solana CAIP-10 address format. Got: "${o.address}"`);let c=f.address,l=address(c),m=L(l),A=await globalThis.crypto.subtle.importKey("raw",m.buffer,{name:"Ed25519"},!1,["verify"]),y;if(i){if(i.length!==1||i[0]!==l)throw new SiwxVerificationError(`Off-chain message signatory must be the message address only. Got: ${i.join(", ")}`);y=await b(A,a,t);}else if(y=await b(A,a,t),!y){let M=ee(s,l);M&&(y=await b(A,a,M));}if(!y)throw new SiwxVerificationError(`ed25519 signature verification failed for address: ${c}`);return {success:!0,data:o}}catch(s){return s instanceof SiwxVerificationError||s instanceof SiwxValidationError?{success:false,error:s.message}:{success:false,error:`ed25519 verification failed: ${String(s)}`}}}export{C as createSolanaSiwxSigner,se as verifyEd25519};
1
+ import {getUtf8Encoder,createSignableMessage,getBase58Decoder,address,compileOffchainMessageV1Envelope,getAddressEncoder,getOffchainMessageDecoder}from'@solana/kit';import {parseCaip2ChainId,parseCaip10AccountId}from'@tuwaio/orbit-core';import {parseMessage,SiwxUnsupportedNamespaceError,SiwxVerificationError,validateMessage,SiwxValidationError}from'@tuwaio/siwx-core';function B(n,e){if(n===e)return true;if(n.length!==e.length)return false;for(let s=0;s<n.length;s++)if(n[s]!==e[s])return false;return true}function j(n,e,s){if(typeof n?.modifyAndSignMessages=="function")return n;if(typeof e?.modifyAndSignMessages=="function")return e;let t=e?.features,a=n?.features,i;Array.isArray(t)&&t.includes("solana:signMessage"),a&&typeof a=="object"&&!Array.isArray(a)&&(i=a["solana:signMessage"]);let o=n?.adapter??e?.adapter,g=[n,o,e,s].find(l=>typeof l?.signMessage=="function"),r=g?.signMessage,f=n?.signMessages??e?.signMessages;if(!i&&!r&&!f)throw new Error("[SIWX-SOLANA] Signer lacks known message signing capabilities.");let c=String(e?.address??n?.address??"solana:signer");return {address:c,async modifyAndSignMessages(l,m={}){if(m.abortSignal?.aborted)throw new Error("Aborted");if(l.length===0)return l;let y=[];for(let M=0;M<l.length;M++){let u=l[M],S,p;if(i){let d=[{account:e,message:u.content}],O=(await i.signMessage(...d))[0];if(!O||!O.signature)throw new Error("[SIWX-SOLANA] Wallet returned invalid signMessage output.");S=O.signature,p=O.signedMessage??u.content;}else if(typeof f=="function"){let A=(await f([{account:e,message:u.content}]))[0];if(!A||!A.signature)throw new Error("[SIWX-SOLANA] Wallet returned invalid signMessages output.");S=A.signature,p=A.signedMessage??u.content;}else if(typeof r=="function"){let d=await r.call(g,u.content);if(p=u.content,d instanceof Uint8Array||d&&d.buffer instanceof ArrayBuffer)S=d;else if(d&&typeof d=="object"&&"signature"in d)S=d.signature;else throw new Error("[SIWX-SOLANA] Unexpected legacy signMessage result format.")}else throw new Error("[SIWX-SOLANA] Missing signing implementation.");let k=u.content.length!==p.length||u.content.some((d,A)=>d!==p[A]),U=u.signatures[c];if(!(U===void 0||!B(U,S))&&!k){y.push(u);continue}let T=k?{[c]:S}:{...u.signatures,[c]:S};y.push(Object.freeze({content:p,signatures:Object.freeze(T)}));}return y}}}function $(n,e,s){let t=n.features,a=t&&typeof t=="object"&&!Array.isArray(t)?t["solana:signOffchainMessage"]:void 0;if(a&&typeof a.signOffchainMessage=="function")return a.supportedMessageVersions?.includes(1)?{async sign(o){let r=(await a.signOffchainMessage({account:e,message:o,messageVersion:1,requiredSigners:[q(e)]}))[0];if(!r?.signature)throw new Error("[SIWX-SOLANA] Wallet returned invalid signOffchainMessage output.");return r}}:{error:"The wallet cannot sign version 1 off-chain messages."};let i=[n,e,s].find(o=>typeof o.signOffchainMessage=="function");if(i){let o=i.signOffchainMessage;return {async sign(g){let r=await o.call(i,g);if(!r?.signature)throw new Error("[SIWX-SOLANA] Wallet returned invalid signOffchainMessage output.");return r}}}}function q(n){let e=n.publicKey;return e instanceof Uint8Array?e:new Uint8Array(getAddressEncoder().encode(address(String(n.address))))}function x(n,e,s){for(let a of [e,n,s]){let i=a.address;if(typeof i=="string")return i}let t=s.publicKey;return typeof t?.toBase58=="function"?t.toBase58():void 0}async function E(n,e,s){if(!n.sign)throw new Error(`[SIWX-SOLANA] ${n.error}`);let t=await n.sign(e);if(t.signedOffchainMessage&&s){let a=compileOffchainMessageV1Envelope({version:1,content:e,requiredSignatories:[{address:address(s)}]}).content;if(!B(new Uint8Array(t.signedOffchainMessage),a))throw new Error("[SIWX-SOLANA] Wallet signed a different off-chain message than requested.")}return getBase58Decoder().decode(new Uint8Array(t.signature))}function v(n,e){let s=n.features;return !Array.isArray(s)||s.includes(e)}function C(n,e={}){let s=e.messageFormat??"auto";return async t=>{try{if(!n)throw new Error("[SIWX-SOLANA] Invalid signer target.");let a=n,{wallet:i,account:o}=n,g=i??n,r=o??n,f=s==="message"?void 0:$(g,r,a);if(s==="offchainMessage"){if(!f)throw new Error("[SIWX-SOLANA] Signer cannot sign off-chain messages.");return await E(f,t,x(g,r,a))}let c;try{c=j(g,r,a);}catch(p){if(!f?.sign)throw p}if(f?.sign&&(!c||!v(r,"solana:signMessage")&&v(r,"solana:signOffchainMessage"))||!c)return await E(f,t,x(g,r,a));let h=getUtf8Encoder().encode(t),y=createSignableMessage(h),u=(await c.modifyAndSignMessages([y]))[0];if(!u)throw new Error("[SIWX-SOLANA] No signed message returned.");let S=u.signatures[c.address];if(!S)throw new Error(`[SIWX-SOLANA] Signature missing for address: ${c.address}`);return getBase58Decoder().decode(S)}catch(a){throw new Error(`[SIWX-SOLANA] Signing failed: ${a.message}`,{cause:a})}}}function L(n){let e="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz",s=new Map(e.split("").map((r,f)=>[r,BigInt(f)])),t=0n;for(let r of n){let f=s.get(r);if(f===void 0)throw new SiwxVerificationError(`Invalid base58 character: "${r}"`);t=t*58n+f;}let a=t.toString(16);a.length%2!==0&&(a="0"+a);let i=[];for(let r=0;r<a.length;r+=2)i.push(parseInt(a.slice(r,r+2),16));let o=0;for(let r of n)if(r==="1")o++;else break;let g=new Uint8Array(o+i.length);return g.set(i,o),g}var R=new Uint8Array([255,...new TextEncoder().encode("solana offchain")]);function Q(n){return n.length>R.length&&R.every((e,s)=>n[s]===e)}function Y(n){let e;try{e=getOffchainMessageDecoder().decode(n);}catch(s){throw new SiwxVerificationError(`Invalid off-chain message: ${String(s)}`)}if(e.version!==1)throw new SiwxVerificationError(`Unsupported off-chain message version: ${e.version} (expected 1)`);return {content:e.content,signatories:e.requiredSignatories.map(({address:s})=>s)}}function ee(n,e){try{return compileOffchainMessageV1Envelope({version:1,content:n,requiredSignatories:[{address:address(e)}]}).content}catch{return}}function ne(n){let e="output"in n?n.output:n,s="signedMessage"in e?e.signedMessage:e.message,t=e.signature,a,i,o;if(s instanceof Uint8Array)if(i=s,Q(s)){let r=Y(s);a=r.content,o=r.signatories;}else a=new TextDecoder().decode(s);else a=s,i=new TextEncoder().encode(s);let g;return t instanceof Uint8Array?g=t:g=L(t),{messageString:a,messageBytes:i,signatureBytes:g,offchainSignatories:o}}async function b(n,e,s){return globalThis.crypto.subtle.verify({name:"Ed25519"},n,e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength),s.buffer.slice(s.byteOffset,s.byteOffset+s.byteLength))}async function se(n,e){try{let{messageString:s,messageBytes:t,signatureBytes:a,offchainSignatories:i}=ne(n),o=parseMessage(s),g=parseCaip2ChainId(o.chainId)?.namespace;if(g!=="solana")throw new SiwxUnsupportedNamespaceError(g??"unknown");if(a.length!==64)throw new SiwxVerificationError(`Invalid Solana signature length: ${a.length} bytes (expected 64)`);let r=validateMessage(o,{skipExpiration:e?.skipExpiration,policy:{enforceNotBefore:!0}});if(!r.valid)throw new SiwxValidationError(r.errors);let f=parseCaip10AccountId(o.address);if(f?.namespace!=="solana")throw new SiwxVerificationError(`Expected solana CAIP-10 address format. Got: "${o.address}"`);let c=f.address,l=address(c),m=L(l),h=await globalThis.crypto.subtle.importKey("raw",m.buffer,{name:"Ed25519"},!1,["verify"]),y;if(i){if(i.length!==1||i[0]!==l)throw new SiwxVerificationError(`Off-chain message signatory must be the message address only. Got: ${i.join(", ")}`);y=await b(h,a,t);}else if(y=await b(h,a,t),!y){let M=ee(s,l);M&&(y=await b(h,a,M));}if(!y)throw new SiwxVerificationError(`ed25519 signature verification failed for address: ${c}`);return {success:!0,data:o}}catch(s){return s instanceof SiwxVerificationError||s instanceof SiwxValidationError?{success:false,error:s.message}:{success:false,error:`ed25519 verification failed: ${String(s)}`}}}export{C as createSolanaSiwxSigner,se as verifyEd25519};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tuwaio/siwx-solana",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
4
4
  "private": false,
5
5
  "author": "Oleksandr Tkach",
6
6
  "license": "Apache-2.0",
@@ -61,7 +61,7 @@
61
61
  "scripts": {
62
62
  "start": "tsup src/index.ts --watch",
63
63
  "build": "tsup",
64
- "test": "vitest run",
64
+ "test": "vitest run --typecheck",
65
65
  "test:coverage": "vitest run --coverage"
66
66
  }
67
67
  }