@sip-protocol/sdk 0.7.0 → 0.7.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.
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Solana Same-Chain Privacy Types
3
+ *
4
+ * Type definitions for Solana stealth address transfers and scanning.
5
+ */
6
+
7
+ import type { PublicKey, Connection, Transaction, VersionedTransaction } from '@solana/web3.js'
8
+ import type { StealthMetaAddress, StealthAddress, HexString } from '@sip-protocol/types'
9
+ import type { SolanaCluster } from './constants'
10
+
11
+ /**
12
+ * Parameters for sending a private SPL token transfer
13
+ */
14
+ export interface SolanaPrivateTransferParams {
15
+ /** Solana RPC connection */
16
+ connection: Connection
17
+ /** Sender's public key */
18
+ sender: PublicKey
19
+ /** Sender's token account (ATA) */
20
+ senderTokenAccount: PublicKey
21
+ /** Recipient's stealth meta-address (sip:solana:...) */
22
+ recipientMetaAddress: StealthMetaAddress
23
+ /** SPL token mint address */
24
+ mint: PublicKey
25
+ /** Amount to transfer (in token's smallest unit) */
26
+ amount: bigint
27
+ /** Function to sign the transaction */
28
+ signTransaction: <T extends Transaction | VersionedTransaction>(tx: T) => Promise<T>
29
+ }
30
+
31
+ /**
32
+ * Result of a private SPL token transfer
33
+ */
34
+ export interface SolanaPrivateTransferResult {
35
+ /** Transaction signature */
36
+ txSignature: string
37
+ /** Stealth address (base58 Solana address) */
38
+ stealthAddress: string
39
+ /** Ephemeral public key (base58) for recipient scanning */
40
+ ephemeralPublicKey: string
41
+ /** View tag for efficient scanning */
42
+ viewTag: string
43
+ /** Explorer URL for the transaction */
44
+ explorerUrl: string
45
+ /** Cluster the transaction was sent on */
46
+ cluster: SolanaCluster
47
+ }
48
+
49
+ /**
50
+ * Parameters for scanning for incoming stealth payments
51
+ */
52
+ export interface SolanaScanParams {
53
+ /** Solana RPC connection */
54
+ connection: Connection
55
+ /** Recipient's viewing private key (hex) */
56
+ viewingPrivateKey: HexString
57
+ /** Recipient's spending public key (hex) */
58
+ spendingPublicKey: HexString
59
+ /** Optional: Start scanning from this slot */
60
+ fromSlot?: number
61
+ /** Optional: Stop scanning at this slot */
62
+ toSlot?: number
63
+ /** Optional: Limit number of results */
64
+ limit?: number
65
+ }
66
+
67
+ /**
68
+ * Result of scanning for incoming payments
69
+ */
70
+ export interface SolanaScanResult {
71
+ /** Stealth address that received the payment (base58) */
72
+ stealthAddress: string
73
+ /** Ephemeral public key from the sender (base58) */
74
+ ephemeralPublicKey: string
75
+ /** Amount received (in token's smallest unit) */
76
+ amount: bigint
77
+ /** Token mint address */
78
+ mint: string
79
+ /** Token symbol (if known) */
80
+ tokenSymbol?: string
81
+ /** Transaction signature */
82
+ txSignature: string
83
+ /** Block slot */
84
+ slot: number
85
+ /** Block timestamp */
86
+ timestamp: number
87
+ }
88
+
89
+ /**
90
+ * Parameters for claiming a stealth payment
91
+ */
92
+ export interface SolanaClaimParams {
93
+ /** Solana RPC connection */
94
+ connection: Connection
95
+ /** Stealth address to claim from (base58) */
96
+ stealthAddress: string
97
+ /** Ephemeral public key from the payment (base58) */
98
+ ephemeralPublicKey: string
99
+ /** Recipient's viewing private key (hex) */
100
+ viewingPrivateKey: HexString
101
+ /** Recipient's spending private key (hex) */
102
+ spendingPrivateKey: HexString
103
+ /** Destination address to send claimed funds (base58) */
104
+ destinationAddress: string
105
+ /** SPL token mint address */
106
+ mint: PublicKey
107
+ }
108
+
109
+ /**
110
+ * Result of claiming a stealth payment
111
+ */
112
+ export interface SolanaClaimResult {
113
+ /** Transaction signature */
114
+ txSignature: string
115
+ /** Destination address that received the funds (base58) */
116
+ destinationAddress: string
117
+ /** Amount claimed (in token's smallest unit) */
118
+ amount: bigint
119
+ /** Explorer URL for the transaction */
120
+ explorerUrl: string
121
+ }
122
+
123
+ /**
124
+ * Announcement data stored in transaction memo
125
+ */
126
+ export interface SolanaAnnouncement {
127
+ /** Ephemeral public key (base58) */
128
+ ephemeralPublicKey: string
129
+ /** View tag for efficient scanning (hex, 1 byte) */
130
+ viewTag: string
131
+ /** Full stealth address (for verification) */
132
+ stealthAddress?: string
133
+ }
134
+
135
+ /**
136
+ * Parse announcement from memo string
137
+ * Format: SIP:1:<ephemeral_pubkey_base58>:<view_tag_hex>
138
+ */
139
+ export function parseAnnouncement(memo: string): SolanaAnnouncement | null {
140
+ if (!memo.startsWith('SIP:1:')) {
141
+ return null
142
+ }
143
+
144
+ const parts = memo.slice(6).split(':')
145
+ if (parts.length < 2) {
146
+ return null
147
+ }
148
+
149
+ return {
150
+ ephemeralPublicKey: parts[0],
151
+ viewTag: parts[1],
152
+ stealthAddress: parts[2],
153
+ }
154
+ }
155
+
156
+ /**
157
+ * Create announcement memo string
158
+ */
159
+ export function createAnnouncementMemo(
160
+ ephemeralPublicKey: string,
161
+ viewTag: string,
162
+ stealthAddress?: string
163
+ ): string {
164
+ const parts = ['SIP:1', ephemeralPublicKey, viewTag]
165
+ if (stealthAddress) {
166
+ parts.push(stealthAddress)
167
+ }
168
+ return parts.join(':')
169
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Executors Module
3
+ *
4
+ * Transaction execution strategies for different scenarios.
5
+ *
6
+ * @packageDocumentation
7
+ */
8
+
9
+ export {
10
+ SolanaSameChainExecutor,
11
+ createSameChainExecutor,
12
+ isSameChainSupported,
13
+ getSupportedSameChainChains,
14
+ type SameChainExecutor,
15
+ type SameChainTransferParams,
16
+ type SameChainTransferResult,
17
+ type SolanaSameChainConfig,
18
+ } from './same-chain'
@@ -0,0 +1,154 @@
1
+ /**
2
+ * Same-Chain Privacy Executor
3
+ *
4
+ * Executes privacy-preserving transfers on the same chain,
5
+ * bypassing cross-chain settlement for direct transfers.
6
+ */
7
+
8
+ import type { Connection, PublicKey, Transaction, VersionedTransaction } from '@solana/web3.js'
9
+ import type { StealthMetaAddress, ChainId, HexString } from '@sip-protocol/types'
10
+ import {
11
+ sendPrivateSPLTransfer,
12
+ estimatePrivateTransferFee,
13
+ type SolanaPrivateTransferResult,
14
+ } from '../chains/solana'
15
+
16
+ /**
17
+ * Parameters for same-chain private transfer
18
+ */
19
+ export interface SameChainTransferParams {
20
+ /** Recipient's stealth meta-address */
21
+ recipientMetaAddress: StealthMetaAddress
22
+ /** Amount to transfer (in token's smallest unit) */
23
+ amount: bigint
24
+ /** Token identifier (symbol or mint address) */
25
+ token: string
26
+ }
27
+
28
+ /**
29
+ * Result of same-chain private transfer
30
+ */
31
+ export interface SameChainTransferResult {
32
+ /** Transaction signature/hash */
33
+ txHash: string
34
+ /** Stealth address that received the funds */
35
+ stealthAddress: string
36
+ /** Ephemeral public key for recipient scanning */
37
+ ephemeralPublicKey: string
38
+ /** Explorer URL */
39
+ explorerUrl: string
40
+ /** Chain the transfer was executed on */
41
+ chain: ChainId
42
+ }
43
+
44
+ /**
45
+ * Same-chain executor interface
46
+ */
47
+ export interface SameChainExecutor {
48
+ /** Chain this executor handles */
49
+ readonly chain: ChainId
50
+
51
+ /**
52
+ * Execute a same-chain private transfer
53
+ */
54
+ execute(params: SameChainTransferParams): Promise<SameChainTransferResult>
55
+
56
+ /**
57
+ * Estimate transaction fee
58
+ */
59
+ estimateFee(params: SameChainTransferParams): Promise<bigint>
60
+ }
61
+
62
+ /**
63
+ * Solana-specific executor configuration
64
+ */
65
+ export interface SolanaSameChainConfig {
66
+ /** Solana RPC connection */
67
+ connection: Connection
68
+ /** Sender's public key */
69
+ sender: PublicKey
70
+ /** Sender's token account getter */
71
+ getTokenAccount: (mint: PublicKey) => Promise<PublicKey>
72
+ /** Transaction signer */
73
+ signTransaction: <T extends Transaction | VersionedTransaction>(tx: T) => Promise<T>
74
+ /** Token mint resolver (symbol -> PublicKey) */
75
+ getTokenMint: (symbol: string) => PublicKey
76
+ }
77
+
78
+ /**
79
+ * Solana Same-Chain Executor
80
+ *
81
+ * Executes privacy-preserving SPL token transfers on Solana.
82
+ */
83
+ export class SolanaSameChainExecutor implements SameChainExecutor {
84
+ readonly chain = 'solana' as const
85
+ private config: SolanaSameChainConfig
86
+
87
+ constructor(config: SolanaSameChainConfig) {
88
+ this.config = config
89
+ }
90
+
91
+ async execute(params: SameChainTransferParams): Promise<SameChainTransferResult> {
92
+ const { recipientMetaAddress, amount, token } = params
93
+ const { connection, sender, getTokenAccount, signTransaction, getTokenMint } = this.config
94
+
95
+ // Resolve token mint
96
+ const mint = getTokenMint(token)
97
+
98
+ // Get sender's token account
99
+ const senderTokenAccount = await getTokenAccount(mint)
100
+
101
+ // Execute private transfer
102
+ const result = await sendPrivateSPLTransfer({
103
+ connection,
104
+ sender,
105
+ senderTokenAccount,
106
+ recipientMetaAddress,
107
+ mint,
108
+ amount,
109
+ signTransaction,
110
+ })
111
+
112
+ return {
113
+ txHash: result.txSignature,
114
+ stealthAddress: result.stealthAddress,
115
+ ephemeralPublicKey: result.ephemeralPublicKey,
116
+ explorerUrl: result.explorerUrl,
117
+ chain: 'solana',
118
+ }
119
+ }
120
+
121
+ async estimateFee(params: SameChainTransferParams): Promise<bigint> {
122
+ // For now, assume ATA might need creation
123
+ return estimatePrivateTransferFee(this.config.connection, true)
124
+ }
125
+ }
126
+
127
+ /**
128
+ * Factory function to create a same-chain executor for a given chain
129
+ */
130
+ export function createSameChainExecutor(
131
+ chain: ChainId,
132
+ config: SolanaSameChainConfig
133
+ ): SameChainExecutor {
134
+ switch (chain) {
135
+ case 'solana':
136
+ return new SolanaSameChainExecutor(config)
137
+ default:
138
+ throw new Error(`Same-chain executor not available for chain: ${chain}`)
139
+ }
140
+ }
141
+
142
+ /**
143
+ * Check if same-chain privacy is supported for a chain
144
+ */
145
+ export function isSameChainSupported(chain: ChainId): boolean {
146
+ return chain === 'solana'
147
+ }
148
+
149
+ /**
150
+ * Get supported same-chain privacy chains
151
+ */
152
+ export function getSupportedSameChainChains(): ChainId[] {
153
+ return ['solana']
154
+ }
package/src/index.ts CHANGED
@@ -46,7 +46,13 @@ export type { SerializedError } from './errors'
46
46
 
47
47
  // Main client
48
48
  export { SIP, createSIP, createProductionSIP } from './sip'
49
- export type { SIPConfig, WalletAdapter, ProductionQuote } from './sip'
49
+ export type {
50
+ SIPConfig,
51
+ WalletAdapter,
52
+ ProductionQuote,
53
+ SameChainExecuteParams,
54
+ SameChainExecuteResult,
55
+ } from './sip'
50
56
 
51
57
  // Intent creation
52
58
  export {
@@ -740,3 +746,54 @@ export type {
740
746
  HardwareErrorCodeType,
741
747
  MockHardwareConfig,
742
748
  } from './wallet'
749
+
750
+ // Solana Same-Chain Privacy
751
+ export {
752
+ // Transfer
753
+ sendPrivateSPLTransfer,
754
+ estimatePrivateTransferFee,
755
+ hasTokenAccount,
756
+ // Scan and Claim
757
+ scanForPayments,
758
+ claimStealthPayment,
759
+ getStealthBalance,
760
+ // Constants
761
+ SOLANA_TOKEN_MINTS,
762
+ SOLANA_TOKEN_DECIMALS,
763
+ SOLANA_RPC_ENDPOINTS,
764
+ SOLANA_EXPLORER_URLS,
765
+ MEMO_PROGRAM_ID,
766
+ SIP_MEMO_PREFIX,
767
+ getExplorerUrl as getSolanaExplorerUrl,
768
+ getTokenMint,
769
+ getTokenDecimals,
770
+ // Types helpers
771
+ parseAnnouncement,
772
+ createAnnouncementMemo,
773
+ } from './chains/solana'
774
+
775
+ export type {
776
+ SolanaPrivateTransferParams,
777
+ SolanaPrivateTransferResult,
778
+ SolanaScanParams,
779
+ SolanaScanResult,
780
+ SolanaClaimParams,
781
+ SolanaClaimResult,
782
+ SolanaAnnouncement,
783
+ SolanaCluster as SolanaSameChainCluster,
784
+ } from './chains/solana'
785
+
786
+ // Same-Chain Executors
787
+ export {
788
+ SolanaSameChainExecutor,
789
+ createSameChainExecutor,
790
+ isSameChainSupported,
791
+ getSupportedSameChainChains,
792
+ } from './executors'
793
+
794
+ export type {
795
+ SameChainExecutor,
796
+ SameChainTransferParams,
797
+ SameChainTransferResult,
798
+ SolanaSameChainConfig,
799
+ } from './executors'
package/src/sip.ts CHANGED
@@ -969,6 +969,133 @@ export class SIP {
969
969
  fulfilledAt: Math.floor(Date.now() / 1000),
970
970
  }
971
971
  }
972
+
973
+ // ─── Same-Chain Privacy ───────────────────────────────────────────────────
974
+
975
+ /**
976
+ * Execute a same-chain private transfer
977
+ *
978
+ * Bypasses cross-chain settlement for direct on-chain privacy transfers.
979
+ * Currently supports Solana only.
980
+ *
981
+ * @param chain - Chain to execute on (must be 'solana')
982
+ * @param params - Transfer parameters
983
+ * @returns Transfer result with stealth address
984
+ *
985
+ * @example
986
+ * ```typescript
987
+ * const result = await sip.executeSameChain('solana', {
988
+ * recipientMetaAddress: {
989
+ * chain: 'solana',
990
+ * spendingKey: '0x...',
991
+ * viewingKey: '0x...',
992
+ * },
993
+ * amount: 5_000_000n, // 5 USDC
994
+ * token: 'USDC',
995
+ * connection,
996
+ * sender: wallet.publicKey,
997
+ * signTransaction: wallet.signTransaction,
998
+ * })
999
+ *
1000
+ * console.log('Sent to stealth:', result.stealthAddress)
1001
+ * ```
1002
+ */
1003
+ async executeSameChain(
1004
+ chain: ChainId,
1005
+ params: SameChainExecuteParams
1006
+ ): Promise<SameChainExecuteResult> {
1007
+ // Validate chain support
1008
+ if (chain !== 'solana') {
1009
+ throw new ValidationError(
1010
+ `Same-chain privacy only supported for 'solana', got '${chain}'`,
1011
+ 'chain'
1012
+ )
1013
+ }
1014
+
1015
+ // Import Solana execution dynamically to avoid bundling issues
1016
+ const { sendPrivateSPLTransfer } = await import('./chains/solana')
1017
+ const { PublicKey: SolanaPublicKey } = await import('@solana/web3.js')
1018
+ const { getAssociatedTokenAddress } = await import('@solana/spl-token')
1019
+ const { SOLANA_TOKEN_MINTS } = await import('./chains/solana/constants')
1020
+
1021
+ // Resolve token mint
1022
+ let mint: InstanceType<typeof SolanaPublicKey>
1023
+ if (params.token in SOLANA_TOKEN_MINTS) {
1024
+ mint = new SolanaPublicKey(SOLANA_TOKEN_MINTS[params.token as keyof typeof SOLANA_TOKEN_MINTS])
1025
+ } else {
1026
+ // Assume it's a mint address
1027
+ mint = new SolanaPublicKey(params.token)
1028
+ }
1029
+
1030
+ // Get sender's token account
1031
+ const senderTokenAccount = await getAssociatedTokenAddress(
1032
+ mint,
1033
+ params.sender
1034
+ )
1035
+
1036
+ // Execute private transfer
1037
+ const result = await sendPrivateSPLTransfer({
1038
+ connection: params.connection,
1039
+ sender: params.sender,
1040
+ senderTokenAccount,
1041
+ recipientMetaAddress: params.recipientMetaAddress,
1042
+ mint,
1043
+ amount: params.amount,
1044
+ signTransaction: params.signTransaction,
1045
+ })
1046
+
1047
+ return {
1048
+ txHash: result.txSignature,
1049
+ stealthAddress: result.stealthAddress,
1050
+ ephemeralPublicKey: result.ephemeralPublicKey,
1051
+ viewTag: result.viewTag,
1052
+ explorerUrl: result.explorerUrl,
1053
+ chain: 'solana',
1054
+ }
1055
+ }
1056
+
1057
+ /**
1058
+ * Check if same-chain privacy is supported for a chain
1059
+ */
1060
+ isSameChainSupported(chain: ChainId): boolean {
1061
+ return chain === 'solana'
1062
+ }
1063
+ }
1064
+
1065
+ /**
1066
+ * Parameters for same-chain private transfer execution
1067
+ */
1068
+ export interface SameChainExecuteParams {
1069
+ /** Recipient's stealth meta-address */
1070
+ recipientMetaAddress: StealthMetaAddress
1071
+ /** Amount to transfer (in token's smallest unit) */
1072
+ amount: bigint
1073
+ /** Token symbol (e.g., 'USDC') or mint address */
1074
+ token: string
1075
+ /** Solana RPC connection */
1076
+ connection: import('@solana/web3.js').Connection
1077
+ /** Sender's public key */
1078
+ sender: import('@solana/web3.js').PublicKey
1079
+ /** Transaction signer */
1080
+ signTransaction: <T extends import('@solana/web3.js').Transaction | import('@solana/web3.js').VersionedTransaction>(tx: T) => Promise<T>
1081
+ }
1082
+
1083
+ /**
1084
+ * Result of same-chain private transfer
1085
+ */
1086
+ export interface SameChainExecuteResult {
1087
+ /** Transaction hash */
1088
+ txHash: string
1089
+ /** Stealth address that received the funds */
1090
+ stealthAddress: string
1091
+ /** Ephemeral public key for recipient scanning */
1092
+ ephemeralPublicKey: string
1093
+ /** View tag for efficient scanning */
1094
+ viewTag: string
1095
+ /** Explorer URL */
1096
+ explorerUrl: string
1097
+ /** Chain the transfer was executed on */
1098
+ chain: ChainId
972
1099
  }
973
1100
 
974
1101
  /**
package/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 RECTOR Labs
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.