@sip-protocol/sdk 0.1.0 → 0.1.4
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 +3236 -1554
- package/dist/index.d.ts +3236 -1554
- package/dist/index.js +9185 -3521
- package/dist/index.mjs +8995 -3376
- package/package.json +5 -2
- package/src/adapters/near-intents.ts +48 -35
- package/src/adapters/oneclick-client.ts +9 -1
- package/src/compliance/compliance-manager.ts +1035 -0
- package/src/compliance/index.ts +43 -0
- package/src/index.ts +129 -2
- package/src/payment/index.ts +54 -0
- package/src/payment/payment.ts +623 -0
- package/src/payment/stablecoins.ts +306 -0
- package/src/privacy.ts +127 -94
- package/src/proofs/circuits/fulfillment_proof.json +1 -0
- package/src/proofs/circuits/funding_proof.json +1 -0
- package/src/proofs/circuits/validity_proof.json +1 -0
- package/src/proofs/interface.ts +13 -1
- package/src/proofs/noir.ts +967 -97
- package/src/secure-memory.ts +147 -0
- package/src/sip.ts +399 -37
- package/src/stealth.ts +116 -84
- package/src/treasury/index.ts +43 -0
- package/src/treasury/treasury.ts +911 -0
- package/src/wallet/hardware/index.ts +87 -0
- package/src/wallet/hardware/ledger.ts +628 -0
- package/src/wallet/hardware/mock.ts +667 -0
- package/src/wallet/hardware/trezor.ts +657 -0
- package/src/wallet/hardware/types.ts +317 -0
- package/src/wallet/index.ts +40 -0
- package/src/zcash/shielded-service.ts +59 -1
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hardware Wallet Types
|
|
3
|
+
*
|
|
4
|
+
* Type definitions for hardware wallet adapters (Ledger, Trezor).
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { ChainId, HexString } from '@sip-protocol/types'
|
|
8
|
+
|
|
9
|
+
// ─── Device Types ───────────────────────────────────────────────────────────────
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Supported hardware wallet manufacturers
|
|
13
|
+
*/
|
|
14
|
+
export type HardwareWalletType = 'ledger' | 'trezor'
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Ledger device models
|
|
18
|
+
*/
|
|
19
|
+
export type LedgerModel = 'nanoS' | 'nanoSPlus' | 'nanoX' | 'stax' | 'flex'
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Trezor device models
|
|
23
|
+
*/
|
|
24
|
+
export type TrezorModel = 'one' | 'T' | 'safe3' | 'safe5'
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Hardware wallet connection status
|
|
28
|
+
*/
|
|
29
|
+
export type HardwareConnectionStatus =
|
|
30
|
+
| 'disconnected'
|
|
31
|
+
| 'connecting'
|
|
32
|
+
| 'connected'
|
|
33
|
+
| 'locked'
|
|
34
|
+
| 'app_closed'
|
|
35
|
+
| 'error'
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Transport type for device communication
|
|
39
|
+
*/
|
|
40
|
+
export type TransportType = 'usb' | 'bluetooth' | 'webusb' | 'webhid'
|
|
41
|
+
|
|
42
|
+
// ─── Device Info ────────────────────────────────────────────────────────────────
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Hardware device information
|
|
46
|
+
*/
|
|
47
|
+
export interface HardwareDeviceInfo {
|
|
48
|
+
/** Device manufacturer */
|
|
49
|
+
manufacturer: HardwareWalletType
|
|
50
|
+
/** Device model */
|
|
51
|
+
model: string
|
|
52
|
+
/** Firmware version */
|
|
53
|
+
firmwareVersion?: string
|
|
54
|
+
/** Whether device is locked */
|
|
55
|
+
isLocked: boolean
|
|
56
|
+
/** Currently open app (if any) */
|
|
57
|
+
currentApp?: string
|
|
58
|
+
/** Device label/name (user-set) */
|
|
59
|
+
label?: string
|
|
60
|
+
/** Device ID (unique identifier) */
|
|
61
|
+
deviceId?: string
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// ─── Derivation Paths ───────────────────────────────────────────────────────────
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Standard BIP44 derivation paths
|
|
68
|
+
*/
|
|
69
|
+
export const DerivationPath = {
|
|
70
|
+
/** Ethereum: m/44'/60'/0'/0/index */
|
|
71
|
+
ETHEREUM: "m/44'/60'/0'/0",
|
|
72
|
+
/** Ethereum (Ledger Live): m/44'/60'/index'/0/0 */
|
|
73
|
+
ETHEREUM_LEDGER_LIVE: "m/44'/60'",
|
|
74
|
+
/** Solana: m/44'/501'/0'/0' */
|
|
75
|
+
SOLANA: "m/44'/501'/0'/0'",
|
|
76
|
+
/** Bitcoin: m/84'/0'/0'/0 (native segwit) */
|
|
77
|
+
BITCOIN: "m/84'/0'/0'/0",
|
|
78
|
+
/** NEAR: m/44'/397'/0' */
|
|
79
|
+
NEAR: "m/44'/397'/0'",
|
|
80
|
+
} as const
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Get derivation path for a chain
|
|
84
|
+
*/
|
|
85
|
+
export function getDerivationPath(chain: ChainId, accountIndex: number = 0): string {
|
|
86
|
+
switch (chain) {
|
|
87
|
+
case 'ethereum':
|
|
88
|
+
return `${DerivationPath.ETHEREUM}/${accountIndex}`
|
|
89
|
+
case 'solana':
|
|
90
|
+
return DerivationPath.SOLANA.replace("0'", `${accountIndex}'`)
|
|
91
|
+
case 'bitcoin':
|
|
92
|
+
return `${DerivationPath.BITCOIN}/${accountIndex}`
|
|
93
|
+
case 'near':
|
|
94
|
+
return DerivationPath.NEAR.replace("0'", `${accountIndex}'`)
|
|
95
|
+
default:
|
|
96
|
+
return `${DerivationPath.ETHEREUM}/${accountIndex}`
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// ─── Configuration ──────────────────────────────────────────────────────────────
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Base hardware wallet configuration
|
|
104
|
+
*/
|
|
105
|
+
export interface HardwareWalletConfig {
|
|
106
|
+
/** Target chain */
|
|
107
|
+
chain: ChainId
|
|
108
|
+
/** Account index (default: 0) */
|
|
109
|
+
accountIndex?: number
|
|
110
|
+
/** Custom derivation path (overrides default) */
|
|
111
|
+
derivationPath?: string
|
|
112
|
+
/** Transport type preference */
|
|
113
|
+
transport?: TransportType
|
|
114
|
+
/** Connection timeout in ms (default: 30000) */
|
|
115
|
+
timeout?: number
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Ledger-specific configuration
|
|
120
|
+
*/
|
|
121
|
+
export interface LedgerConfig extends HardwareWalletConfig {
|
|
122
|
+
/** Expected app name to be open on device */
|
|
123
|
+
appName?: string
|
|
124
|
+
/** Whether to use Ledger Live derivation path */
|
|
125
|
+
useLedgerLive?: boolean
|
|
126
|
+
/** Scramble key for transport */
|
|
127
|
+
scrambleKey?: string
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Trezor-specific configuration
|
|
132
|
+
*/
|
|
133
|
+
export interface TrezorConfig extends HardwareWalletConfig {
|
|
134
|
+
/** Trezor Connect manifest URL */
|
|
135
|
+
manifestUrl?: string
|
|
136
|
+
/** Trezor Connect manifest email */
|
|
137
|
+
manifestEmail?: string
|
|
138
|
+
/** Trezor Connect manifest app name */
|
|
139
|
+
manifestAppName?: string
|
|
140
|
+
/** Whether to use popup for Trezor Connect */
|
|
141
|
+
popup?: boolean
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// ─── Signing Requests ───────────────────────────────────────────────────────────
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Hardware wallet signing request
|
|
148
|
+
*/
|
|
149
|
+
export interface HardwareSignRequest {
|
|
150
|
+
/** Raw message to sign */
|
|
151
|
+
message: Uint8Array
|
|
152
|
+
/** Display message on device (if supported) */
|
|
153
|
+
displayMessage?: string
|
|
154
|
+
/** Whether this is a transaction (vs arbitrary message) */
|
|
155
|
+
isTransaction?: boolean
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Ethereum transaction for hardware signing
|
|
160
|
+
*/
|
|
161
|
+
export interface HardwareEthereumTx {
|
|
162
|
+
/** Recipient address */
|
|
163
|
+
to: string
|
|
164
|
+
/** Value in wei (hex) */
|
|
165
|
+
value: HexString
|
|
166
|
+
/** Gas limit (hex) */
|
|
167
|
+
gasLimit: HexString
|
|
168
|
+
/** Gas price (hex) - for legacy tx */
|
|
169
|
+
gasPrice?: HexString
|
|
170
|
+
/** Max fee per gas (hex) - for EIP-1559 */
|
|
171
|
+
maxFeePerGas?: HexString
|
|
172
|
+
/** Max priority fee per gas (hex) - for EIP-1559 */
|
|
173
|
+
maxPriorityFeePerGas?: HexString
|
|
174
|
+
/** Transaction data (hex) */
|
|
175
|
+
data?: HexString
|
|
176
|
+
/** Nonce (hex) */
|
|
177
|
+
nonce: HexString
|
|
178
|
+
/** Chain ID */
|
|
179
|
+
chainId: number
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Signature from hardware wallet
|
|
184
|
+
*/
|
|
185
|
+
export interface HardwareSignature {
|
|
186
|
+
/** r component */
|
|
187
|
+
r: HexString
|
|
188
|
+
/** s component */
|
|
189
|
+
s: HexString
|
|
190
|
+
/** v component (recovery id) */
|
|
191
|
+
v: number
|
|
192
|
+
/** Full signature (r + s + v) */
|
|
193
|
+
signature: HexString
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// ─── Account Info ───────────────────────────────────────────────────────────────
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Account derived from hardware wallet
|
|
200
|
+
*/
|
|
201
|
+
export interface HardwareAccount {
|
|
202
|
+
/** Account address */
|
|
203
|
+
address: string
|
|
204
|
+
/** Public key (hex) */
|
|
205
|
+
publicKey: HexString
|
|
206
|
+
/** Derivation path used */
|
|
207
|
+
derivationPath: string
|
|
208
|
+
/** Account index */
|
|
209
|
+
index: number
|
|
210
|
+
/** Chain */
|
|
211
|
+
chain: ChainId
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// ─── Transport Interfaces ───────────────────────────────────────────────────────
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Abstract transport interface for hardware communication
|
|
218
|
+
*
|
|
219
|
+
* This is implemented by actual transport libraries:
|
|
220
|
+
* - @ledgerhq/hw-transport-webusb
|
|
221
|
+
* - @ledgerhq/hw-transport-webhid
|
|
222
|
+
* - @trezor/connect-web
|
|
223
|
+
*/
|
|
224
|
+
export interface HardwareTransport {
|
|
225
|
+
/** Open connection to device */
|
|
226
|
+
open(): Promise<void>
|
|
227
|
+
/** Close connection */
|
|
228
|
+
close(): Promise<void>
|
|
229
|
+
/** Send APDU command (Ledger) */
|
|
230
|
+
send?(cla: number, ins: number, p1: number, p2: number, data?: Buffer): Promise<Buffer>
|
|
231
|
+
/** Check if transport is open */
|
|
232
|
+
isOpen?: boolean
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// ─── Error Types ────────────────────────────────────────────────────────────────
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Hardware wallet error codes
|
|
239
|
+
*/
|
|
240
|
+
export const HardwareErrorCode = {
|
|
241
|
+
/** Device not found/connected */
|
|
242
|
+
DEVICE_NOT_FOUND: 'HARDWARE_DEVICE_NOT_FOUND',
|
|
243
|
+
/** Device is locked (requires PIN) */
|
|
244
|
+
DEVICE_LOCKED: 'HARDWARE_DEVICE_LOCKED',
|
|
245
|
+
/** Required app not open on device */
|
|
246
|
+
APP_NOT_OPEN: 'HARDWARE_APP_NOT_OPEN',
|
|
247
|
+
/** User rejected on device */
|
|
248
|
+
USER_REJECTED: 'HARDWARE_USER_REJECTED',
|
|
249
|
+
/** Transport/communication error */
|
|
250
|
+
TRANSPORT_ERROR: 'HARDWARE_TRANSPORT_ERROR',
|
|
251
|
+
/** Timeout waiting for device */
|
|
252
|
+
TIMEOUT: 'HARDWARE_TIMEOUT',
|
|
253
|
+
/** Unsupported operation */
|
|
254
|
+
UNSUPPORTED: 'HARDWARE_UNSUPPORTED',
|
|
255
|
+
/** Invalid derivation path */
|
|
256
|
+
INVALID_PATH: 'HARDWARE_INVALID_PATH',
|
|
257
|
+
} as const
|
|
258
|
+
|
|
259
|
+
export type HardwareErrorCodeType = typeof HardwareErrorCode[keyof typeof HardwareErrorCode]
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Hardware wallet error
|
|
263
|
+
*/
|
|
264
|
+
export class HardwareWalletError extends Error {
|
|
265
|
+
readonly code: HardwareErrorCodeType
|
|
266
|
+
readonly device?: HardwareWalletType
|
|
267
|
+
readonly details?: unknown
|
|
268
|
+
|
|
269
|
+
constructor(
|
|
270
|
+
message: string,
|
|
271
|
+
code: HardwareErrorCodeType,
|
|
272
|
+
device?: HardwareWalletType,
|
|
273
|
+
details?: unknown
|
|
274
|
+
) {
|
|
275
|
+
super(message)
|
|
276
|
+
this.name = 'HardwareWalletError'
|
|
277
|
+
this.code = code
|
|
278
|
+
this.device = device
|
|
279
|
+
this.details = details
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// ─── Utilities ──────────────────────────────────────────────────────────────────
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Check if browser supports WebUSB
|
|
287
|
+
*/
|
|
288
|
+
export function supportsWebUSB(): boolean {
|
|
289
|
+
return typeof navigator !== 'undefined' && 'usb' in navigator
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Check if browser supports WebHID
|
|
294
|
+
*/
|
|
295
|
+
export function supportsWebHID(): boolean {
|
|
296
|
+
return typeof navigator !== 'undefined' && 'hid' in navigator
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Check if browser supports Web Bluetooth
|
|
301
|
+
*/
|
|
302
|
+
export function supportsWebBluetooth(): boolean {
|
|
303
|
+
return typeof navigator !== 'undefined' && 'bluetooth' in navigator
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Get available transport types
|
|
308
|
+
*/
|
|
309
|
+
export function getAvailableTransports(): TransportType[] {
|
|
310
|
+
const transports: TransportType[] = []
|
|
311
|
+
|
|
312
|
+
if (supportsWebUSB()) transports.push('webusb')
|
|
313
|
+
if (supportsWebHID()) transports.push('webhid')
|
|
314
|
+
if (supportsWebBluetooth()) transports.push('bluetooth')
|
|
315
|
+
|
|
316
|
+
return transports
|
|
317
|
+
}
|
package/src/wallet/index.ts
CHANGED
|
@@ -84,6 +84,46 @@ export type {
|
|
|
84
84
|
MockEthereumAdapterConfig,
|
|
85
85
|
} from './ethereum'
|
|
86
86
|
|
|
87
|
+
// Hardware wallet adapters
|
|
88
|
+
export {
|
|
89
|
+
// Types
|
|
90
|
+
type HardwareWalletType,
|
|
91
|
+
type LedgerModel,
|
|
92
|
+
type TrezorModel,
|
|
93
|
+
type HardwareConnectionStatus,
|
|
94
|
+
type TransportType,
|
|
95
|
+
type HardwareDeviceInfo,
|
|
96
|
+
type HardwareWalletConfig,
|
|
97
|
+
type LedgerConfig,
|
|
98
|
+
type TrezorConfig,
|
|
99
|
+
type HardwareSignRequest,
|
|
100
|
+
type HardwareEthereumTx,
|
|
101
|
+
type HardwareSignature,
|
|
102
|
+
type HardwareAccount,
|
|
103
|
+
type HardwareTransport,
|
|
104
|
+
type HardwareErrorCodeType,
|
|
105
|
+
type MockHardwareConfig,
|
|
106
|
+
HardwareErrorCode,
|
|
107
|
+
HardwareWalletError,
|
|
108
|
+
DerivationPath,
|
|
109
|
+
getDerivationPath,
|
|
110
|
+
supportsWebUSB,
|
|
111
|
+
supportsWebHID,
|
|
112
|
+
supportsWebBluetooth,
|
|
113
|
+
getAvailableTransports,
|
|
114
|
+
// Ledger
|
|
115
|
+
LedgerWalletAdapter,
|
|
116
|
+
createLedgerAdapter,
|
|
117
|
+
// Trezor
|
|
118
|
+
TrezorWalletAdapter,
|
|
119
|
+
createTrezorAdapter,
|
|
120
|
+
// Mocks
|
|
121
|
+
MockLedgerAdapter,
|
|
122
|
+
MockTrezorAdapter,
|
|
123
|
+
createMockLedgerAdapter,
|
|
124
|
+
createMockTrezorAdapter,
|
|
125
|
+
} from './hardware'
|
|
126
|
+
|
|
87
127
|
// Re-export types from types package for convenience
|
|
88
128
|
export type {
|
|
89
129
|
// Core types
|
|
@@ -369,11 +369,14 @@ export class ZcashShieldedService {
|
|
|
369
369
|
)
|
|
370
370
|
}
|
|
371
371
|
|
|
372
|
+
// Get fee from operation result, fall back to params.fee or estimate
|
|
373
|
+
const fee = operation.result.fee ?? params.fee ?? this.estimateFee(1)
|
|
374
|
+
|
|
372
375
|
return {
|
|
373
376
|
txid: operation.result.txid,
|
|
374
377
|
operationId,
|
|
375
378
|
amount: params.amount,
|
|
376
|
-
fee
|
|
379
|
+
fee,
|
|
377
380
|
to: params.to,
|
|
378
381
|
from: fromAddress,
|
|
379
382
|
timestamp: Math.floor(Date.now() / 1000),
|
|
@@ -561,6 +564,61 @@ export class ZcashShieldedService {
|
|
|
561
564
|
return this.client.isTestnet
|
|
562
565
|
}
|
|
563
566
|
|
|
567
|
+
// ─── Fee Estimation ──────────────────────────────────────────────────────────
|
|
568
|
+
|
|
569
|
+
/**
|
|
570
|
+
* ZIP-317 fee constants (in ZEC)
|
|
571
|
+
* @see https://zips.z.cash/zip-0317
|
|
572
|
+
*/
|
|
573
|
+
private static readonly ZIP317_MARGINAL_FEE = 0.00005 // 5000 zatoshis per logical action
|
|
574
|
+
private static readonly ZIP317_GRACE_ACTIONS = 2 // First 2 actions are free
|
|
575
|
+
private static readonly ZIP317_P2PKH_STANDARD_INPUT_SIZE = 150
|
|
576
|
+
private static readonly ZIP317_P2PKH_STANDARD_OUTPUT_SIZE = 34
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
* Estimate transaction fee based on ZIP-317 conventional fee
|
|
580
|
+
*
|
|
581
|
+
* The ZIP-317 fee is calculated as:
|
|
582
|
+
* fee = marginal_fee * max(grace_actions, logical_actions)
|
|
583
|
+
*
|
|
584
|
+
* For shielded transactions:
|
|
585
|
+
* - Each Sapling spend = 1 logical action
|
|
586
|
+
* - Each Sapling output = 1 logical action
|
|
587
|
+
* - Each Orchard action = 1 logical action (covers both spend and output)
|
|
588
|
+
*
|
|
589
|
+
* @param recipients - Number of recipients (outputs)
|
|
590
|
+
* @param inputs - Estimated number of input notes (default: 1)
|
|
591
|
+
* @returns Estimated fee in ZEC
|
|
592
|
+
*
|
|
593
|
+
* @example
|
|
594
|
+
* ```typescript
|
|
595
|
+
* // Estimate fee for 1 recipient
|
|
596
|
+
* const fee = service.estimateFee(1)
|
|
597
|
+
*
|
|
598
|
+
* // Estimate fee for 3 recipients with 2 input notes
|
|
599
|
+
* const fee = service.estimateFee(3, 2)
|
|
600
|
+
* ```
|
|
601
|
+
*/
|
|
602
|
+
estimateFee(recipients: number = 1, inputs: number = 1): number {
|
|
603
|
+
// For shielded transactions, logical actions = inputs + outputs
|
|
604
|
+
// Plus 1 for change output in most cases
|
|
605
|
+
const logicalActions = inputs + recipients + 1
|
|
606
|
+
|
|
607
|
+
// ZIP-317: fee = marginal_fee * max(grace_actions, logical_actions)
|
|
608
|
+
const billableActions = Math.max(ZcashShieldedService.ZIP317_GRACE_ACTIONS, logicalActions)
|
|
609
|
+
|
|
610
|
+
return billableActions * ZcashShieldedService.ZIP317_MARGINAL_FEE
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
/**
|
|
614
|
+
* Get minimum fee for a shielded transaction
|
|
615
|
+
*
|
|
616
|
+
* @returns Minimum fee in ZEC (ZIP-317 with grace actions)
|
|
617
|
+
*/
|
|
618
|
+
getMinimumFee(): number {
|
|
619
|
+
return ZcashShieldedService.ZIP317_GRACE_ACTIONS * ZcashShieldedService.ZIP317_MARGINAL_FEE
|
|
620
|
+
}
|
|
621
|
+
|
|
564
622
|
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
565
623
|
|
|
566
624
|
/**
|