@sip-protocol/sdk 0.1.8 → 0.2.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/LICENSE +21 -0
- package/dist/browser.d.mts +2 -0
- package/dist/browser.d.ts +2 -0
- package/dist/browser.js +12925 -0
- package/dist/browser.mjs +432 -0
- package/dist/chunk-O4Y2ZUDL.mjs +12721 -0
- package/dist/index.d.mts +800 -91
- package/dist/index.d.ts +800 -91
- package/dist/index.js +1855 -376
- package/dist/index.mjs +262 -11111
- package/package.json +23 -14
- package/src/adapters/near-intents.ts +139 -22
- package/src/browser.ts +33 -0
- package/src/commitment.ts +4 -4
- package/src/index.ts +71 -0
- package/src/oracle/index.ts +12 -0
- package/src/oracle/serialization.ts +237 -0
- package/src/oracle/types.ts +257 -0
- package/src/oracle/verification.ts +257 -0
- package/src/proofs/browser-utils.ts +141 -0
- package/src/proofs/browser.ts +884 -0
- package/src/proofs/index.ts +14 -0
- package/src/stealth.ts +868 -12
- package/src/validation.ts +7 -0
package/dist/index.js
CHANGED
|
@@ -30,9 +30,14 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
+
ATTESTATION_VERSION: () => ATTESTATION_VERSION,
|
|
33
34
|
BaseWalletAdapter: () => BaseWalletAdapter,
|
|
35
|
+
BrowserNoirProvider: () => BrowserNoirProvider,
|
|
36
|
+
CHAIN_NUMERIC_IDS: () => CHAIN_NUMERIC_IDS,
|
|
34
37
|
ComplianceManager: () => ComplianceManager,
|
|
35
38
|
CryptoError: () => CryptoError,
|
|
39
|
+
DEFAULT_THRESHOLD: () => DEFAULT_THRESHOLD,
|
|
40
|
+
DEFAULT_TOTAL_ORACLES: () => DEFAULT_TOTAL_ORACLES,
|
|
36
41
|
DerivationPath: () => DerivationPath,
|
|
37
42
|
EncryptionNotImplementedError: () => EncryptionNotImplementedError,
|
|
38
43
|
ErrorCode: () => ErrorCode,
|
|
@@ -42,7 +47,7 @@ __export(index_exports, {
|
|
|
42
47
|
HardwareWalletError: () => HardwareWalletError,
|
|
43
48
|
IntentBuilder: () => IntentBuilder,
|
|
44
49
|
IntentError: () => IntentError,
|
|
45
|
-
IntentStatus: () =>
|
|
50
|
+
IntentStatus: () => import_types33.IntentStatus,
|
|
46
51
|
LedgerWalletAdapter: () => LedgerWalletAdapter,
|
|
47
52
|
MockEthereumAdapter: () => MockEthereumAdapter,
|
|
48
53
|
MockLedgerAdapter: () => MockLedgerAdapter,
|
|
@@ -51,26 +56,27 @@ __export(index_exports, {
|
|
|
51
56
|
MockSolver: () => MockSolver,
|
|
52
57
|
MockTrezorAdapter: () => MockTrezorAdapter,
|
|
53
58
|
MockWalletAdapter: () => MockWalletAdapter,
|
|
54
|
-
NATIVE_TOKENS: () =>
|
|
59
|
+
NATIVE_TOKENS: () => import_types33.NATIVE_TOKENS,
|
|
55
60
|
NEARIntentsAdapter: () => NEARIntentsAdapter,
|
|
56
61
|
NetworkError: () => NetworkError,
|
|
57
62
|
NoirProofProvider: () => NoirProofProvider,
|
|
63
|
+
ORACLE_DOMAIN: () => ORACLE_DOMAIN,
|
|
58
64
|
OneClickClient: () => OneClickClient,
|
|
59
|
-
OneClickDepositMode: () =>
|
|
60
|
-
OneClickErrorCode: () =>
|
|
61
|
-
OneClickSwapStatus: () =>
|
|
62
|
-
OneClickSwapType: () =>
|
|
65
|
+
OneClickDepositMode: () => import_types37.OneClickDepositMode,
|
|
66
|
+
OneClickErrorCode: () => import_types37.OneClickErrorCode,
|
|
67
|
+
OneClickSwapStatus: () => import_types37.OneClickSwapStatus,
|
|
68
|
+
OneClickSwapType: () => import_types37.OneClickSwapType,
|
|
63
69
|
PaymentBuilder: () => PaymentBuilder,
|
|
64
|
-
PaymentStatus: () =>
|
|
65
|
-
PrivacyLevel: () =>
|
|
70
|
+
PaymentStatus: () => import_types34.PaymentStatus,
|
|
71
|
+
PrivacyLevel: () => import_types33.PrivacyLevel,
|
|
66
72
|
ProofError: () => ProofError,
|
|
67
73
|
ProofGenerationError: () => ProofGenerationError,
|
|
68
74
|
ProofNotImplementedError: () => ProofNotImplementedError,
|
|
69
|
-
ProposalStatus: () =>
|
|
70
|
-
ReportStatus: () =>
|
|
75
|
+
ProposalStatus: () => import_types35.ProposalStatus,
|
|
76
|
+
ReportStatus: () => import_types36.ReportStatus,
|
|
71
77
|
SIP: () => SIP,
|
|
72
78
|
SIPError: () => SIPError,
|
|
73
|
-
SIP_VERSION: () =>
|
|
79
|
+
SIP_VERSION: () => import_types33.SIP_VERSION,
|
|
74
80
|
STABLECOIN_ADDRESSES: () => STABLECOIN_ADDRESSES,
|
|
75
81
|
STABLECOIN_DECIMALS: () => STABLECOIN_DECIMALS,
|
|
76
82
|
STABLECOIN_INFO: () => STABLECOIN_INFO,
|
|
@@ -79,18 +85,23 @@ __export(index_exports, {
|
|
|
79
85
|
TrezorWalletAdapter: () => TrezorWalletAdapter,
|
|
80
86
|
ValidationError: () => ValidationError,
|
|
81
87
|
WalletError: () => WalletError,
|
|
82
|
-
WalletErrorCode: () =>
|
|
83
|
-
ZcashErrorCode: () =>
|
|
88
|
+
WalletErrorCode: () => import_types32.WalletErrorCode,
|
|
89
|
+
ZcashErrorCode: () => import_types38.ZcashErrorCode,
|
|
84
90
|
ZcashRPCClient: () => ZcashRPCClient,
|
|
85
91
|
ZcashRPCError: () => ZcashRPCError,
|
|
86
92
|
ZcashShieldedService: () => ZcashShieldedService,
|
|
87
93
|
addBlindings: () => addBlindings,
|
|
88
94
|
addCommitments: () => addCommitments,
|
|
95
|
+
addOracle: () => addOracle,
|
|
89
96
|
attachProofs: () => attachProofs,
|
|
90
97
|
base58ToHex: () => base58ToHex,
|
|
98
|
+
browserBytesToHex: () => bytesToHex7,
|
|
99
|
+
browserHexToBytes: () => hexToBytes5,
|
|
100
|
+
checkEd25519StealthAddress: () => checkEd25519StealthAddress,
|
|
91
101
|
checkStealthAddress: () => checkStealthAddress,
|
|
92
102
|
commit: () => commit,
|
|
93
103
|
commitZero: () => commitZero,
|
|
104
|
+
computeAttestationHash: () => computeAttestationHash,
|
|
94
105
|
createCommitment: () => createCommitment,
|
|
95
106
|
createEthereumAdapter: () => createEthereumAdapter,
|
|
96
107
|
createLedgerAdapter: () => createLedgerAdapter,
|
|
@@ -103,6 +114,7 @@ __export(index_exports, {
|
|
|
103
114
|
createMockSolver: () => createMockSolver,
|
|
104
115
|
createMockTrezorAdapter: () => createMockTrezorAdapter,
|
|
105
116
|
createNEARIntentsAdapter: () => createNEARIntentsAdapter,
|
|
117
|
+
createOracleRegistry: () => createOracleRegistry,
|
|
106
118
|
createProductionSIP: () => createProductionSIP,
|
|
107
119
|
createSIP: () => createSIP,
|
|
108
120
|
createShieldedIntent: () => createShieldedIntent,
|
|
@@ -115,12 +127,17 @@ __export(index_exports, {
|
|
|
115
127
|
decodeStealthMetaAddress: () => decodeStealthMetaAddress,
|
|
116
128
|
decryptMemo: () => decryptMemo,
|
|
117
129
|
decryptWithViewing: () => decryptWithViewing,
|
|
130
|
+
deriveEd25519StealthPrivateKey: () => deriveEd25519StealthPrivateKey,
|
|
131
|
+
deriveOracleId: () => deriveOracleId,
|
|
118
132
|
deriveStealthPrivateKey: () => deriveStealthPrivateKey,
|
|
119
133
|
deriveViewingKey: () => deriveViewingKey,
|
|
134
|
+
deserializeAttestationMessage: () => deserializeAttestationMessage,
|
|
120
135
|
deserializeIntent: () => deserializeIntent,
|
|
121
136
|
deserializePayment: () => deserializePayment,
|
|
122
137
|
detectEthereumWallets: () => detectEthereumWallets,
|
|
123
138
|
detectSolanaWallets: () => detectSolanaWallets,
|
|
139
|
+
ed25519PublicKeyToNearAddress: () => ed25519PublicKeyToNearAddress,
|
|
140
|
+
ed25519PublicKeyToSolanaAddress: () => ed25519PublicKeyToSolanaAddress,
|
|
124
141
|
encodeStealthMetaAddress: () => encodeStealthMetaAddress,
|
|
125
142
|
encryptForViewing: () => encryptForViewing,
|
|
126
143
|
featureNotSupportedError: () => featureNotSupportedError,
|
|
@@ -128,13 +145,19 @@ __export(index_exports, {
|
|
|
128
145
|
fromHex: () => fromHex,
|
|
129
146
|
fromStablecoinUnits: () => fromStablecoinUnits,
|
|
130
147
|
generateBlinding: () => generateBlinding,
|
|
148
|
+
generateEd25519StealthAddress: () => generateEd25519StealthAddress,
|
|
149
|
+
generateEd25519StealthMetaAddress: () => generateEd25519StealthMetaAddress,
|
|
131
150
|
generateIntentId: () => generateIntentId,
|
|
132
151
|
generateRandomBytes: () => generateRandomBytes,
|
|
133
152
|
generateStealthAddress: () => generateStealthAddress,
|
|
134
153
|
generateStealthMetaAddress: () => generateStealthMetaAddress,
|
|
135
154
|
generateViewingKey: () => generateViewingKey,
|
|
155
|
+
getActiveOracles: () => getActiveOracles,
|
|
136
156
|
getAvailableTransports: () => getAvailableTransports,
|
|
157
|
+
getBrowserInfo: () => getBrowserInfo,
|
|
158
|
+
getChainNumericId: () => getChainNumericId,
|
|
137
159
|
getChainsForStablecoin: () => getChainsForStablecoin,
|
|
160
|
+
getCurveForChain: () => getCurveForChain,
|
|
138
161
|
getDefaultRpcEndpoint: () => getDefaultRpcEndpoint,
|
|
139
162
|
getDerivationPath: () => getDerivationPath,
|
|
140
163
|
getErrorMessage: () => getErrorMessage,
|
|
@@ -151,14 +174,17 @@ __export(index_exports, {
|
|
|
151
174
|
getStablecoinsForChain: () => getStablecoinsForChain,
|
|
152
175
|
getSupportedStablecoins: () => getSupportedStablecoins,
|
|
153
176
|
getTimeRemaining: () => getTimeRemaining,
|
|
177
|
+
hasEnoughOracles: () => hasEnoughOracles,
|
|
154
178
|
hasErrorCode: () => hasErrorCode,
|
|
155
179
|
hasRequiredProofs: () => hasRequiredProofs,
|
|
156
180
|
hash: () => hash,
|
|
157
181
|
hexToNumber: () => hexToNumber,
|
|
182
|
+
isBrowser: () => isBrowser,
|
|
183
|
+
isEd25519Chain: () => isEd25519Chain,
|
|
158
184
|
isExpired: () => isExpired,
|
|
159
185
|
isNonNegativeAmount: () => isNonNegativeAmount,
|
|
160
186
|
isPaymentExpired: () => isPaymentExpired,
|
|
161
|
-
isPrivate: () =>
|
|
187
|
+
isPrivate: () => import_types33.isPrivate,
|
|
162
188
|
isPrivateWalletAdapter: () => isPrivateWalletAdapter,
|
|
163
189
|
isSIPError: () => isSIPError,
|
|
164
190
|
isStablecoin: () => isStablecoin,
|
|
@@ -166,40 +192,54 @@ __export(index_exports, {
|
|
|
166
192
|
isValidAmount: () => isValidAmount,
|
|
167
193
|
isValidChainId: () => isValidChainId,
|
|
168
194
|
isValidCompressedPublicKey: () => isValidCompressedPublicKey,
|
|
195
|
+
isValidEd25519PublicKey: () => isValidEd25519PublicKey,
|
|
169
196
|
isValidHex: () => isValidHex,
|
|
170
197
|
isValidHexLength: () => isValidHexLength,
|
|
198
|
+
isValidNearAccountId: () => isValidNearAccountId,
|
|
199
|
+
isValidNearImplicitAddress: () => isValidNearImplicitAddress,
|
|
171
200
|
isValidPrivacyLevel: () => isValidPrivacyLevel,
|
|
172
201
|
isValidPrivateKey: () => isValidPrivateKey,
|
|
173
202
|
isValidScalar: () => isValidScalar,
|
|
174
203
|
isValidSlippage: () => isValidSlippage,
|
|
204
|
+
isValidSolanaAddress: () => isValidSolanaAddress,
|
|
175
205
|
isValidStealthMetaAddress: () => isValidStealthMetaAddress,
|
|
206
|
+
nearAddressToEd25519PublicKey: () => nearAddressToEd25519PublicKey,
|
|
176
207
|
normalizeAddress: () => normalizeAddress,
|
|
177
208
|
notConnectedError: () => notConnectedError,
|
|
178
209
|
publicKeyToEthAddress: () => publicKeyToEthAddress,
|
|
179
210
|
registerWallet: () => registerWallet,
|
|
211
|
+
removeOracle: () => removeOracle,
|
|
180
212
|
secureWipe: () => secureWipe,
|
|
181
213
|
secureWipeAll: () => secureWipeAll,
|
|
214
|
+
serializeAttestationMessage: () => serializeAttestationMessage,
|
|
182
215
|
serializeIntent: () => serializeIntent,
|
|
183
216
|
serializePayment: () => serializePayment,
|
|
217
|
+
signAttestationMessage: () => signAttestationMessage,
|
|
218
|
+
solanaAddressToEd25519PublicKey: () => solanaAddressToEd25519PublicKey,
|
|
184
219
|
solanaPublicKeyToHex: () => solanaPublicKeyToHex,
|
|
185
220
|
subtractBlindings: () => subtractBlindings,
|
|
186
221
|
subtractCommitments: () => subtractCommitments,
|
|
187
|
-
|
|
222
|
+
supportsSharedArrayBuffer: () => supportsSharedArrayBuffer,
|
|
223
|
+
supportsViewingKey: () => import_types33.supportsViewingKey,
|
|
188
224
|
supportsWebBluetooth: () => supportsWebBluetooth,
|
|
189
225
|
supportsWebHID: () => supportsWebHID,
|
|
190
226
|
supportsWebUSB: () => supportsWebUSB,
|
|
227
|
+
supportsWebWorkers: () => supportsWebWorkers,
|
|
191
228
|
toHex: () => toHex,
|
|
192
229
|
toStablecoinUnits: () => toStablecoinUnits,
|
|
193
230
|
trackIntent: () => trackIntent,
|
|
194
231
|
trackPayment: () => trackPayment,
|
|
232
|
+
updateOracleStatus: () => updateOracleStatus,
|
|
195
233
|
validateAsset: () => validateAsset,
|
|
196
234
|
validateCreateIntentParams: () => validateCreateIntentParams,
|
|
197
235
|
validateIntentInput: () => validateIntentInput,
|
|
198
236
|
validateIntentOutput: () => validateIntentOutput,
|
|
199
237
|
validateScalar: () => validateScalar,
|
|
200
238
|
validateViewingKey: () => validateViewingKey,
|
|
239
|
+
verifyAttestation: () => verifyAttestation,
|
|
201
240
|
verifyCommitment: () => verifyCommitment,
|
|
202
241
|
verifyOpening: () => verifyOpening,
|
|
242
|
+
verifyOracleSignature: () => verifyOracleSignature,
|
|
203
243
|
walletRegistry: () => walletRegistry,
|
|
204
244
|
withSecureBuffer: () => withSecureBuffer,
|
|
205
245
|
withSecureBufferSync: () => withSecureBufferSync,
|
|
@@ -410,7 +450,9 @@ var import_types = require("@sip-protocol/types");
|
|
|
410
450
|
|
|
411
451
|
// src/stealth.ts
|
|
412
452
|
var import_secp256k1 = require("@noble/curves/secp256k1");
|
|
453
|
+
var import_ed25519 = require("@noble/curves/ed25519");
|
|
413
454
|
var import_sha256 = require("@noble/hashes/sha256");
|
|
455
|
+
var import_sha512 = require("@noble/hashes/sha512");
|
|
414
456
|
var import_sha3 = require("@noble/hashes/sha3");
|
|
415
457
|
var import_utils2 = require("@noble/hashes/utils");
|
|
416
458
|
|
|
@@ -463,6 +505,9 @@ function isValidCompressedPublicKey(key) {
|
|
|
463
505
|
const prefix = key.slice(2, 4);
|
|
464
506
|
return prefix === "02" || prefix === "03";
|
|
465
507
|
}
|
|
508
|
+
function isValidEd25519PublicKey(key) {
|
|
509
|
+
return isValidHexLength(key, 32);
|
|
510
|
+
}
|
|
466
511
|
function isValidPrivateKey(key) {
|
|
467
512
|
return isValidHexLength(key, 32);
|
|
468
513
|
}
|
|
@@ -837,17 +882,33 @@ function decodeStealthMetaAddress(encoded) {
|
|
|
837
882
|
"encoded.chain"
|
|
838
883
|
);
|
|
839
884
|
}
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
885
|
+
const chainId = chain;
|
|
886
|
+
if (isEd25519Chain(chainId)) {
|
|
887
|
+
if (!isValidEd25519PublicKey(spendingKey)) {
|
|
888
|
+
throw new ValidationError(
|
|
889
|
+
"spendingKey must be a valid 32-byte ed25519 public key",
|
|
890
|
+
"encoded.spendingKey"
|
|
891
|
+
);
|
|
892
|
+
}
|
|
893
|
+
if (!isValidEd25519PublicKey(viewingKey)) {
|
|
894
|
+
throw new ValidationError(
|
|
895
|
+
"viewingKey must be a valid 32-byte ed25519 public key",
|
|
896
|
+
"encoded.viewingKey"
|
|
897
|
+
);
|
|
898
|
+
}
|
|
899
|
+
} else {
|
|
900
|
+
if (!isValidCompressedPublicKey(spendingKey)) {
|
|
901
|
+
throw new ValidationError(
|
|
902
|
+
"spendingKey must be a valid compressed secp256k1 public key",
|
|
903
|
+
"encoded.spendingKey"
|
|
904
|
+
);
|
|
905
|
+
}
|
|
906
|
+
if (!isValidCompressedPublicKey(viewingKey)) {
|
|
907
|
+
throw new ValidationError(
|
|
908
|
+
"viewingKey must be a valid compressed secp256k1 public key",
|
|
909
|
+
"encoded.viewingKey"
|
|
910
|
+
);
|
|
911
|
+
}
|
|
851
912
|
}
|
|
852
913
|
return {
|
|
853
914
|
chain,
|
|
@@ -903,6 +964,396 @@ function toChecksumAddress(address) {
|
|
|
903
964
|
}
|
|
904
965
|
return checksummed;
|
|
905
966
|
}
|
|
967
|
+
var ED25519_ORDER = 2n ** 252n + 27742317777372353535851937790883648493n;
|
|
968
|
+
var ED25519_CHAINS = ["solana", "near"];
|
|
969
|
+
function isEd25519Chain(chain) {
|
|
970
|
+
return ED25519_CHAINS.includes(chain);
|
|
971
|
+
}
|
|
972
|
+
function getCurveForChain(chain) {
|
|
973
|
+
return isEd25519Chain(chain) ? "ed25519" : "secp256k1";
|
|
974
|
+
}
|
|
975
|
+
function validateEd25519StealthMetaAddress(metaAddress, field = "recipientMetaAddress") {
|
|
976
|
+
if (!metaAddress || typeof metaAddress !== "object") {
|
|
977
|
+
throw new ValidationError("must be an object", field);
|
|
978
|
+
}
|
|
979
|
+
if (!isValidChainId(metaAddress.chain)) {
|
|
980
|
+
throw new ValidationError(
|
|
981
|
+
`invalid chain '${metaAddress.chain}'`,
|
|
982
|
+
`${field}.chain`
|
|
983
|
+
);
|
|
984
|
+
}
|
|
985
|
+
if (!isEd25519Chain(metaAddress.chain)) {
|
|
986
|
+
throw new ValidationError(
|
|
987
|
+
`chain '${metaAddress.chain}' does not use ed25519, use secp256k1 functions instead`,
|
|
988
|
+
`${field}.chain`
|
|
989
|
+
);
|
|
990
|
+
}
|
|
991
|
+
if (!isValidEd25519PublicKey(metaAddress.spendingKey)) {
|
|
992
|
+
throw new ValidationError(
|
|
993
|
+
"spendingKey must be a valid ed25519 public key (32 bytes)",
|
|
994
|
+
`${field}.spendingKey`
|
|
995
|
+
);
|
|
996
|
+
}
|
|
997
|
+
if (!isValidEd25519PublicKey(metaAddress.viewingKey)) {
|
|
998
|
+
throw new ValidationError(
|
|
999
|
+
"viewingKey must be a valid ed25519 public key (32 bytes)",
|
|
1000
|
+
`${field}.viewingKey`
|
|
1001
|
+
);
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
function validateEd25519StealthAddress(stealthAddress, field = "stealthAddress") {
|
|
1005
|
+
if (!stealthAddress || typeof stealthAddress !== "object") {
|
|
1006
|
+
throw new ValidationError("must be an object", field);
|
|
1007
|
+
}
|
|
1008
|
+
if (!isValidEd25519PublicKey(stealthAddress.address)) {
|
|
1009
|
+
throw new ValidationError(
|
|
1010
|
+
"address must be a valid ed25519 public key (32 bytes)",
|
|
1011
|
+
`${field}.address`
|
|
1012
|
+
);
|
|
1013
|
+
}
|
|
1014
|
+
if (!isValidEd25519PublicKey(stealthAddress.ephemeralPublicKey)) {
|
|
1015
|
+
throw new ValidationError(
|
|
1016
|
+
"ephemeralPublicKey must be a valid ed25519 public key (32 bytes)",
|
|
1017
|
+
`${field}.ephemeralPublicKey`
|
|
1018
|
+
);
|
|
1019
|
+
}
|
|
1020
|
+
if (typeof stealthAddress.viewTag !== "number" || !Number.isInteger(stealthAddress.viewTag) || stealthAddress.viewTag < 0 || stealthAddress.viewTag > 255) {
|
|
1021
|
+
throw new ValidationError(
|
|
1022
|
+
"viewTag must be an integer between 0 and 255",
|
|
1023
|
+
`${field}.viewTag`
|
|
1024
|
+
);
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
function getEd25519Scalar(privateKey) {
|
|
1028
|
+
const hash2 = (0, import_sha512.sha512)(privateKey);
|
|
1029
|
+
const scalar = hash2.slice(0, 32);
|
|
1030
|
+
scalar[0] &= 248;
|
|
1031
|
+
scalar[31] &= 127;
|
|
1032
|
+
scalar[31] |= 64;
|
|
1033
|
+
return bytesToBigIntLE(scalar);
|
|
1034
|
+
}
|
|
1035
|
+
function bytesToBigIntLE(bytes) {
|
|
1036
|
+
let result = 0n;
|
|
1037
|
+
for (let i = bytes.length - 1; i >= 0; i--) {
|
|
1038
|
+
result = (result << 8n) + BigInt(bytes[i]);
|
|
1039
|
+
}
|
|
1040
|
+
return result;
|
|
1041
|
+
}
|
|
1042
|
+
function bigIntToBytesLE(value, length) {
|
|
1043
|
+
const bytes = new Uint8Array(length);
|
|
1044
|
+
for (let i = 0; i < length; i++) {
|
|
1045
|
+
bytes[i] = Number(value & 0xffn);
|
|
1046
|
+
value >>= 8n;
|
|
1047
|
+
}
|
|
1048
|
+
return bytes;
|
|
1049
|
+
}
|
|
1050
|
+
function generateEd25519StealthMetaAddress(chain, label) {
|
|
1051
|
+
if (!isValidChainId(chain)) {
|
|
1052
|
+
throw new ValidationError(
|
|
1053
|
+
`invalid chain '${chain}', must be one of: solana, ethereum, near, zcash, polygon, arbitrum, optimism, base`,
|
|
1054
|
+
"chain"
|
|
1055
|
+
);
|
|
1056
|
+
}
|
|
1057
|
+
if (!isEd25519Chain(chain)) {
|
|
1058
|
+
throw new ValidationError(
|
|
1059
|
+
`chain '${chain}' does not use ed25519, use generateStealthMetaAddress() for secp256k1 chains`,
|
|
1060
|
+
"chain"
|
|
1061
|
+
);
|
|
1062
|
+
}
|
|
1063
|
+
const spendingPrivateKey = (0, import_utils2.randomBytes)(32);
|
|
1064
|
+
const viewingPrivateKey = (0, import_utils2.randomBytes)(32);
|
|
1065
|
+
try {
|
|
1066
|
+
const spendingKey = import_ed25519.ed25519.getPublicKey(spendingPrivateKey);
|
|
1067
|
+
const viewingKey = import_ed25519.ed25519.getPublicKey(viewingPrivateKey);
|
|
1068
|
+
const result = {
|
|
1069
|
+
metaAddress: {
|
|
1070
|
+
spendingKey: `0x${(0, import_utils2.bytesToHex)(spendingKey)}`,
|
|
1071
|
+
viewingKey: `0x${(0, import_utils2.bytesToHex)(viewingKey)}`,
|
|
1072
|
+
chain,
|
|
1073
|
+
label
|
|
1074
|
+
},
|
|
1075
|
+
spendingPrivateKey: `0x${(0, import_utils2.bytesToHex)(spendingPrivateKey)}`,
|
|
1076
|
+
viewingPrivateKey: `0x${(0, import_utils2.bytesToHex)(viewingPrivateKey)}`
|
|
1077
|
+
};
|
|
1078
|
+
return result;
|
|
1079
|
+
} finally {
|
|
1080
|
+
secureWipeAll(spendingPrivateKey, viewingPrivateKey);
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
function generateEd25519StealthAddress(recipientMetaAddress) {
|
|
1084
|
+
validateEd25519StealthMetaAddress(recipientMetaAddress);
|
|
1085
|
+
const ephemeralPrivateKey = (0, import_utils2.randomBytes)(32);
|
|
1086
|
+
try {
|
|
1087
|
+
const ephemeralPublicKey = import_ed25519.ed25519.getPublicKey(ephemeralPrivateKey);
|
|
1088
|
+
const spendingKeyBytes = (0, import_utils2.hexToBytes)(recipientMetaAddress.spendingKey.slice(2));
|
|
1089
|
+
const viewingKeyBytes = (0, import_utils2.hexToBytes)(recipientMetaAddress.viewingKey.slice(2));
|
|
1090
|
+
const rawEphemeralScalar = getEd25519Scalar(ephemeralPrivateKey);
|
|
1091
|
+
const ephemeralScalar = rawEphemeralScalar % ED25519_ORDER;
|
|
1092
|
+
if (ephemeralScalar === 0n) {
|
|
1093
|
+
throw new Error("CRITICAL: Zero ephemeral scalar after reduction - investigate RNG");
|
|
1094
|
+
}
|
|
1095
|
+
const spendingPoint = import_ed25519.ed25519.ExtendedPoint.fromHex(spendingKeyBytes);
|
|
1096
|
+
const sharedSecretPoint = spendingPoint.multiply(ephemeralScalar);
|
|
1097
|
+
const sharedSecretHash = (0, import_sha256.sha256)(sharedSecretPoint.toRawBytes());
|
|
1098
|
+
const hashScalar = bytesToBigInt(sharedSecretHash) % ED25519_ORDER;
|
|
1099
|
+
if (hashScalar === 0n) {
|
|
1100
|
+
throw new Error("CRITICAL: Zero hash scalar after reduction - investigate hash computation");
|
|
1101
|
+
}
|
|
1102
|
+
const hashTimesG = import_ed25519.ed25519.ExtendedPoint.BASE.multiply(hashScalar);
|
|
1103
|
+
const viewingPoint = import_ed25519.ed25519.ExtendedPoint.fromHex(viewingKeyBytes);
|
|
1104
|
+
const stealthPoint = viewingPoint.add(hashTimesG);
|
|
1105
|
+
const stealthAddressBytes = stealthPoint.toRawBytes();
|
|
1106
|
+
const viewTag = sharedSecretHash[0];
|
|
1107
|
+
return {
|
|
1108
|
+
stealthAddress: {
|
|
1109
|
+
address: `0x${(0, import_utils2.bytesToHex)(stealthAddressBytes)}`,
|
|
1110
|
+
ephemeralPublicKey: `0x${(0, import_utils2.bytesToHex)(ephemeralPublicKey)}`,
|
|
1111
|
+
viewTag
|
|
1112
|
+
},
|
|
1113
|
+
sharedSecret: `0x${(0, import_utils2.bytesToHex)(sharedSecretHash)}`
|
|
1114
|
+
};
|
|
1115
|
+
} finally {
|
|
1116
|
+
secureWipe(ephemeralPrivateKey);
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
function deriveEd25519StealthPrivateKey(stealthAddress, spendingPrivateKey, viewingPrivateKey) {
|
|
1120
|
+
validateEd25519StealthAddress(stealthAddress);
|
|
1121
|
+
if (!isValidPrivateKey(spendingPrivateKey)) {
|
|
1122
|
+
throw new ValidationError(
|
|
1123
|
+
"must be a valid 32-byte hex string",
|
|
1124
|
+
"spendingPrivateKey"
|
|
1125
|
+
);
|
|
1126
|
+
}
|
|
1127
|
+
if (!isValidPrivateKey(viewingPrivateKey)) {
|
|
1128
|
+
throw new ValidationError(
|
|
1129
|
+
"must be a valid 32-byte hex string",
|
|
1130
|
+
"viewingPrivateKey"
|
|
1131
|
+
);
|
|
1132
|
+
}
|
|
1133
|
+
const spendingPrivBytes = (0, import_utils2.hexToBytes)(spendingPrivateKey.slice(2));
|
|
1134
|
+
const viewingPrivBytes = (0, import_utils2.hexToBytes)(viewingPrivateKey.slice(2));
|
|
1135
|
+
const ephemeralPubBytes = (0, import_utils2.hexToBytes)(stealthAddress.ephemeralPublicKey.slice(2));
|
|
1136
|
+
try {
|
|
1137
|
+
const rawSpendingScalar = getEd25519Scalar(spendingPrivBytes);
|
|
1138
|
+
const spendingScalar = rawSpendingScalar % ED25519_ORDER;
|
|
1139
|
+
if (spendingScalar === 0n) {
|
|
1140
|
+
throw new Error("CRITICAL: Zero spending scalar after reduction - investigate key derivation");
|
|
1141
|
+
}
|
|
1142
|
+
const ephemeralPoint = import_ed25519.ed25519.ExtendedPoint.fromHex(ephemeralPubBytes);
|
|
1143
|
+
const sharedSecretPoint = ephemeralPoint.multiply(spendingScalar);
|
|
1144
|
+
const sharedSecretHash = (0, import_sha256.sha256)(sharedSecretPoint.toRawBytes());
|
|
1145
|
+
const rawViewingScalar = getEd25519Scalar(viewingPrivBytes);
|
|
1146
|
+
const viewingScalar = rawViewingScalar % ED25519_ORDER;
|
|
1147
|
+
if (viewingScalar === 0n) {
|
|
1148
|
+
throw new Error("CRITICAL: Zero viewing scalar after reduction - investigate key derivation");
|
|
1149
|
+
}
|
|
1150
|
+
const hashScalar = bytesToBigInt(sharedSecretHash) % ED25519_ORDER;
|
|
1151
|
+
if (hashScalar === 0n) {
|
|
1152
|
+
throw new Error("CRITICAL: Zero hash scalar after reduction - investigate hash computation");
|
|
1153
|
+
}
|
|
1154
|
+
const stealthPrivateScalar = (viewingScalar + hashScalar) % ED25519_ORDER;
|
|
1155
|
+
if (stealthPrivateScalar === 0n) {
|
|
1156
|
+
throw new Error("CRITICAL: Zero stealth scalar after reduction - investigate key derivation");
|
|
1157
|
+
}
|
|
1158
|
+
const stealthPrivateKey = bigIntToBytesLE(stealthPrivateScalar, 32);
|
|
1159
|
+
const result = {
|
|
1160
|
+
stealthAddress: stealthAddress.address,
|
|
1161
|
+
ephemeralPublicKey: stealthAddress.ephemeralPublicKey,
|
|
1162
|
+
privateKey: `0x${(0, import_utils2.bytesToHex)(stealthPrivateKey)}`
|
|
1163
|
+
};
|
|
1164
|
+
secureWipe(stealthPrivateKey);
|
|
1165
|
+
return result;
|
|
1166
|
+
} finally {
|
|
1167
|
+
secureWipeAll(spendingPrivBytes, viewingPrivBytes);
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
function checkEd25519StealthAddress(stealthAddress, spendingPrivateKey, viewingPrivateKey) {
|
|
1171
|
+
validateEd25519StealthAddress(stealthAddress);
|
|
1172
|
+
if (!isValidPrivateKey(spendingPrivateKey)) {
|
|
1173
|
+
throw new ValidationError(
|
|
1174
|
+
"must be a valid 32-byte hex string",
|
|
1175
|
+
"spendingPrivateKey"
|
|
1176
|
+
);
|
|
1177
|
+
}
|
|
1178
|
+
if (!isValidPrivateKey(viewingPrivateKey)) {
|
|
1179
|
+
throw new ValidationError(
|
|
1180
|
+
"must be a valid 32-byte hex string",
|
|
1181
|
+
"viewingPrivateKey"
|
|
1182
|
+
);
|
|
1183
|
+
}
|
|
1184
|
+
const spendingPrivBytes = (0, import_utils2.hexToBytes)(spendingPrivateKey.slice(2));
|
|
1185
|
+
const viewingPrivBytes = (0, import_utils2.hexToBytes)(viewingPrivateKey.slice(2));
|
|
1186
|
+
const ephemeralPubBytes = (0, import_utils2.hexToBytes)(stealthAddress.ephemeralPublicKey.slice(2));
|
|
1187
|
+
try {
|
|
1188
|
+
const rawSpendingScalar = getEd25519Scalar(spendingPrivBytes);
|
|
1189
|
+
const spendingScalar = rawSpendingScalar % ED25519_ORDER;
|
|
1190
|
+
if (spendingScalar === 0n) {
|
|
1191
|
+
throw new Error("CRITICAL: Zero spending scalar after reduction - investigate key derivation");
|
|
1192
|
+
}
|
|
1193
|
+
const ephemeralPoint = import_ed25519.ed25519.ExtendedPoint.fromHex(ephemeralPubBytes);
|
|
1194
|
+
const sharedSecretPoint = ephemeralPoint.multiply(spendingScalar);
|
|
1195
|
+
const sharedSecretHash = (0, import_sha256.sha256)(sharedSecretPoint.toRawBytes());
|
|
1196
|
+
if (sharedSecretHash[0] !== stealthAddress.viewTag) {
|
|
1197
|
+
return false;
|
|
1198
|
+
}
|
|
1199
|
+
const rawViewingScalar = getEd25519Scalar(viewingPrivBytes);
|
|
1200
|
+
const viewingScalar = rawViewingScalar % ED25519_ORDER;
|
|
1201
|
+
if (viewingScalar === 0n) {
|
|
1202
|
+
throw new Error("CRITICAL: Zero viewing scalar after reduction - investigate key derivation");
|
|
1203
|
+
}
|
|
1204
|
+
const hashScalar = bytesToBigInt(sharedSecretHash) % ED25519_ORDER;
|
|
1205
|
+
if (hashScalar === 0n) {
|
|
1206
|
+
throw new Error("CRITICAL: Zero hash scalar after reduction - investigate hash computation");
|
|
1207
|
+
}
|
|
1208
|
+
const stealthPrivateScalar = (viewingScalar + hashScalar) % ED25519_ORDER;
|
|
1209
|
+
if (stealthPrivateScalar === 0n) {
|
|
1210
|
+
throw new Error("CRITICAL: Zero stealth scalar after reduction - investigate key derivation");
|
|
1211
|
+
}
|
|
1212
|
+
const expectedPubKey = import_ed25519.ed25519.ExtendedPoint.BASE.multiply(stealthPrivateScalar);
|
|
1213
|
+
const expectedPubKeyBytes = expectedPubKey.toRawBytes();
|
|
1214
|
+
const providedAddress = (0, import_utils2.hexToBytes)(stealthAddress.address.slice(2));
|
|
1215
|
+
return (0, import_utils2.bytesToHex)(expectedPubKeyBytes) === (0, import_utils2.bytesToHex)(providedAddress);
|
|
1216
|
+
} finally {
|
|
1217
|
+
secureWipeAll(spendingPrivBytes, viewingPrivBytes);
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
var BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
1221
|
+
function bytesToBase58(bytes) {
|
|
1222
|
+
let leadingZeros = 0;
|
|
1223
|
+
for (let i = 0; i < bytes.length && bytes[i] === 0; i++) {
|
|
1224
|
+
leadingZeros++;
|
|
1225
|
+
}
|
|
1226
|
+
let value = 0n;
|
|
1227
|
+
for (const byte of bytes) {
|
|
1228
|
+
value = value * 256n + BigInt(byte);
|
|
1229
|
+
}
|
|
1230
|
+
let result = "";
|
|
1231
|
+
while (value > 0n) {
|
|
1232
|
+
const remainder = value % 58n;
|
|
1233
|
+
value = value / 58n;
|
|
1234
|
+
result = BASE58_ALPHABET[Number(remainder)] + result;
|
|
1235
|
+
}
|
|
1236
|
+
return "1".repeat(leadingZeros) + result;
|
|
1237
|
+
}
|
|
1238
|
+
function base58ToBytes(str) {
|
|
1239
|
+
let leadingOnes = 0;
|
|
1240
|
+
for (let i = 0; i < str.length && str[i] === "1"; i++) {
|
|
1241
|
+
leadingOnes++;
|
|
1242
|
+
}
|
|
1243
|
+
let value = 0n;
|
|
1244
|
+
for (const char of str) {
|
|
1245
|
+
const index = BASE58_ALPHABET.indexOf(char);
|
|
1246
|
+
if (index === -1) {
|
|
1247
|
+
throw new ValidationError(`Invalid base58 character: ${char}`, "address");
|
|
1248
|
+
}
|
|
1249
|
+
value = value * 58n + BigInt(index);
|
|
1250
|
+
}
|
|
1251
|
+
const bytes = [];
|
|
1252
|
+
while (value > 0n) {
|
|
1253
|
+
bytes.unshift(Number(value % 256n));
|
|
1254
|
+
value = value / 256n;
|
|
1255
|
+
}
|
|
1256
|
+
const result = new Uint8Array(leadingOnes + bytes.length);
|
|
1257
|
+
for (let i = 0; i < leadingOnes; i++) {
|
|
1258
|
+
result[i] = 0;
|
|
1259
|
+
}
|
|
1260
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
1261
|
+
result[leadingOnes + i] = bytes[i];
|
|
1262
|
+
}
|
|
1263
|
+
return result;
|
|
1264
|
+
}
|
|
1265
|
+
function ed25519PublicKeyToSolanaAddress(publicKey) {
|
|
1266
|
+
if (!isValidHex(publicKey)) {
|
|
1267
|
+
throw new ValidationError(
|
|
1268
|
+
"publicKey must be a valid hex string with 0x prefix",
|
|
1269
|
+
"publicKey"
|
|
1270
|
+
);
|
|
1271
|
+
}
|
|
1272
|
+
if (!isValidEd25519PublicKey(publicKey)) {
|
|
1273
|
+
throw new ValidationError(
|
|
1274
|
+
"publicKey must be 32 bytes (64 hex characters)",
|
|
1275
|
+
"publicKey"
|
|
1276
|
+
);
|
|
1277
|
+
}
|
|
1278
|
+
const publicKeyBytes = (0, import_utils2.hexToBytes)(publicKey.slice(2));
|
|
1279
|
+
return bytesToBase58(publicKeyBytes);
|
|
1280
|
+
}
|
|
1281
|
+
function isValidSolanaAddress(address) {
|
|
1282
|
+
if (typeof address !== "string" || address.length === 0) {
|
|
1283
|
+
return false;
|
|
1284
|
+
}
|
|
1285
|
+
if (address.length < 32 || address.length > 44) {
|
|
1286
|
+
return false;
|
|
1287
|
+
}
|
|
1288
|
+
try {
|
|
1289
|
+
const decoded = base58ToBytes(address);
|
|
1290
|
+
return decoded.length === 32;
|
|
1291
|
+
} catch {
|
|
1292
|
+
return false;
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
function solanaAddressToEd25519PublicKey(address) {
|
|
1296
|
+
if (!isValidSolanaAddress(address)) {
|
|
1297
|
+
throw new ValidationError(
|
|
1298
|
+
"Invalid Solana address format",
|
|
1299
|
+
"address"
|
|
1300
|
+
);
|
|
1301
|
+
}
|
|
1302
|
+
const decoded = base58ToBytes(address);
|
|
1303
|
+
return `0x${(0, import_utils2.bytesToHex)(decoded)}`;
|
|
1304
|
+
}
|
|
1305
|
+
function ed25519PublicKeyToNearAddress(publicKey) {
|
|
1306
|
+
if (!isValidHex(publicKey)) {
|
|
1307
|
+
throw new ValidationError(
|
|
1308
|
+
"publicKey must be a valid hex string with 0x prefix",
|
|
1309
|
+
"publicKey"
|
|
1310
|
+
);
|
|
1311
|
+
}
|
|
1312
|
+
if (!isValidEd25519PublicKey(publicKey)) {
|
|
1313
|
+
throw new ValidationError(
|
|
1314
|
+
"publicKey must be 32 bytes (64 hex characters)",
|
|
1315
|
+
"publicKey"
|
|
1316
|
+
);
|
|
1317
|
+
}
|
|
1318
|
+
return publicKey.slice(2).toLowerCase();
|
|
1319
|
+
}
|
|
1320
|
+
function nearAddressToEd25519PublicKey(address) {
|
|
1321
|
+
if (!isValidNearImplicitAddress(address)) {
|
|
1322
|
+
throw new ValidationError(
|
|
1323
|
+
"Invalid NEAR implicit address format",
|
|
1324
|
+
"address"
|
|
1325
|
+
);
|
|
1326
|
+
}
|
|
1327
|
+
return `0x${address.toLowerCase()}`;
|
|
1328
|
+
}
|
|
1329
|
+
function isValidNearImplicitAddress(address) {
|
|
1330
|
+
if (typeof address !== "string" || address.length === 0) {
|
|
1331
|
+
return false;
|
|
1332
|
+
}
|
|
1333
|
+
if (address.length !== 64) {
|
|
1334
|
+
return false;
|
|
1335
|
+
}
|
|
1336
|
+
return /^[0-9a-f]{64}$/.test(address);
|
|
1337
|
+
}
|
|
1338
|
+
function isValidNearAccountId(accountId) {
|
|
1339
|
+
if (typeof accountId !== "string" || accountId.length === 0) {
|
|
1340
|
+
return false;
|
|
1341
|
+
}
|
|
1342
|
+
if (isValidNearImplicitAddress(accountId)) {
|
|
1343
|
+
return true;
|
|
1344
|
+
}
|
|
1345
|
+
if (accountId.length < 2 || accountId.length > 64) {
|
|
1346
|
+
return false;
|
|
1347
|
+
}
|
|
1348
|
+
const nearAccountPattern = /^[a-z0-9]([a-z0-9._-]*[a-z0-9])?$/;
|
|
1349
|
+
if (!nearAccountPattern.test(accountId)) {
|
|
1350
|
+
return false;
|
|
1351
|
+
}
|
|
1352
|
+
if (accountId.includes("..")) {
|
|
1353
|
+
return false;
|
|
1354
|
+
}
|
|
1355
|
+
return true;
|
|
1356
|
+
}
|
|
906
1357
|
|
|
907
1358
|
// src/crypto.ts
|
|
908
1359
|
var import_sha2563 = require("@noble/hashes/sha256");
|
|
@@ -957,9 +1408,9 @@ function commit(value, blinding) {
|
|
|
957
1408
|
if (r.length !== 32) {
|
|
958
1409
|
throw new ValidationError("must be 32 bytes", "blinding", { received: r.length });
|
|
959
1410
|
}
|
|
960
|
-
|
|
1411
|
+
const rScalar = bytesToBigInt2(r) % CURVE_ORDER;
|
|
961
1412
|
if (rScalar === 0n) {
|
|
962
|
-
|
|
1413
|
+
throw new Error("CRITICAL: Zero blinding scalar after reduction - investigate RNG");
|
|
963
1414
|
}
|
|
964
1415
|
let C;
|
|
965
1416
|
if (value === 0n && rScalar === 0n) {
|
|
@@ -985,9 +1436,9 @@ function verifyOpening(commitment, value, blinding) {
|
|
|
985
1436
|
}
|
|
986
1437
|
const C = import_secp256k12.secp256k1.ProjectivePoint.fromHex(commitment.slice(2));
|
|
987
1438
|
const blindingBytes = (0, import_utils3.hexToBytes)(blinding.slice(2));
|
|
988
|
-
|
|
1439
|
+
const rScalar = bytesToBigInt2(blindingBytes) % CURVE_ORDER;
|
|
989
1440
|
if (rScalar === 0n) {
|
|
990
|
-
|
|
1441
|
+
throw new Error("CRITICAL: Zero blinding scalar after reduction - investigate RNG");
|
|
991
1442
|
}
|
|
992
1443
|
let expected;
|
|
993
1444
|
if (value === 0n) {
|
|
@@ -1151,7 +1602,7 @@ var import_sha2565 = require("@noble/hashes/sha256");
|
|
|
1151
1602
|
|
|
1152
1603
|
// src/privacy.ts
|
|
1153
1604
|
var import_sha2564 = require("@noble/hashes/sha256");
|
|
1154
|
-
var
|
|
1605
|
+
var import_sha5122 = require("@noble/hashes/sha512");
|
|
1155
1606
|
var import_hmac = require("@noble/hashes/hmac");
|
|
1156
1607
|
var import_hkdf = require("@noble/hashes/hkdf");
|
|
1157
1608
|
var import_utils5 = require("@noble/hashes/utils");
|
|
@@ -1213,7 +1664,7 @@ function deriveViewingKey(masterKey, childPath) {
|
|
|
1213
1664
|
const masterKeyHex = masterKey.key.startsWith("0x") ? masterKey.key.slice(2) : masterKey.key;
|
|
1214
1665
|
const masterKeyBytes = (0, import_utils5.hexToBytes)(masterKeyHex);
|
|
1215
1666
|
const childPathBytes = (0, import_utils5.utf8ToBytes)(childPath);
|
|
1216
|
-
const derivedFull = (0, import_hmac.hmac)(
|
|
1667
|
+
const derivedFull = (0, import_hmac.hmac)(import_sha5122.sha512, masterKeyBytes, childPathBytes);
|
|
1217
1668
|
try {
|
|
1218
1669
|
const derivedBytes = derivedFull.slice(0, 32);
|
|
1219
1670
|
const derived = `0x${(0, import_utils5.bytesToHex)(derivedBytes)}`;
|
|
@@ -1973,6 +2424,8 @@ var NEARIntentsAdapter = class {
|
|
|
1973
2424
|
let refundAddress = senderAddress;
|
|
1974
2425
|
let stealthData;
|
|
1975
2426
|
let sharedSecret;
|
|
2427
|
+
let curve;
|
|
2428
|
+
let nativeRecipientAddress;
|
|
1976
2429
|
if (request.privacyLevel !== import_types3.PrivacyLevel.TRANSPARENT) {
|
|
1977
2430
|
if (!recipientMetaAddress) {
|
|
1978
2431
|
throw new ValidationError(
|
|
@@ -1981,25 +2434,91 @@ var NEARIntentsAdapter = class {
|
|
|
1981
2434
|
);
|
|
1982
2435
|
}
|
|
1983
2436
|
const metaAddr = typeof recipientMetaAddress === "string" ? decodeStealthMetaAddress(recipientMetaAddress) : recipientMetaAddress;
|
|
1984
|
-
const
|
|
1985
|
-
const outputChainType = CHAIN_BLOCKCHAIN_MAP[
|
|
1986
|
-
if (
|
|
2437
|
+
const outputChain = request.outputAsset.chain;
|
|
2438
|
+
const outputChainType = CHAIN_BLOCKCHAIN_MAP[outputChain];
|
|
2439
|
+
if (isEd25519Chain(outputChain)) {
|
|
2440
|
+
curve = "ed25519";
|
|
2441
|
+
const spendingKeyBytes = (metaAddr.spendingKey.length - 2) / 2;
|
|
2442
|
+
if (spendingKeyBytes !== 32) {
|
|
2443
|
+
throw new ValidationError(
|
|
2444
|
+
`Meta-address has ${spendingKeyBytes}-byte keys but ${outputChain} requires ed25519 (32-byte) keys. Please generate an ed25519 meta-address using generateEd25519StealthMetaAddress('${outputChain}').`,
|
|
2445
|
+
"recipientMetaAddress",
|
|
2446
|
+
{ outputChain, keySize: spendingKeyBytes, expectedSize: 32 }
|
|
2447
|
+
);
|
|
2448
|
+
}
|
|
2449
|
+
const { stealthAddress, sharedSecret: secret } = generateEd25519StealthAddress(metaAddr);
|
|
2450
|
+
stealthData = stealthAddress;
|
|
2451
|
+
sharedSecret = secret;
|
|
2452
|
+
if (outputChain === "solana") {
|
|
2453
|
+
recipientAddress = ed25519PublicKeyToSolanaAddress(stealthAddress.address);
|
|
2454
|
+
} else if (outputChain === "near") {
|
|
2455
|
+
recipientAddress = ed25519PublicKeyToNearAddress(stealthAddress.address);
|
|
2456
|
+
} else {
|
|
2457
|
+
throw new ValidationError(
|
|
2458
|
+
`ed25519 address derivation not implemented for ${outputChain}`,
|
|
2459
|
+
"outputAsset",
|
|
2460
|
+
{ outputChain }
|
|
2461
|
+
);
|
|
2462
|
+
}
|
|
2463
|
+
nativeRecipientAddress = recipientAddress;
|
|
2464
|
+
} else if (outputChainType === "evm") {
|
|
2465
|
+
curve = "secp256k1";
|
|
2466
|
+
const spendingKeyBytes = (metaAddr.spendingKey.length - 2) / 2;
|
|
2467
|
+
if (spendingKeyBytes !== 33) {
|
|
2468
|
+
throw new ValidationError(
|
|
2469
|
+
`Meta-address has ${spendingKeyBytes}-byte keys but ${outputChain} requires secp256k1 (33-byte compressed) keys. Please generate a secp256k1 meta-address using generateStealthMetaAddress('${outputChain}').`,
|
|
2470
|
+
"recipientMetaAddress",
|
|
2471
|
+
{ outputChain, keySize: spendingKeyBytes, expectedSize: 33 }
|
|
2472
|
+
);
|
|
2473
|
+
}
|
|
2474
|
+
const { stealthAddress, sharedSecret: secret } = generateStealthAddress(metaAddr);
|
|
2475
|
+
stealthData = stealthAddress;
|
|
2476
|
+
sharedSecret = secret;
|
|
1987
2477
|
recipientAddress = publicKeyToEthAddress(stealthAddress.address);
|
|
2478
|
+
nativeRecipientAddress = recipientAddress;
|
|
1988
2479
|
} else {
|
|
1989
|
-
|
|
2480
|
+
throw new ValidationError(
|
|
2481
|
+
`Stealth addresses are not yet supported for ${outputChain} output. Supported chains: EVM (Ethereum, Polygon, etc.), Solana, NEAR. For ${outputChain}, please provide a direct wallet address.`,
|
|
2482
|
+
"outputAsset",
|
|
2483
|
+
{ outputChain, outputChainType }
|
|
2484
|
+
);
|
|
1990
2485
|
}
|
|
1991
|
-
stealthData = stealthAddress;
|
|
1992
|
-
sharedSecret = secret;
|
|
1993
2486
|
if (!senderAddress) {
|
|
1994
|
-
const
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
2487
|
+
const inputChain = request.inputAsset.chain;
|
|
2488
|
+
const inputChainType = CHAIN_BLOCKCHAIN_MAP[inputChain];
|
|
2489
|
+
if (isEd25519Chain(inputChain)) {
|
|
2490
|
+
const inputKeyBytes = (metaAddr.spendingKey.length - 2) / 2;
|
|
2491
|
+
if (inputKeyBytes === 32) {
|
|
2492
|
+
const refundStealth = generateEd25519StealthAddress(metaAddr);
|
|
2493
|
+
if (inputChain === "solana") {
|
|
2494
|
+
refundAddress = ed25519PublicKeyToSolanaAddress(refundStealth.stealthAddress.address);
|
|
2495
|
+
} else if (inputChain === "near") {
|
|
2496
|
+
refundAddress = ed25519PublicKeyToNearAddress(refundStealth.stealthAddress.address);
|
|
2497
|
+
}
|
|
2498
|
+
} else {
|
|
2499
|
+
throw new ValidationError(
|
|
2500
|
+
`Cross-curve refunds not supported: input chain ${inputChain} requires ed25519 but meta-address uses secp256k1. Please provide a senderAddress for refunds, or use matching curves for input/output chains.`,
|
|
2501
|
+
"senderAddress",
|
|
2502
|
+
{ inputChain, inputChainType, metaAddressCurve: "secp256k1" }
|
|
2503
|
+
);
|
|
2504
|
+
}
|
|
2505
|
+
} else if (inputChainType === "evm") {
|
|
2506
|
+
const inputKeyBytes = (metaAddr.spendingKey.length - 2) / 2;
|
|
2507
|
+
if (inputKeyBytes === 33) {
|
|
2508
|
+
const refundStealth = generateStealthAddress(metaAddr);
|
|
2509
|
+
refundAddress = publicKeyToEthAddress(refundStealth.stealthAddress.address);
|
|
2510
|
+
} else {
|
|
2511
|
+
throw new ValidationError(
|
|
2512
|
+
`Cross-curve refunds not supported: input chain ${inputChain} requires secp256k1 but meta-address uses ed25519. Please provide a senderAddress for refunds, or use matching curves for input/output chains.`,
|
|
2513
|
+
"senderAddress",
|
|
2514
|
+
{ inputChain, inputChainType, metaAddressCurve: "ed25519" }
|
|
2515
|
+
);
|
|
2516
|
+
}
|
|
1998
2517
|
} else {
|
|
1999
2518
|
throw new ValidationError(
|
|
2000
|
-
`senderAddress is required for refunds on ${
|
|
2519
|
+
`senderAddress is required for refunds on ${inputChain}. Automatic refund address generation is only supported for EVM, Solana, and NEAR chains.`,
|
|
2001
2520
|
"senderAddress",
|
|
2002
|
-
{ inputChain
|
|
2521
|
+
{ inputChain, inputChainType }
|
|
2003
2522
|
);
|
|
2004
2523
|
}
|
|
2005
2524
|
}
|
|
@@ -2017,7 +2536,9 @@ var NEARIntentsAdapter = class {
|
|
|
2017
2536
|
request,
|
|
2018
2537
|
quoteRequest,
|
|
2019
2538
|
stealthAddress: stealthData,
|
|
2020
|
-
sharedSecret
|
|
2539
|
+
sharedSecret,
|
|
2540
|
+
curve,
|
|
2541
|
+
nativeRecipientAddress
|
|
2021
2542
|
};
|
|
2022
2543
|
}
|
|
2023
2544
|
/**
|
|
@@ -4282,7 +4803,739 @@ var NoirProofProvider = class {
|
|
|
4282
4803
|
}
|
|
4283
4804
|
try {
|
|
4284
4805
|
const proofHex = proof.proof.startsWith("0x") ? proof.proof.slice(2) : proof.proof;
|
|
4285
|
-
const proofBytes = new Uint8Array(Buffer.from(proofHex, "hex"));
|
|
4806
|
+
const proofBytes = new Uint8Array(Buffer.from(proofHex, "hex"));
|
|
4807
|
+
const isValid = await backend.verifyProof({
|
|
4808
|
+
proof: proofBytes,
|
|
4809
|
+
publicInputs: proof.publicInputs.map(
|
|
4810
|
+
(input) => input.startsWith("0x") ? input.slice(2) : input
|
|
4811
|
+
)
|
|
4812
|
+
});
|
|
4813
|
+
return isValid;
|
|
4814
|
+
} catch (error) {
|
|
4815
|
+
if (this.config.verbose) {
|
|
4816
|
+
console.error("[NoirProofProvider] Verification error:", error);
|
|
4817
|
+
}
|
|
4818
|
+
return false;
|
|
4819
|
+
}
|
|
4820
|
+
}
|
|
4821
|
+
/**
|
|
4822
|
+
* Destroy the provider and free resources
|
|
4823
|
+
*/
|
|
4824
|
+
async destroy() {
|
|
4825
|
+
if (this.fundingBackend) {
|
|
4826
|
+
await this.fundingBackend.destroy();
|
|
4827
|
+
this.fundingBackend = null;
|
|
4828
|
+
}
|
|
4829
|
+
if (this.validityBackend) {
|
|
4830
|
+
await this.validityBackend.destroy();
|
|
4831
|
+
this.validityBackend = null;
|
|
4832
|
+
}
|
|
4833
|
+
if (this.fulfillmentBackend) {
|
|
4834
|
+
await this.fulfillmentBackend.destroy();
|
|
4835
|
+
this.fulfillmentBackend = null;
|
|
4836
|
+
}
|
|
4837
|
+
this.fundingNoir = null;
|
|
4838
|
+
this.validityNoir = null;
|
|
4839
|
+
this.fulfillmentNoir = null;
|
|
4840
|
+
this._isReady = false;
|
|
4841
|
+
}
|
|
4842
|
+
// ─── Private Methods ───────────────────────────────────────────────────────
|
|
4843
|
+
ensureReady() {
|
|
4844
|
+
if (!this._isReady) {
|
|
4845
|
+
throw new ProofError(
|
|
4846
|
+
"NoirProofProvider not initialized. Call initialize() first.",
|
|
4847
|
+
"SIP_4004" /* PROOF_PROVIDER_NOT_READY */
|
|
4848
|
+
);
|
|
4849
|
+
}
|
|
4850
|
+
}
|
|
4851
|
+
/**
|
|
4852
|
+
* Compute the commitment hash that the circuit expects
|
|
4853
|
+
*
|
|
4854
|
+
* The circuit computes:
|
|
4855
|
+
* 1. commitment = pedersen_commitment([balance, blinding])
|
|
4856
|
+
* 2. commitment_hash = pedersen_hash([commitment.x, commitment.y, asset_id])
|
|
4857
|
+
*
|
|
4858
|
+
* We need to compute this outside to pass as a public input.
|
|
4859
|
+
*
|
|
4860
|
+
* **IMPORTANT**: This SDK uses SHA256 as a deterministic stand-in for Pedersen hash.
|
|
4861
|
+
* Both the SDK and circuit MUST use the same hash function. The bundled circuit
|
|
4862
|
+
* artifacts are configured to use SHA256 for compatibility. If you use custom
|
|
4863
|
+
* circuits with actual Pedersen hashing, you must update this implementation.
|
|
4864
|
+
*
|
|
4865
|
+
* @see docs/specs/HASH-COMPATIBILITY.md for hash function requirements
|
|
4866
|
+
*/
|
|
4867
|
+
async computeCommitmentHash(balance, blindingFactor, assetId) {
|
|
4868
|
+
const blindingField = this.bytesToField(blindingFactor);
|
|
4869
|
+
const { sha256: sha25611 } = await import("@noble/hashes/sha256");
|
|
4870
|
+
const { bytesToHex: bytesToHex15 } = await import("@noble/hashes/utils");
|
|
4871
|
+
const preimage = new Uint8Array([
|
|
4872
|
+
...this.bigintToBytes(balance, 8),
|
|
4873
|
+
...blindingFactor.slice(0, 32),
|
|
4874
|
+
...this.hexToBytes(this.assetIdToField(assetId))
|
|
4875
|
+
]);
|
|
4876
|
+
const hash2 = sha25611(preimage);
|
|
4877
|
+
const commitmentHash = bytesToHex15(hash2);
|
|
4878
|
+
return { commitmentHash, blindingField };
|
|
4879
|
+
}
|
|
4880
|
+
/**
|
|
4881
|
+
* Convert asset ID to field element
|
|
4882
|
+
*/
|
|
4883
|
+
assetIdToField(assetId) {
|
|
4884
|
+
if (assetId.startsWith("0x")) {
|
|
4885
|
+
return assetId.slice(2).padStart(64, "0");
|
|
4886
|
+
}
|
|
4887
|
+
const encoder = new TextEncoder();
|
|
4888
|
+
const bytes = encoder.encode(assetId);
|
|
4889
|
+
let result = 0n;
|
|
4890
|
+
for (let i = 0; i < bytes.length && i < 31; i++) {
|
|
4891
|
+
result = result * 256n + BigInt(bytes[i]);
|
|
4892
|
+
}
|
|
4893
|
+
return result.toString(16).padStart(64, "0");
|
|
4894
|
+
}
|
|
4895
|
+
/**
|
|
4896
|
+
* Convert bytes to field element string
|
|
4897
|
+
*/
|
|
4898
|
+
bytesToField(bytes) {
|
|
4899
|
+
let result = 0n;
|
|
4900
|
+
const len = Math.min(bytes.length, 31);
|
|
4901
|
+
for (let i = 0; i < len; i++) {
|
|
4902
|
+
result = result * 256n + BigInt(bytes[i]);
|
|
4903
|
+
}
|
|
4904
|
+
return result.toString();
|
|
4905
|
+
}
|
|
4906
|
+
/**
|
|
4907
|
+
* Convert bigint to bytes
|
|
4908
|
+
*/
|
|
4909
|
+
bigintToBytes(value, length) {
|
|
4910
|
+
const bytes = new Uint8Array(length);
|
|
4911
|
+
let v = value;
|
|
4912
|
+
for (let i = length - 1; i >= 0; i--) {
|
|
4913
|
+
bytes[i] = Number(v & 0xffn);
|
|
4914
|
+
v = v >> 8n;
|
|
4915
|
+
}
|
|
4916
|
+
return bytes;
|
|
4917
|
+
}
|
|
4918
|
+
/**
|
|
4919
|
+
* Convert hex string to bytes
|
|
4920
|
+
*/
|
|
4921
|
+
hexToBytes(hex) {
|
|
4922
|
+
const h = hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
4923
|
+
const bytes = new Uint8Array(h.length / 2);
|
|
4924
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
4925
|
+
bytes[i] = parseInt(h.slice(i * 2, i * 2 + 2), 16);
|
|
4926
|
+
}
|
|
4927
|
+
return bytes;
|
|
4928
|
+
}
|
|
4929
|
+
/**
|
|
4930
|
+
* Convert hex string to field element string
|
|
4931
|
+
*/
|
|
4932
|
+
hexToField(hex) {
|
|
4933
|
+
const h = hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
4934
|
+
return h.padStart(64, "0");
|
|
4935
|
+
}
|
|
4936
|
+
/**
|
|
4937
|
+
* Convert field string to 32-byte array
|
|
4938
|
+
*/
|
|
4939
|
+
fieldToBytes32(field) {
|
|
4940
|
+
const hex = field.padStart(64, "0");
|
|
4941
|
+
const bytes = [];
|
|
4942
|
+
for (let i = 0; i < 32; i++) {
|
|
4943
|
+
bytes.push(parseInt(hex.slice(i * 2, i * 2 + 2), 16));
|
|
4944
|
+
}
|
|
4945
|
+
return bytes;
|
|
4946
|
+
}
|
|
4947
|
+
/**
|
|
4948
|
+
* Compute sender commitment for validity proof
|
|
4949
|
+
*
|
|
4950
|
+
* Uses SHA256 for SDK-side computation. The bundled circuit artifacts
|
|
4951
|
+
* are compiled to use SHA256 for compatibility with this SDK.
|
|
4952
|
+
*
|
|
4953
|
+
* @see computeCommitmentHash for hash function compatibility notes
|
|
4954
|
+
*/
|
|
4955
|
+
async computeSenderCommitment(senderAddressField, senderBlindingField) {
|
|
4956
|
+
const { sha256: sha25611 } = await import("@noble/hashes/sha256");
|
|
4957
|
+
const { bytesToHex: bytesToHex15 } = await import("@noble/hashes/utils");
|
|
4958
|
+
const addressBytes = this.hexToBytes(senderAddressField);
|
|
4959
|
+
const blindingBytes = this.hexToBytes(senderBlindingField.padStart(64, "0"));
|
|
4960
|
+
const preimage = new Uint8Array([...addressBytes, ...blindingBytes]);
|
|
4961
|
+
const hash2 = sha25611(preimage);
|
|
4962
|
+
const commitmentX = bytesToHex15(hash2.slice(0, 16)).padStart(64, "0");
|
|
4963
|
+
const commitmentY = bytesToHex15(hash2.slice(16, 32)).padStart(64, "0");
|
|
4964
|
+
return { commitmentX, commitmentY };
|
|
4965
|
+
}
|
|
4966
|
+
/**
|
|
4967
|
+
* Compute nullifier for validity proof
|
|
4968
|
+
*
|
|
4969
|
+
* Uses SHA256 for SDK-side computation. The bundled circuit artifacts
|
|
4970
|
+
* are compiled to use SHA256 for compatibility with this SDK.
|
|
4971
|
+
*
|
|
4972
|
+
* @see computeCommitmentHash for hash function compatibility notes
|
|
4973
|
+
*/
|
|
4974
|
+
async computeNullifier(senderSecretField, intentHashField, nonceField) {
|
|
4975
|
+
const { sha256: sha25611 } = await import("@noble/hashes/sha256");
|
|
4976
|
+
const { bytesToHex: bytesToHex15 } = await import("@noble/hashes/utils");
|
|
4977
|
+
const secretBytes = this.hexToBytes(senderSecretField.padStart(64, "0"));
|
|
4978
|
+
const intentBytes = this.hexToBytes(intentHashField);
|
|
4979
|
+
const nonceBytes = this.hexToBytes(nonceField.padStart(64, "0"));
|
|
4980
|
+
const preimage = new Uint8Array([...secretBytes, ...intentBytes, ...nonceBytes]);
|
|
4981
|
+
const hash2 = sha25611(preimage);
|
|
4982
|
+
return bytesToHex15(hash2);
|
|
4983
|
+
}
|
|
4984
|
+
/**
|
|
4985
|
+
* Compute output commitment for fulfillment proof
|
|
4986
|
+
*
|
|
4987
|
+
* Uses SHA256 for SDK-side computation. The bundled circuit artifacts
|
|
4988
|
+
* are compiled to use SHA256 for compatibility with this SDK.
|
|
4989
|
+
*
|
|
4990
|
+
* @see computeCommitmentHash for hash function compatibility notes
|
|
4991
|
+
*/
|
|
4992
|
+
async computeOutputCommitment(outputAmount, outputBlinding) {
|
|
4993
|
+
const { sha256: sha25611 } = await import("@noble/hashes/sha256");
|
|
4994
|
+
const { bytesToHex: bytesToHex15 } = await import("@noble/hashes/utils");
|
|
4995
|
+
const amountBytes = this.bigintToBytes(outputAmount, 8);
|
|
4996
|
+
const blindingBytes = outputBlinding.slice(0, 32);
|
|
4997
|
+
const preimage = new Uint8Array([...amountBytes, ...blindingBytes]);
|
|
4998
|
+
const hash2 = sha25611(preimage);
|
|
4999
|
+
const commitmentX = bytesToHex15(hash2.slice(0, 16)).padStart(64, "0");
|
|
5000
|
+
const commitmentY = bytesToHex15(hash2.slice(16, 32)).padStart(64, "0");
|
|
5001
|
+
return { commitmentX, commitmentY };
|
|
5002
|
+
}
|
|
5003
|
+
/**
|
|
5004
|
+
* Compute solver ID from solver secret
|
|
5005
|
+
*
|
|
5006
|
+
* Uses SHA256 for SDK-side computation. The bundled circuit artifacts
|
|
5007
|
+
* are compiled to use SHA256 for compatibility with this SDK.
|
|
5008
|
+
*
|
|
5009
|
+
* @see computeCommitmentHash for hash function compatibility notes
|
|
5010
|
+
*/
|
|
5011
|
+
async computeSolverId(solverSecretField) {
|
|
5012
|
+
const { sha256: sha25611 } = await import("@noble/hashes/sha256");
|
|
5013
|
+
const { bytesToHex: bytesToHex15 } = await import("@noble/hashes/utils");
|
|
5014
|
+
const secretBytes = this.hexToBytes(solverSecretField.padStart(64, "0"));
|
|
5015
|
+
const hash2 = sha25611(secretBytes);
|
|
5016
|
+
return bytesToHex15(hash2);
|
|
5017
|
+
}
|
|
5018
|
+
/**
|
|
5019
|
+
* Compute oracle message hash for fulfillment proof
|
|
5020
|
+
*
|
|
5021
|
+
* Hash of attestation data that oracle signs
|
|
5022
|
+
*/
|
|
5023
|
+
async computeOracleMessageHash(recipient, amount, txHash, blockNumber) {
|
|
5024
|
+
const { sha256: sha25611 } = await import("@noble/hashes/sha256");
|
|
5025
|
+
const recipientBytes = this.hexToBytes(this.hexToField(recipient));
|
|
5026
|
+
const amountBytes = this.bigintToBytes(amount, 8);
|
|
5027
|
+
const txHashBytes = this.hexToBytes(this.hexToField(txHash));
|
|
5028
|
+
const blockBytes = this.bigintToBytes(blockNumber, 8);
|
|
5029
|
+
const preimage = new Uint8Array([
|
|
5030
|
+
...recipientBytes,
|
|
5031
|
+
...amountBytes,
|
|
5032
|
+
...txHashBytes,
|
|
5033
|
+
...blockBytes
|
|
5034
|
+
]);
|
|
5035
|
+
const hash2 = sha25611(preimage);
|
|
5036
|
+
return Array.from(hash2);
|
|
5037
|
+
}
|
|
5038
|
+
/**
|
|
5039
|
+
* Derive secp256k1 public key coordinates from a private key
|
|
5040
|
+
*
|
|
5041
|
+
* @param privateKey - 32-byte private key as Uint8Array
|
|
5042
|
+
* @returns X and Y coordinates as 32-byte arrays
|
|
5043
|
+
*/
|
|
5044
|
+
getPublicKeyCoordinates(privateKey) {
|
|
5045
|
+
const uncompressedPubKey = import_secp256k13.secp256k1.getPublicKey(privateKey, false);
|
|
5046
|
+
const x = Array.from(uncompressedPubKey.slice(1, 33));
|
|
5047
|
+
const y = Array.from(uncompressedPubKey.slice(33, 65));
|
|
5048
|
+
return { x, y };
|
|
5049
|
+
}
|
|
5050
|
+
/**
|
|
5051
|
+
* Derive public key coordinates from a field string (private key)
|
|
5052
|
+
*
|
|
5053
|
+
* @param privateKeyField - Private key as hex field string
|
|
5054
|
+
* @returns X and Y coordinates as 32-byte arrays
|
|
5055
|
+
*/
|
|
5056
|
+
getPublicKeyFromField(privateKeyField) {
|
|
5057
|
+
const privateKeyBytes = this.hexToBytes(privateKeyField.padStart(64, "0"));
|
|
5058
|
+
return this.getPublicKeyCoordinates(privateKeyBytes);
|
|
5059
|
+
}
|
|
5060
|
+
};
|
|
5061
|
+
|
|
5062
|
+
// src/proofs/browser-utils.ts
|
|
5063
|
+
function hexToBytes5(hex) {
|
|
5064
|
+
const h = hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
5065
|
+
if (h.length === 0) return new Uint8Array(0);
|
|
5066
|
+
if (h.length % 2 !== 0) {
|
|
5067
|
+
throw new Error("Hex string must have even length");
|
|
5068
|
+
}
|
|
5069
|
+
const bytes = new Uint8Array(h.length / 2);
|
|
5070
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
5071
|
+
bytes[i] = parseInt(h.slice(i * 2, i * 2 + 2), 16);
|
|
5072
|
+
}
|
|
5073
|
+
return bytes;
|
|
5074
|
+
}
|
|
5075
|
+
function bytesToHex7(bytes) {
|
|
5076
|
+
return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
5077
|
+
}
|
|
5078
|
+
function isBrowser() {
|
|
5079
|
+
return typeof window !== "undefined" && typeof window.document !== "undefined";
|
|
5080
|
+
}
|
|
5081
|
+
function supportsWebWorkers() {
|
|
5082
|
+
return typeof Worker !== "undefined";
|
|
5083
|
+
}
|
|
5084
|
+
function supportsSharedArrayBuffer() {
|
|
5085
|
+
try {
|
|
5086
|
+
return typeof SharedArrayBuffer !== "undefined";
|
|
5087
|
+
} catch {
|
|
5088
|
+
return false;
|
|
5089
|
+
}
|
|
5090
|
+
}
|
|
5091
|
+
function getBrowserInfo() {
|
|
5092
|
+
return {
|
|
5093
|
+
isBrowser: isBrowser(),
|
|
5094
|
+
supportsWorkers: supportsWebWorkers(),
|
|
5095
|
+
supportsSharedArrayBuffer: supportsSharedArrayBuffer(),
|
|
5096
|
+
userAgent: typeof navigator !== "undefined" ? navigator.userAgent : null
|
|
5097
|
+
};
|
|
5098
|
+
}
|
|
5099
|
+
|
|
5100
|
+
// src/proofs/browser.ts
|
|
5101
|
+
var import_noir_js2 = require("@noir-lang/noir_js");
|
|
5102
|
+
var import_bb2 = require("@aztec/bb.js");
|
|
5103
|
+
var import_secp256k14 = require("@noble/curves/secp256k1");
|
|
5104
|
+
var BrowserNoirProvider = class _BrowserNoirProvider {
|
|
5105
|
+
framework = "noir";
|
|
5106
|
+
_isReady = false;
|
|
5107
|
+
config;
|
|
5108
|
+
// Circuit instances
|
|
5109
|
+
fundingNoir = null;
|
|
5110
|
+
fundingBackend = null;
|
|
5111
|
+
validityNoir = null;
|
|
5112
|
+
validityBackend = null;
|
|
5113
|
+
fulfillmentNoir = null;
|
|
5114
|
+
fulfillmentBackend = null;
|
|
5115
|
+
// Worker instance (optional)
|
|
5116
|
+
worker = null;
|
|
5117
|
+
workerPending = /* @__PURE__ */ new Map();
|
|
5118
|
+
constructor(config = {}) {
|
|
5119
|
+
this.config = {
|
|
5120
|
+
useWorker: config.useWorker ?? true,
|
|
5121
|
+
verbose: config.verbose ?? false,
|
|
5122
|
+
oraclePublicKey: config.oraclePublicKey ?? void 0,
|
|
5123
|
+
timeout: config.timeout ?? 6e4
|
|
5124
|
+
};
|
|
5125
|
+
if (!isBrowser()) {
|
|
5126
|
+
console.warn(
|
|
5127
|
+
"[BrowserNoirProvider] Not running in browser environment. Consider using NoirProofProvider for Node.js."
|
|
5128
|
+
);
|
|
5129
|
+
}
|
|
5130
|
+
}
|
|
5131
|
+
get isReady() {
|
|
5132
|
+
return this._isReady;
|
|
5133
|
+
}
|
|
5134
|
+
/**
|
|
5135
|
+
* Get browser environment info
|
|
5136
|
+
*/
|
|
5137
|
+
static getBrowserInfo() {
|
|
5138
|
+
return getBrowserInfo();
|
|
5139
|
+
}
|
|
5140
|
+
/**
|
|
5141
|
+
* Check if browser supports all required features
|
|
5142
|
+
*/
|
|
5143
|
+
static checkBrowserSupport() {
|
|
5144
|
+
const missing = [];
|
|
5145
|
+
if (!isBrowser()) {
|
|
5146
|
+
missing.push("browser environment");
|
|
5147
|
+
}
|
|
5148
|
+
if (typeof WebAssembly === "undefined") {
|
|
5149
|
+
missing.push("WebAssembly");
|
|
5150
|
+
}
|
|
5151
|
+
if (!supportsSharedArrayBuffer()) {
|
|
5152
|
+
missing.push("SharedArrayBuffer (requires COOP/COEP headers)");
|
|
5153
|
+
}
|
|
5154
|
+
return {
|
|
5155
|
+
supported: missing.length === 0,
|
|
5156
|
+
missing
|
|
5157
|
+
};
|
|
5158
|
+
}
|
|
5159
|
+
/**
|
|
5160
|
+
* Derive secp256k1 public key coordinates from a private key
|
|
5161
|
+
*/
|
|
5162
|
+
static derivePublicKey(privateKey) {
|
|
5163
|
+
const uncompressedPubKey = import_secp256k14.secp256k1.getPublicKey(privateKey, false);
|
|
5164
|
+
const x = Array.from(uncompressedPubKey.slice(1, 33));
|
|
5165
|
+
const y = Array.from(uncompressedPubKey.slice(33, 65));
|
|
5166
|
+
return { x, y };
|
|
5167
|
+
}
|
|
5168
|
+
/**
|
|
5169
|
+
* Initialize the browser provider
|
|
5170
|
+
*
|
|
5171
|
+
* Loads WASM and circuit artifacts. This should be called before any
|
|
5172
|
+
* proof generation. Consider showing a loading indicator during init.
|
|
5173
|
+
*
|
|
5174
|
+
* @param onProgress - Optional progress callback
|
|
5175
|
+
*/
|
|
5176
|
+
async initialize(onProgress) {
|
|
5177
|
+
if (this._isReady) {
|
|
5178
|
+
return;
|
|
5179
|
+
}
|
|
5180
|
+
const { supported, missing } = _BrowserNoirProvider.checkBrowserSupport();
|
|
5181
|
+
if (!supported) {
|
|
5182
|
+
throw new ProofError(
|
|
5183
|
+
`Browser missing required features: ${missing.join(", ")}`,
|
|
5184
|
+
"SIP_4004" /* PROOF_PROVIDER_NOT_READY */
|
|
5185
|
+
);
|
|
5186
|
+
}
|
|
5187
|
+
try {
|
|
5188
|
+
onProgress?.({
|
|
5189
|
+
stage: "initializing",
|
|
5190
|
+
percent: 0,
|
|
5191
|
+
message: "Loading WASM runtime..."
|
|
5192
|
+
});
|
|
5193
|
+
if (this.config.verbose) {
|
|
5194
|
+
console.log("[BrowserNoirProvider] Initializing...");
|
|
5195
|
+
console.log("[BrowserNoirProvider] Browser info:", getBrowserInfo());
|
|
5196
|
+
}
|
|
5197
|
+
const fundingCircuit = funding_proof_default;
|
|
5198
|
+
const validityCircuit = validity_proof_default;
|
|
5199
|
+
const fulfillmentCircuit = fulfillment_proof_default;
|
|
5200
|
+
onProgress?.({
|
|
5201
|
+
stage: "initializing",
|
|
5202
|
+
percent: 20,
|
|
5203
|
+
message: "Creating proof backends..."
|
|
5204
|
+
});
|
|
5205
|
+
this.fundingBackend = new import_bb2.UltraHonkBackend(fundingCircuit.bytecode);
|
|
5206
|
+
this.validityBackend = new import_bb2.UltraHonkBackend(validityCircuit.bytecode);
|
|
5207
|
+
this.fulfillmentBackend = new import_bb2.UltraHonkBackend(fulfillmentCircuit.bytecode);
|
|
5208
|
+
onProgress?.({
|
|
5209
|
+
stage: "initializing",
|
|
5210
|
+
percent: 60,
|
|
5211
|
+
message: "Initializing Noir circuits..."
|
|
5212
|
+
});
|
|
5213
|
+
this.fundingNoir = new import_noir_js2.Noir(fundingCircuit);
|
|
5214
|
+
this.validityNoir = new import_noir_js2.Noir(validityCircuit);
|
|
5215
|
+
this.fulfillmentNoir = new import_noir_js2.Noir(fulfillmentCircuit);
|
|
5216
|
+
onProgress?.({
|
|
5217
|
+
stage: "initializing",
|
|
5218
|
+
percent: 90,
|
|
5219
|
+
message: "Setting up worker..."
|
|
5220
|
+
});
|
|
5221
|
+
if (this.config.useWorker && supportsWebWorkers()) {
|
|
5222
|
+
await this.initializeWorker();
|
|
5223
|
+
}
|
|
5224
|
+
this._isReady = true;
|
|
5225
|
+
onProgress?.({
|
|
5226
|
+
stage: "complete",
|
|
5227
|
+
percent: 100,
|
|
5228
|
+
message: "Ready for proof generation"
|
|
5229
|
+
});
|
|
5230
|
+
if (this.config.verbose) {
|
|
5231
|
+
console.log("[BrowserNoirProvider] Initialization complete");
|
|
5232
|
+
}
|
|
5233
|
+
} catch (error) {
|
|
5234
|
+
throw new ProofError(
|
|
5235
|
+
`Failed to initialize BrowserNoirProvider: ${error instanceof Error ? error.message : String(error)}`,
|
|
5236
|
+
"SIP_4003" /* PROOF_NOT_IMPLEMENTED */,
|
|
5237
|
+
{ context: { error } }
|
|
5238
|
+
);
|
|
5239
|
+
}
|
|
5240
|
+
}
|
|
5241
|
+
/**
|
|
5242
|
+
* Initialize Web Worker for off-main-thread proof generation
|
|
5243
|
+
*/
|
|
5244
|
+
async initializeWorker() {
|
|
5245
|
+
if (this.config.verbose) {
|
|
5246
|
+
console.log("[BrowserNoirProvider] Worker support: using async main-thread");
|
|
5247
|
+
}
|
|
5248
|
+
}
|
|
5249
|
+
/**
|
|
5250
|
+
* Generate a Funding Proof
|
|
5251
|
+
*
|
|
5252
|
+
* Proves: balance >= minimumRequired without revealing balance
|
|
5253
|
+
*
|
|
5254
|
+
* @param params - Funding proof parameters
|
|
5255
|
+
* @param onProgress - Optional progress callback
|
|
5256
|
+
*/
|
|
5257
|
+
async generateFundingProof(params, onProgress) {
|
|
5258
|
+
this.ensureReady();
|
|
5259
|
+
if (!this.fundingNoir || !this.fundingBackend) {
|
|
5260
|
+
throw new ProofGenerationError("funding", "Funding circuit not initialized");
|
|
5261
|
+
}
|
|
5262
|
+
try {
|
|
5263
|
+
onProgress?.({
|
|
5264
|
+
stage: "witness",
|
|
5265
|
+
percent: 10,
|
|
5266
|
+
message: "Preparing witness inputs..."
|
|
5267
|
+
});
|
|
5268
|
+
const { commitmentHash, blindingField } = await this.computeCommitmentHash(
|
|
5269
|
+
params.balance,
|
|
5270
|
+
params.blindingFactor,
|
|
5271
|
+
params.assetId
|
|
5272
|
+
);
|
|
5273
|
+
const witnessInputs = {
|
|
5274
|
+
commitment_hash: commitmentHash,
|
|
5275
|
+
minimum_required: params.minimumRequired.toString(),
|
|
5276
|
+
asset_id: this.assetIdToField(params.assetId),
|
|
5277
|
+
balance: params.balance.toString(),
|
|
5278
|
+
blinding: blindingField
|
|
5279
|
+
};
|
|
5280
|
+
onProgress?.({
|
|
5281
|
+
stage: "witness",
|
|
5282
|
+
percent: 30,
|
|
5283
|
+
message: "Generating witness..."
|
|
5284
|
+
});
|
|
5285
|
+
const { witness } = await this.fundingNoir.execute(witnessInputs);
|
|
5286
|
+
onProgress?.({
|
|
5287
|
+
stage: "proving",
|
|
5288
|
+
percent: 50,
|
|
5289
|
+
message: "Generating proof (this may take a moment)..."
|
|
5290
|
+
});
|
|
5291
|
+
const proofData = await this.fundingBackend.generateProof(witness);
|
|
5292
|
+
onProgress?.({
|
|
5293
|
+
stage: "complete",
|
|
5294
|
+
percent: 100,
|
|
5295
|
+
message: "Proof generated successfully"
|
|
5296
|
+
});
|
|
5297
|
+
const publicInputs = [
|
|
5298
|
+
`0x${commitmentHash}`,
|
|
5299
|
+
`0x${params.minimumRequired.toString(16).padStart(16, "0")}`,
|
|
5300
|
+
`0x${this.assetIdToField(params.assetId)}`
|
|
5301
|
+
];
|
|
5302
|
+
const proof = {
|
|
5303
|
+
type: "funding",
|
|
5304
|
+
proof: `0x${bytesToHex7(proofData.proof)}`,
|
|
5305
|
+
publicInputs
|
|
5306
|
+
};
|
|
5307
|
+
return { proof, publicInputs };
|
|
5308
|
+
} catch (error) {
|
|
5309
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
5310
|
+
throw new ProofGenerationError(
|
|
5311
|
+
"funding",
|
|
5312
|
+
`Failed to generate funding proof: ${message}`,
|
|
5313
|
+
error instanceof Error ? error : void 0
|
|
5314
|
+
);
|
|
5315
|
+
}
|
|
5316
|
+
}
|
|
5317
|
+
/**
|
|
5318
|
+
* Generate a Validity Proof
|
|
5319
|
+
*
|
|
5320
|
+
* Proves: Intent is authorized by sender without revealing identity
|
|
5321
|
+
*/
|
|
5322
|
+
async generateValidityProof(params, onProgress) {
|
|
5323
|
+
this.ensureReady();
|
|
5324
|
+
if (!this.validityNoir || !this.validityBackend) {
|
|
5325
|
+
throw new ProofGenerationError("validity", "Validity circuit not initialized");
|
|
5326
|
+
}
|
|
5327
|
+
try {
|
|
5328
|
+
onProgress?.({
|
|
5329
|
+
stage: "witness",
|
|
5330
|
+
percent: 10,
|
|
5331
|
+
message: "Preparing validity witness..."
|
|
5332
|
+
});
|
|
5333
|
+
const intentHashField = this.hexToField(params.intentHash);
|
|
5334
|
+
const senderAddressField = this.hexToField(params.senderAddress);
|
|
5335
|
+
const senderBlindingField = this.bytesToField(params.senderBlinding);
|
|
5336
|
+
const senderSecretField = this.bytesToField(params.senderSecret);
|
|
5337
|
+
const nonceField = this.bytesToField(params.nonce);
|
|
5338
|
+
const { commitmentX, commitmentY } = await this.computeSenderCommitment(
|
|
5339
|
+
senderAddressField,
|
|
5340
|
+
senderBlindingField
|
|
5341
|
+
);
|
|
5342
|
+
const nullifier = await this.computeNullifier(senderSecretField, intentHashField, nonceField);
|
|
5343
|
+
const signature = Array.from(params.authorizationSignature);
|
|
5344
|
+
const messageHash = this.fieldToBytes32(intentHashField);
|
|
5345
|
+
let pubKeyX;
|
|
5346
|
+
let pubKeyY;
|
|
5347
|
+
if (params.senderPublicKey) {
|
|
5348
|
+
pubKeyX = Array.from(params.senderPublicKey.x);
|
|
5349
|
+
pubKeyY = Array.from(params.senderPublicKey.y);
|
|
5350
|
+
} else {
|
|
5351
|
+
const coords = this.getPublicKeyCoordinates(params.senderSecret);
|
|
5352
|
+
pubKeyX = coords.x;
|
|
5353
|
+
pubKeyY = coords.y;
|
|
5354
|
+
}
|
|
5355
|
+
const witnessInputs = {
|
|
5356
|
+
intent_hash: intentHashField,
|
|
5357
|
+
sender_commitment_x: commitmentX,
|
|
5358
|
+
sender_commitment_y: commitmentY,
|
|
5359
|
+
nullifier,
|
|
5360
|
+
timestamp: params.timestamp.toString(),
|
|
5361
|
+
expiry: params.expiry.toString(),
|
|
5362
|
+
sender_address: senderAddressField,
|
|
5363
|
+
sender_blinding: senderBlindingField,
|
|
5364
|
+
sender_secret: senderSecretField,
|
|
5365
|
+
pub_key_x: pubKeyX,
|
|
5366
|
+
pub_key_y: pubKeyY,
|
|
5367
|
+
signature,
|
|
5368
|
+
message_hash: messageHash,
|
|
5369
|
+
nonce: nonceField
|
|
5370
|
+
};
|
|
5371
|
+
onProgress?.({
|
|
5372
|
+
stage: "witness",
|
|
5373
|
+
percent: 30,
|
|
5374
|
+
message: "Generating witness..."
|
|
5375
|
+
});
|
|
5376
|
+
const { witness } = await this.validityNoir.execute(witnessInputs);
|
|
5377
|
+
onProgress?.({
|
|
5378
|
+
stage: "proving",
|
|
5379
|
+
percent: 50,
|
|
5380
|
+
message: "Generating validity proof..."
|
|
5381
|
+
});
|
|
5382
|
+
const proofData = await this.validityBackend.generateProof(witness);
|
|
5383
|
+
onProgress?.({
|
|
5384
|
+
stage: "complete",
|
|
5385
|
+
percent: 100,
|
|
5386
|
+
message: "Validity proof generated"
|
|
5387
|
+
});
|
|
5388
|
+
const publicInputs = [
|
|
5389
|
+
`0x${intentHashField}`,
|
|
5390
|
+
`0x${commitmentX}`,
|
|
5391
|
+
`0x${commitmentY}`,
|
|
5392
|
+
`0x${nullifier}`,
|
|
5393
|
+
`0x${params.timestamp.toString(16).padStart(16, "0")}`,
|
|
5394
|
+
`0x${params.expiry.toString(16).padStart(16, "0")}`
|
|
5395
|
+
];
|
|
5396
|
+
const proof = {
|
|
5397
|
+
type: "validity",
|
|
5398
|
+
proof: `0x${bytesToHex7(proofData.proof)}`,
|
|
5399
|
+
publicInputs
|
|
5400
|
+
};
|
|
5401
|
+
return { proof, publicInputs };
|
|
5402
|
+
} catch (error) {
|
|
5403
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
5404
|
+
throw new ProofGenerationError(
|
|
5405
|
+
"validity",
|
|
5406
|
+
`Failed to generate validity proof: ${message}`,
|
|
5407
|
+
error instanceof Error ? error : void 0
|
|
5408
|
+
);
|
|
5409
|
+
}
|
|
5410
|
+
}
|
|
5411
|
+
/**
|
|
5412
|
+
* Generate a Fulfillment Proof
|
|
5413
|
+
*
|
|
5414
|
+
* Proves: Solver correctly executed the intent
|
|
5415
|
+
*/
|
|
5416
|
+
async generateFulfillmentProof(params, onProgress) {
|
|
5417
|
+
this.ensureReady();
|
|
5418
|
+
if (!this.fulfillmentNoir || !this.fulfillmentBackend) {
|
|
5419
|
+
throw new ProofGenerationError("fulfillment", "Fulfillment circuit not initialized");
|
|
5420
|
+
}
|
|
5421
|
+
try {
|
|
5422
|
+
onProgress?.({
|
|
5423
|
+
stage: "witness",
|
|
5424
|
+
percent: 10,
|
|
5425
|
+
message: "Preparing fulfillment witness..."
|
|
5426
|
+
});
|
|
5427
|
+
const intentHashField = this.hexToField(params.intentHash);
|
|
5428
|
+
const recipientStealthField = this.hexToField(params.recipientStealth);
|
|
5429
|
+
const { commitmentX, commitmentY } = await this.computeOutputCommitment(
|
|
5430
|
+
params.outputAmount,
|
|
5431
|
+
params.outputBlinding
|
|
5432
|
+
);
|
|
5433
|
+
const solverSecretField = this.bytesToField(params.solverSecret);
|
|
5434
|
+
const solverId = await this.computeSolverId(solverSecretField);
|
|
5435
|
+
const outputBlindingField = this.bytesToField(params.outputBlinding);
|
|
5436
|
+
const attestation = params.oracleAttestation;
|
|
5437
|
+
const attestationRecipientField = this.hexToField(attestation.recipient);
|
|
5438
|
+
const attestationTxHashField = this.hexToField(attestation.txHash);
|
|
5439
|
+
const oracleSignature = Array.from(attestation.signature);
|
|
5440
|
+
const oracleMessageHash = await this.computeOracleMessageHash(
|
|
5441
|
+
attestation.recipient,
|
|
5442
|
+
attestation.amount,
|
|
5443
|
+
attestation.txHash,
|
|
5444
|
+
attestation.blockNumber
|
|
5445
|
+
);
|
|
5446
|
+
const oraclePubKeyX = this.config.oraclePublicKey?.x ?? new Array(32).fill(0);
|
|
5447
|
+
const oraclePubKeyY = this.config.oraclePublicKey?.y ?? new Array(32).fill(0);
|
|
5448
|
+
const witnessInputs = {
|
|
5449
|
+
intent_hash: intentHashField,
|
|
5450
|
+
output_commitment_x: commitmentX,
|
|
5451
|
+
output_commitment_y: commitmentY,
|
|
5452
|
+
recipient_stealth: recipientStealthField,
|
|
5453
|
+
min_output_amount: params.minOutputAmount.toString(),
|
|
5454
|
+
solver_id: solverId,
|
|
5455
|
+
fulfillment_time: params.fulfillmentTime.toString(),
|
|
5456
|
+
expiry: params.expiry.toString(),
|
|
5457
|
+
output_amount: params.outputAmount.toString(),
|
|
5458
|
+
output_blinding: outputBlindingField,
|
|
5459
|
+
solver_secret: solverSecretField,
|
|
5460
|
+
attestation_recipient: attestationRecipientField,
|
|
5461
|
+
attestation_amount: attestation.amount.toString(),
|
|
5462
|
+
attestation_tx_hash: attestationTxHashField,
|
|
5463
|
+
attestation_block: attestation.blockNumber.toString(),
|
|
5464
|
+
oracle_signature: oracleSignature,
|
|
5465
|
+
oracle_message_hash: oracleMessageHash,
|
|
5466
|
+
oracle_pub_key_x: oraclePubKeyX,
|
|
5467
|
+
oracle_pub_key_y: oraclePubKeyY
|
|
5468
|
+
};
|
|
5469
|
+
onProgress?.({
|
|
5470
|
+
stage: "witness",
|
|
5471
|
+
percent: 30,
|
|
5472
|
+
message: "Generating witness..."
|
|
5473
|
+
});
|
|
5474
|
+
const { witness } = await this.fulfillmentNoir.execute(witnessInputs);
|
|
5475
|
+
onProgress?.({
|
|
5476
|
+
stage: "proving",
|
|
5477
|
+
percent: 50,
|
|
5478
|
+
message: "Generating fulfillment proof..."
|
|
5479
|
+
});
|
|
5480
|
+
const proofData = await this.fulfillmentBackend.generateProof(witness);
|
|
5481
|
+
onProgress?.({
|
|
5482
|
+
stage: "complete",
|
|
5483
|
+
percent: 100,
|
|
5484
|
+
message: "Fulfillment proof generated"
|
|
5485
|
+
});
|
|
5486
|
+
const publicInputs = [
|
|
5487
|
+
`0x${intentHashField}`,
|
|
5488
|
+
`0x${commitmentX}`,
|
|
5489
|
+
`0x${commitmentY}`,
|
|
5490
|
+
`0x${recipientStealthField}`,
|
|
5491
|
+
`0x${params.minOutputAmount.toString(16).padStart(16, "0")}`,
|
|
5492
|
+
`0x${solverId}`,
|
|
5493
|
+
`0x${params.fulfillmentTime.toString(16).padStart(16, "0")}`,
|
|
5494
|
+
`0x${params.expiry.toString(16).padStart(16, "0")}`
|
|
5495
|
+
];
|
|
5496
|
+
const proof = {
|
|
5497
|
+
type: "fulfillment",
|
|
5498
|
+
proof: `0x${bytesToHex7(proofData.proof)}`,
|
|
5499
|
+
publicInputs
|
|
5500
|
+
};
|
|
5501
|
+
return { proof, publicInputs };
|
|
5502
|
+
} catch (error) {
|
|
5503
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
5504
|
+
throw new ProofGenerationError(
|
|
5505
|
+
"fulfillment",
|
|
5506
|
+
`Failed to generate fulfillment proof: ${message}`,
|
|
5507
|
+
error instanceof Error ? error : void 0
|
|
5508
|
+
);
|
|
5509
|
+
}
|
|
5510
|
+
}
|
|
5511
|
+
/**
|
|
5512
|
+
* Verify a proof
|
|
5513
|
+
*/
|
|
5514
|
+
async verifyProof(proof) {
|
|
5515
|
+
this.ensureReady();
|
|
5516
|
+
let backend = null;
|
|
5517
|
+
switch (proof.type) {
|
|
5518
|
+
case "funding":
|
|
5519
|
+
backend = this.fundingBackend;
|
|
5520
|
+
break;
|
|
5521
|
+
case "validity":
|
|
5522
|
+
backend = this.validityBackend;
|
|
5523
|
+
break;
|
|
5524
|
+
case "fulfillment":
|
|
5525
|
+
backend = this.fulfillmentBackend;
|
|
5526
|
+
break;
|
|
5527
|
+
default:
|
|
5528
|
+
throw new ProofError(`Unknown proof type: ${proof.type}`, "SIP_4003" /* PROOF_NOT_IMPLEMENTED */);
|
|
5529
|
+
}
|
|
5530
|
+
if (!backend) {
|
|
5531
|
+
throw new ProofError(
|
|
5532
|
+
`${proof.type} backend not initialized`,
|
|
5533
|
+
"SIP_4004" /* PROOF_PROVIDER_NOT_READY */
|
|
5534
|
+
);
|
|
5535
|
+
}
|
|
5536
|
+
try {
|
|
5537
|
+
const proofHex = proof.proof.startsWith("0x") ? proof.proof.slice(2) : proof.proof;
|
|
5538
|
+
const proofBytes = hexToBytes5(proofHex);
|
|
4286
5539
|
const isValid = await backend.verifyProof({
|
|
4287
5540
|
proof: proofBytes,
|
|
4288
5541
|
publicInputs: proof.publicInputs.map(
|
|
@@ -4292,7 +5545,7 @@ var NoirProofProvider = class {
|
|
|
4292
5545
|
return isValid;
|
|
4293
5546
|
} catch (error) {
|
|
4294
5547
|
if (this.config.verbose) {
|
|
4295
|
-
console.error("[
|
|
5548
|
+
console.error("[BrowserNoirProvider] Verification error:", error);
|
|
4296
5549
|
}
|
|
4297
5550
|
return false;
|
|
4298
5551
|
}
|
|
@@ -4313,52 +5566,37 @@ var NoirProofProvider = class {
|
|
|
4313
5566
|
await this.fulfillmentBackend.destroy();
|
|
4314
5567
|
this.fulfillmentBackend = null;
|
|
4315
5568
|
}
|
|
5569
|
+
if (this.worker) {
|
|
5570
|
+
this.worker.terminate();
|
|
5571
|
+
this.worker = null;
|
|
5572
|
+
}
|
|
4316
5573
|
this.fundingNoir = null;
|
|
4317
5574
|
this.validityNoir = null;
|
|
4318
5575
|
this.fulfillmentNoir = null;
|
|
4319
5576
|
this._isReady = false;
|
|
4320
5577
|
}
|
|
4321
|
-
// ─── Private Methods
|
|
5578
|
+
// ─── Private Utility Methods ────────────────────────────────────────────────
|
|
4322
5579
|
ensureReady() {
|
|
4323
5580
|
if (!this._isReady) {
|
|
4324
5581
|
throw new ProofError(
|
|
4325
|
-
"
|
|
5582
|
+
"BrowserNoirProvider not initialized. Call initialize() first.",
|
|
4326
5583
|
"SIP_4004" /* PROOF_PROVIDER_NOT_READY */
|
|
4327
5584
|
);
|
|
4328
5585
|
}
|
|
4329
5586
|
}
|
|
4330
|
-
/**
|
|
4331
|
-
* Compute the commitment hash that the circuit expects
|
|
4332
|
-
*
|
|
4333
|
-
* The circuit computes:
|
|
4334
|
-
* 1. commitment = pedersen_commitment([balance, blinding])
|
|
4335
|
-
* 2. commitment_hash = pedersen_hash([commitment.x, commitment.y, asset_id])
|
|
4336
|
-
*
|
|
4337
|
-
* We need to compute this outside to pass as a public input.
|
|
4338
|
-
*
|
|
4339
|
-
* **IMPORTANT**: This SDK uses SHA256 as a deterministic stand-in for Pedersen hash.
|
|
4340
|
-
* Both the SDK and circuit MUST use the same hash function. The bundled circuit
|
|
4341
|
-
* artifacts are configured to use SHA256 for compatibility. If you use custom
|
|
4342
|
-
* circuits with actual Pedersen hashing, you must update this implementation.
|
|
4343
|
-
*
|
|
4344
|
-
* @see docs/specs/HASH-COMPATIBILITY.md for hash function requirements
|
|
4345
|
-
*/
|
|
4346
5587
|
async computeCommitmentHash(balance, blindingFactor, assetId) {
|
|
4347
5588
|
const blindingField = this.bytesToField(blindingFactor);
|
|
4348
|
-
const { sha256:
|
|
4349
|
-
const { bytesToHex:
|
|
5589
|
+
const { sha256: sha25611 } = await import("@noble/hashes/sha256");
|
|
5590
|
+
const { bytesToHex: nobleToHex } = await import("@noble/hashes/utils");
|
|
4350
5591
|
const preimage = new Uint8Array([
|
|
4351
5592
|
...this.bigintToBytes(balance, 8),
|
|
4352
5593
|
...blindingFactor.slice(0, 32),
|
|
4353
|
-
...
|
|
5594
|
+
...hexToBytes5(this.assetIdToField(assetId))
|
|
4354
5595
|
]);
|
|
4355
|
-
const hash2 =
|
|
4356
|
-
const commitmentHash =
|
|
5596
|
+
const hash2 = sha25611(preimage);
|
|
5597
|
+
const commitmentHash = nobleToHex(hash2);
|
|
4357
5598
|
return { commitmentHash, blindingField };
|
|
4358
5599
|
}
|
|
4359
|
-
/**
|
|
4360
|
-
* Convert asset ID to field element
|
|
4361
|
-
*/
|
|
4362
5600
|
assetIdToField(assetId) {
|
|
4363
5601
|
if (assetId.startsWith("0x")) {
|
|
4364
5602
|
return assetId.slice(2).padStart(64, "0");
|
|
@@ -4371,9 +5609,6 @@ var NoirProofProvider = class {
|
|
|
4371
5609
|
}
|
|
4372
5610
|
return result.toString(16).padStart(64, "0");
|
|
4373
5611
|
}
|
|
4374
|
-
/**
|
|
4375
|
-
* Convert bytes to field element string
|
|
4376
|
-
*/
|
|
4377
5612
|
bytesToField(bytes) {
|
|
4378
5613
|
let result = 0n;
|
|
4379
5614
|
const len = Math.min(bytes.length, 31);
|
|
@@ -4382,9 +5617,6 @@ var NoirProofProvider = class {
|
|
|
4382
5617
|
}
|
|
4383
5618
|
return result.toString();
|
|
4384
5619
|
}
|
|
4385
|
-
/**
|
|
4386
|
-
* Convert bigint to bytes
|
|
4387
|
-
*/
|
|
4388
5620
|
bigintToBytes(value, length) {
|
|
4389
5621
|
const bytes = new Uint8Array(length);
|
|
4390
5622
|
let v = value;
|
|
@@ -4394,27 +5626,10 @@ var NoirProofProvider = class {
|
|
|
4394
5626
|
}
|
|
4395
5627
|
return bytes;
|
|
4396
5628
|
}
|
|
4397
|
-
/**
|
|
4398
|
-
* Convert hex string to bytes
|
|
4399
|
-
*/
|
|
4400
|
-
hexToBytes(hex) {
|
|
4401
|
-
const h = hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
4402
|
-
const bytes = new Uint8Array(h.length / 2);
|
|
4403
|
-
for (let i = 0; i < bytes.length; i++) {
|
|
4404
|
-
bytes[i] = parseInt(h.slice(i * 2, i * 2 + 2), 16);
|
|
4405
|
-
}
|
|
4406
|
-
return bytes;
|
|
4407
|
-
}
|
|
4408
|
-
/**
|
|
4409
|
-
* Convert hex string to field element string
|
|
4410
|
-
*/
|
|
4411
5629
|
hexToField(hex) {
|
|
4412
5630
|
const h = hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
4413
5631
|
return h.padStart(64, "0");
|
|
4414
5632
|
}
|
|
4415
|
-
/**
|
|
4416
|
-
* Convert field string to 32-byte array
|
|
4417
|
-
*/
|
|
4418
5633
|
fieldToBytes32(field) {
|
|
4419
5634
|
const hex = field.padStart(64, "0");
|
|
4420
5635
|
const bytes = [];
|
|
@@ -4423,87 +5638,50 @@ var NoirProofProvider = class {
|
|
|
4423
5638
|
}
|
|
4424
5639
|
return bytes;
|
|
4425
5640
|
}
|
|
4426
|
-
/**
|
|
4427
|
-
* Compute sender commitment for validity proof
|
|
4428
|
-
*
|
|
4429
|
-
* Uses SHA256 for SDK-side computation. The bundled circuit artifacts
|
|
4430
|
-
* are compiled to use SHA256 for compatibility with this SDK.
|
|
4431
|
-
*
|
|
4432
|
-
* @see computeCommitmentHash for hash function compatibility notes
|
|
4433
|
-
*/
|
|
4434
5641
|
async computeSenderCommitment(senderAddressField, senderBlindingField) {
|
|
4435
|
-
const { sha256:
|
|
4436
|
-
const { bytesToHex:
|
|
4437
|
-
const addressBytes =
|
|
4438
|
-
const blindingBytes =
|
|
5642
|
+
const { sha256: sha25611 } = await import("@noble/hashes/sha256");
|
|
5643
|
+
const { bytesToHex: nobleToHex } = await import("@noble/hashes/utils");
|
|
5644
|
+
const addressBytes = hexToBytes5(senderAddressField);
|
|
5645
|
+
const blindingBytes = hexToBytes5(senderBlindingField.padStart(64, "0"));
|
|
4439
5646
|
const preimage = new Uint8Array([...addressBytes, ...blindingBytes]);
|
|
4440
|
-
const hash2 =
|
|
4441
|
-
const commitmentX =
|
|
4442
|
-
const commitmentY =
|
|
5647
|
+
const hash2 = sha25611(preimage);
|
|
5648
|
+
const commitmentX = nobleToHex(hash2.slice(0, 16)).padStart(64, "0");
|
|
5649
|
+
const commitmentY = nobleToHex(hash2.slice(16, 32)).padStart(64, "0");
|
|
4443
5650
|
return { commitmentX, commitmentY };
|
|
4444
5651
|
}
|
|
4445
|
-
/**
|
|
4446
|
-
* Compute nullifier for validity proof
|
|
4447
|
-
*
|
|
4448
|
-
* Uses SHA256 for SDK-side computation. The bundled circuit artifacts
|
|
4449
|
-
* are compiled to use SHA256 for compatibility with this SDK.
|
|
4450
|
-
*
|
|
4451
|
-
* @see computeCommitmentHash for hash function compatibility notes
|
|
4452
|
-
*/
|
|
4453
5652
|
async computeNullifier(senderSecretField, intentHashField, nonceField) {
|
|
4454
|
-
const { sha256:
|
|
4455
|
-
const { bytesToHex:
|
|
4456
|
-
const secretBytes =
|
|
4457
|
-
const intentBytes =
|
|
4458
|
-
const nonceBytes =
|
|
5653
|
+
const { sha256: sha25611 } = await import("@noble/hashes/sha256");
|
|
5654
|
+
const { bytesToHex: nobleToHex } = await import("@noble/hashes/utils");
|
|
5655
|
+
const secretBytes = hexToBytes5(senderSecretField.padStart(64, "0"));
|
|
5656
|
+
const intentBytes = hexToBytes5(intentHashField);
|
|
5657
|
+
const nonceBytes = hexToBytes5(nonceField.padStart(64, "0"));
|
|
4459
5658
|
const preimage = new Uint8Array([...secretBytes, ...intentBytes, ...nonceBytes]);
|
|
4460
|
-
const hash2 =
|
|
4461
|
-
return
|
|
5659
|
+
const hash2 = sha25611(preimage);
|
|
5660
|
+
return nobleToHex(hash2);
|
|
4462
5661
|
}
|
|
4463
|
-
/**
|
|
4464
|
-
* Compute output commitment for fulfillment proof
|
|
4465
|
-
*
|
|
4466
|
-
* Uses SHA256 for SDK-side computation. The bundled circuit artifacts
|
|
4467
|
-
* are compiled to use SHA256 for compatibility with this SDK.
|
|
4468
|
-
*
|
|
4469
|
-
* @see computeCommitmentHash for hash function compatibility notes
|
|
4470
|
-
*/
|
|
4471
5662
|
async computeOutputCommitment(outputAmount, outputBlinding) {
|
|
4472
|
-
const { sha256:
|
|
4473
|
-
const { bytesToHex:
|
|
5663
|
+
const { sha256: sha25611 } = await import("@noble/hashes/sha256");
|
|
5664
|
+
const { bytesToHex: nobleToHex } = await import("@noble/hashes/utils");
|
|
4474
5665
|
const amountBytes = this.bigintToBytes(outputAmount, 8);
|
|
4475
5666
|
const blindingBytes = outputBlinding.slice(0, 32);
|
|
4476
5667
|
const preimage = new Uint8Array([...amountBytes, ...blindingBytes]);
|
|
4477
|
-
const hash2 =
|
|
4478
|
-
const commitmentX =
|
|
4479
|
-
const commitmentY =
|
|
5668
|
+
const hash2 = sha25611(preimage);
|
|
5669
|
+
const commitmentX = nobleToHex(hash2.slice(0, 16)).padStart(64, "0");
|
|
5670
|
+
const commitmentY = nobleToHex(hash2.slice(16, 32)).padStart(64, "0");
|
|
4480
5671
|
return { commitmentX, commitmentY };
|
|
4481
5672
|
}
|
|
4482
|
-
/**
|
|
4483
|
-
* Compute solver ID from solver secret
|
|
4484
|
-
*
|
|
4485
|
-
* Uses SHA256 for SDK-side computation. The bundled circuit artifacts
|
|
4486
|
-
* are compiled to use SHA256 for compatibility with this SDK.
|
|
4487
|
-
*
|
|
4488
|
-
* @see computeCommitmentHash for hash function compatibility notes
|
|
4489
|
-
*/
|
|
4490
5673
|
async computeSolverId(solverSecretField) {
|
|
4491
|
-
const { sha256:
|
|
4492
|
-
const { bytesToHex:
|
|
4493
|
-
const secretBytes =
|
|
4494
|
-
const hash2 =
|
|
4495
|
-
return
|
|
5674
|
+
const { sha256: sha25611 } = await import("@noble/hashes/sha256");
|
|
5675
|
+
const { bytesToHex: nobleToHex } = await import("@noble/hashes/utils");
|
|
5676
|
+
const secretBytes = hexToBytes5(solverSecretField.padStart(64, "0"));
|
|
5677
|
+
const hash2 = sha25611(secretBytes);
|
|
5678
|
+
return nobleToHex(hash2);
|
|
4496
5679
|
}
|
|
4497
|
-
/**
|
|
4498
|
-
* Compute oracle message hash for fulfillment proof
|
|
4499
|
-
*
|
|
4500
|
-
* Hash of attestation data that oracle signs
|
|
4501
|
-
*/
|
|
4502
5680
|
async computeOracleMessageHash(recipient, amount, txHash, blockNumber) {
|
|
4503
|
-
const { sha256:
|
|
4504
|
-
const recipientBytes =
|
|
5681
|
+
const { sha256: sha25611 } = await import("@noble/hashes/sha256");
|
|
5682
|
+
const recipientBytes = hexToBytes5(this.hexToField(recipient));
|
|
4505
5683
|
const amountBytes = this.bigintToBytes(amount, 8);
|
|
4506
|
-
const txHashBytes =
|
|
5684
|
+
const txHashBytes = hexToBytes5(this.hexToField(txHash));
|
|
4507
5685
|
const blockBytes = this.bigintToBytes(blockNumber, 8);
|
|
4508
5686
|
const preimage = new Uint8Array([
|
|
4509
5687
|
...recipientBytes,
|
|
@@ -4511,42 +5689,303 @@ var NoirProofProvider = class {
|
|
|
4511
5689
|
...txHashBytes,
|
|
4512
5690
|
...blockBytes
|
|
4513
5691
|
]);
|
|
4514
|
-
const hash2 =
|
|
5692
|
+
const hash2 = sha25611(preimage);
|
|
4515
5693
|
return Array.from(hash2);
|
|
4516
5694
|
}
|
|
4517
|
-
/**
|
|
4518
|
-
* Derive secp256k1 public key coordinates from a private key
|
|
4519
|
-
*
|
|
4520
|
-
* @param privateKey - 32-byte private key as Uint8Array
|
|
4521
|
-
* @returns X and Y coordinates as 32-byte arrays
|
|
4522
|
-
*/
|
|
4523
5695
|
getPublicKeyCoordinates(privateKey) {
|
|
4524
|
-
const uncompressedPubKey =
|
|
5696
|
+
const uncompressedPubKey = import_secp256k14.secp256k1.getPublicKey(privateKey, false);
|
|
4525
5697
|
const x = Array.from(uncompressedPubKey.slice(1, 33));
|
|
4526
5698
|
const y = Array.from(uncompressedPubKey.slice(33, 65));
|
|
4527
5699
|
return { x, y };
|
|
4528
5700
|
}
|
|
4529
|
-
/**
|
|
4530
|
-
* Derive public key coordinates from a field string (private key)
|
|
4531
|
-
*
|
|
4532
|
-
* @param privateKeyField - Private key as hex field string
|
|
4533
|
-
* @returns X and Y coordinates as 32-byte arrays
|
|
4534
|
-
*/
|
|
4535
|
-
getPublicKeyFromField(privateKeyField) {
|
|
4536
|
-
const privateKeyBytes = this.hexToBytes(privateKeyField.padStart(64, "0"));
|
|
4537
|
-
return this.getPublicKeyCoordinates(privateKeyBytes);
|
|
4538
|
-
}
|
|
4539
5701
|
};
|
|
4540
5702
|
|
|
5703
|
+
// src/oracle/types.ts
|
|
5704
|
+
var ORACLE_DOMAIN = "SIP-ORACLE-ATTESTATION-V1";
|
|
5705
|
+
var ATTESTATION_VERSION = 1;
|
|
5706
|
+
var DEFAULT_THRESHOLD = 3;
|
|
5707
|
+
var DEFAULT_TOTAL_ORACLES = 5;
|
|
5708
|
+
var CHAIN_NUMERIC_IDS = {
|
|
5709
|
+
ethereum: 1,
|
|
5710
|
+
polygon: 137,
|
|
5711
|
+
arbitrum: 42161,
|
|
5712
|
+
optimism: 10,
|
|
5713
|
+
base: 8453,
|
|
5714
|
+
bitcoin: 0,
|
|
5715
|
+
// Non-standard, SIP-specific (Bitcoin mainnet)
|
|
5716
|
+
solana: 501,
|
|
5717
|
+
// Non-standard, SIP-specific
|
|
5718
|
+
near: 502,
|
|
5719
|
+
// Non-standard, SIP-specific
|
|
5720
|
+
zcash: 503
|
|
5721
|
+
// Non-standard, SIP-specific
|
|
5722
|
+
};
|
|
5723
|
+
|
|
5724
|
+
// src/oracle/verification.ts
|
|
5725
|
+
var import_ed255192 = require("@noble/curves/ed25519");
|
|
5726
|
+
var import_sha2568 = require("@noble/hashes/sha256");
|
|
5727
|
+
var import_utils9 = require("@noble/hashes/utils");
|
|
5728
|
+
|
|
5729
|
+
// src/oracle/serialization.ts
|
|
5730
|
+
var import_sha2567 = require("@noble/hashes/sha256");
|
|
5731
|
+
var import_utils8 = require("@noble/hashes/utils");
|
|
5732
|
+
function serializeAttestationMessage(message) {
|
|
5733
|
+
const buffer = new Uint8Array(197);
|
|
5734
|
+
const view = new DataView(buffer.buffer);
|
|
5735
|
+
let offset = 0;
|
|
5736
|
+
buffer[offset++] = message.version;
|
|
5737
|
+
view.setUint32(offset, message.chainId, false);
|
|
5738
|
+
offset += 4;
|
|
5739
|
+
const intentHashBytes = normalizeToBytes(message.intentHash, 32, "intentHash");
|
|
5740
|
+
buffer.set(intentHashBytes, offset);
|
|
5741
|
+
offset += 32;
|
|
5742
|
+
const recipientBytes = normalizeToBytes(message.recipient, 32, "recipient");
|
|
5743
|
+
buffer.set(recipientBytes, offset);
|
|
5744
|
+
offset += 32;
|
|
5745
|
+
const amountBytes = bigintToBytes(message.amount, 16);
|
|
5746
|
+
buffer.set(amountBytes, offset);
|
|
5747
|
+
offset += 16;
|
|
5748
|
+
const assetIdBytes = normalizeToBytes(message.assetId, 32, "assetId");
|
|
5749
|
+
buffer.set(assetIdBytes, offset);
|
|
5750
|
+
offset += 32;
|
|
5751
|
+
const txHashBytes = normalizeToBytes(message.txHash, 32, "txHash");
|
|
5752
|
+
buffer.set(txHashBytes, offset);
|
|
5753
|
+
offset += 32;
|
|
5754
|
+
view.setBigUint64(offset, message.blockNumber, false);
|
|
5755
|
+
offset += 8;
|
|
5756
|
+
const blockHashBytes = normalizeToBytes(message.blockHash, 32, "blockHash");
|
|
5757
|
+
buffer.set(blockHashBytes, offset);
|
|
5758
|
+
offset += 32;
|
|
5759
|
+
view.setBigUint64(offset, BigInt(message.timestamp), false);
|
|
5760
|
+
return buffer;
|
|
5761
|
+
}
|
|
5762
|
+
function deserializeAttestationMessage(bytes) {
|
|
5763
|
+
if (bytes.length !== 197) {
|
|
5764
|
+
throw new ValidationError(
|
|
5765
|
+
`Invalid attestation message length: ${bytes.length}, expected 197`,
|
|
5766
|
+
"bytes"
|
|
5767
|
+
);
|
|
5768
|
+
}
|
|
5769
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset);
|
|
5770
|
+
let offset = 0;
|
|
5771
|
+
const version = bytes[offset++];
|
|
5772
|
+
const chainId = view.getUint32(offset, false);
|
|
5773
|
+
offset += 4;
|
|
5774
|
+
const intentHash = `0x${(0, import_utils8.bytesToHex)(bytes.slice(offset, offset + 32))}`;
|
|
5775
|
+
offset += 32;
|
|
5776
|
+
const recipient = `0x${(0, import_utils8.bytesToHex)(bytes.slice(offset, offset + 32))}`;
|
|
5777
|
+
offset += 32;
|
|
5778
|
+
const amount = bytesToBigint(bytes.slice(offset, offset + 16));
|
|
5779
|
+
offset += 16;
|
|
5780
|
+
const assetId = `0x${(0, import_utils8.bytesToHex)(bytes.slice(offset, offset + 32))}`;
|
|
5781
|
+
offset += 32;
|
|
5782
|
+
const txHash = `0x${(0, import_utils8.bytesToHex)(bytes.slice(offset, offset + 32))}`;
|
|
5783
|
+
offset += 32;
|
|
5784
|
+
const blockNumber = view.getBigUint64(offset, false);
|
|
5785
|
+
offset += 8;
|
|
5786
|
+
const blockHash = `0x${(0, import_utils8.bytesToHex)(bytes.slice(offset, offset + 32))}`;
|
|
5787
|
+
offset += 32;
|
|
5788
|
+
const timestamp = Number(view.getBigUint64(offset, false));
|
|
5789
|
+
return {
|
|
5790
|
+
version,
|
|
5791
|
+
chainId,
|
|
5792
|
+
intentHash,
|
|
5793
|
+
recipient,
|
|
5794
|
+
amount,
|
|
5795
|
+
assetId,
|
|
5796
|
+
txHash,
|
|
5797
|
+
blockNumber,
|
|
5798
|
+
blockHash,
|
|
5799
|
+
timestamp
|
|
5800
|
+
};
|
|
5801
|
+
}
|
|
5802
|
+
function computeAttestationHash(message) {
|
|
5803
|
+
const domain = (0, import_utils8.utf8ToBytes)(ORACLE_DOMAIN);
|
|
5804
|
+
const messageBytes = serializeAttestationMessage(message);
|
|
5805
|
+
const toHash = new Uint8Array(domain.length + messageBytes.length);
|
|
5806
|
+
toHash.set(domain, 0);
|
|
5807
|
+
toHash.set(messageBytes, domain.length);
|
|
5808
|
+
return (0, import_sha2567.sha256)(toHash);
|
|
5809
|
+
}
|
|
5810
|
+
function getChainNumericId(chain) {
|
|
5811
|
+
const id = CHAIN_NUMERIC_IDS[chain];
|
|
5812
|
+
if (id === void 0) {
|
|
5813
|
+
throw new ValidationError(`Unknown chain: ${chain}`, "chain");
|
|
5814
|
+
}
|
|
5815
|
+
return id;
|
|
5816
|
+
}
|
|
5817
|
+
function normalizeToBytes(hex, length, field) {
|
|
5818
|
+
const stripped = hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
5819
|
+
const bytes = (0, import_utils8.hexToBytes)(stripped);
|
|
5820
|
+
if (bytes.length === length) {
|
|
5821
|
+
return bytes;
|
|
5822
|
+
}
|
|
5823
|
+
if (bytes.length > length) {
|
|
5824
|
+
throw new ValidationError(
|
|
5825
|
+
`${field} is too long: ${bytes.length} bytes, max ${length}`,
|
|
5826
|
+
field
|
|
5827
|
+
);
|
|
5828
|
+
}
|
|
5829
|
+
const padded = new Uint8Array(length);
|
|
5830
|
+
padded.set(bytes, length - bytes.length);
|
|
5831
|
+
return padded;
|
|
5832
|
+
}
|
|
5833
|
+
function bigintToBytes(value, length) {
|
|
5834
|
+
const bytes = new Uint8Array(length);
|
|
5835
|
+
let v = value;
|
|
5836
|
+
for (let i = length - 1; i >= 0; i--) {
|
|
5837
|
+
bytes[i] = Number(v & 0xffn);
|
|
5838
|
+
v >>= 8n;
|
|
5839
|
+
}
|
|
5840
|
+
return bytes;
|
|
5841
|
+
}
|
|
5842
|
+
function bytesToBigint(bytes) {
|
|
5843
|
+
let result = 0n;
|
|
5844
|
+
for (const byte of bytes) {
|
|
5845
|
+
result = (result << 8n) + BigInt(byte);
|
|
5846
|
+
}
|
|
5847
|
+
return result;
|
|
5848
|
+
}
|
|
5849
|
+
|
|
5850
|
+
// src/oracle/verification.ts
|
|
5851
|
+
function deriveOracleId(publicKey) {
|
|
5852
|
+
const keyBytes = typeof publicKey === "string" ? (0, import_utils9.hexToBytes)(publicKey.startsWith("0x") ? publicKey.slice(2) : publicKey) : publicKey;
|
|
5853
|
+
const hash2 = (0, import_sha2568.sha256)(keyBytes);
|
|
5854
|
+
return `0x${(0, import_utils9.bytesToHex)(hash2)}`;
|
|
5855
|
+
}
|
|
5856
|
+
function verifyAttestation(attestation, registry) {
|
|
5857
|
+
const { message, signatures } = attestation;
|
|
5858
|
+
const errors = [];
|
|
5859
|
+
const validOracles = [];
|
|
5860
|
+
if (signatures.length < registry.threshold) {
|
|
5861
|
+
errors.push(
|
|
5862
|
+
`Insufficient signatures: ${signatures.length} < ${registry.threshold} required`
|
|
5863
|
+
);
|
|
5864
|
+
}
|
|
5865
|
+
const messageHash = computeAttestationHash(message);
|
|
5866
|
+
const seenOracles = /* @__PURE__ */ new Set();
|
|
5867
|
+
let validCount = 0;
|
|
5868
|
+
for (const sig of signatures) {
|
|
5869
|
+
if (seenOracles.has(sig.oracleId)) {
|
|
5870
|
+
errors.push(`Duplicate signature from oracle: ${sig.oracleId}`);
|
|
5871
|
+
continue;
|
|
5872
|
+
}
|
|
5873
|
+
seenOracles.add(sig.oracleId);
|
|
5874
|
+
const oracle = registry.oracles.get(sig.oracleId);
|
|
5875
|
+
if (!oracle) {
|
|
5876
|
+
errors.push(`Unknown oracle: ${sig.oracleId}`);
|
|
5877
|
+
continue;
|
|
5878
|
+
}
|
|
5879
|
+
if (oracle.status !== "active") {
|
|
5880
|
+
errors.push(`Oracle not active: ${sig.oracleId} (status: ${oracle.status})`);
|
|
5881
|
+
continue;
|
|
5882
|
+
}
|
|
5883
|
+
try {
|
|
5884
|
+
const publicKeyBytes = (0, import_utils9.hexToBytes)(
|
|
5885
|
+
oracle.publicKey.startsWith("0x") ? oracle.publicKey.slice(2) : oracle.publicKey
|
|
5886
|
+
);
|
|
5887
|
+
const signatureBytes = (0, import_utils9.hexToBytes)(
|
|
5888
|
+
sig.signature.startsWith("0x") ? sig.signature.slice(2) : sig.signature
|
|
5889
|
+
);
|
|
5890
|
+
const isValid = import_ed255192.ed25519.verify(signatureBytes, messageHash, publicKeyBytes);
|
|
5891
|
+
if (isValid) {
|
|
5892
|
+
validCount++;
|
|
5893
|
+
validOracles.push(sig.oracleId);
|
|
5894
|
+
} else {
|
|
5895
|
+
errors.push(`Invalid signature from oracle: ${sig.oracleId}`);
|
|
5896
|
+
}
|
|
5897
|
+
} catch (e) {
|
|
5898
|
+
errors.push(`Signature verification error for ${sig.oracleId}: ${e}`);
|
|
5899
|
+
}
|
|
5900
|
+
}
|
|
5901
|
+
const valid = validCount >= registry.threshold && errors.length === 0;
|
|
5902
|
+
return {
|
|
5903
|
+
valid,
|
|
5904
|
+
validSignatures: validCount,
|
|
5905
|
+
threshold: registry.threshold,
|
|
5906
|
+
validOracles,
|
|
5907
|
+
errors: errors.length > 0 ? errors : void 0
|
|
5908
|
+
};
|
|
5909
|
+
}
|
|
5910
|
+
function verifyOracleSignature(signature, messageHash, oracle) {
|
|
5911
|
+
try {
|
|
5912
|
+
const publicKeyBytes = (0, import_utils9.hexToBytes)(
|
|
5913
|
+
oracle.publicKey.startsWith("0x") ? oracle.publicKey.slice(2) : oracle.publicKey
|
|
5914
|
+
);
|
|
5915
|
+
const signatureBytes = (0, import_utils9.hexToBytes)(
|
|
5916
|
+
signature.signature.startsWith("0x") ? signature.signature.slice(2) : signature.signature
|
|
5917
|
+
);
|
|
5918
|
+
return import_ed255192.ed25519.verify(signatureBytes, messageHash, publicKeyBytes);
|
|
5919
|
+
} catch {
|
|
5920
|
+
return false;
|
|
5921
|
+
}
|
|
5922
|
+
}
|
|
5923
|
+
function signAttestationMessage(messageHash, privateKey) {
|
|
5924
|
+
const signature = import_ed255192.ed25519.sign(messageHash, privateKey);
|
|
5925
|
+
const publicKey = import_ed255192.ed25519.getPublicKey(privateKey);
|
|
5926
|
+
const oracleId = deriveOracleId(publicKey);
|
|
5927
|
+
return {
|
|
5928
|
+
oracleId,
|
|
5929
|
+
signature: `0x${(0, import_utils9.bytesToHex)(signature)}`
|
|
5930
|
+
};
|
|
5931
|
+
}
|
|
5932
|
+
function createOracleRegistry(config = {}) {
|
|
5933
|
+
const registry = {
|
|
5934
|
+
oracles: /* @__PURE__ */ new Map(),
|
|
5935
|
+
threshold: config.threshold ?? DEFAULT_THRESHOLD,
|
|
5936
|
+
totalOracles: 0,
|
|
5937
|
+
version: 1,
|
|
5938
|
+
lastUpdated: Date.now()
|
|
5939
|
+
};
|
|
5940
|
+
if (config.customOracles) {
|
|
5941
|
+
for (const oracle of config.customOracles) {
|
|
5942
|
+
registry.oracles.set(oracle.id, oracle);
|
|
5943
|
+
}
|
|
5944
|
+
registry.totalOracles = config.customOracles.length;
|
|
5945
|
+
}
|
|
5946
|
+
return registry;
|
|
5947
|
+
}
|
|
5948
|
+
function addOracle(registry, oracle) {
|
|
5949
|
+
registry.oracles.set(oracle.id, oracle);
|
|
5950
|
+
registry.totalOracles = registry.oracles.size;
|
|
5951
|
+
registry.lastUpdated = Date.now();
|
|
5952
|
+
}
|
|
5953
|
+
function removeOracle(registry, oracleId) {
|
|
5954
|
+
const removed = registry.oracles.delete(oracleId);
|
|
5955
|
+
if (removed) {
|
|
5956
|
+
registry.totalOracles = registry.oracles.size;
|
|
5957
|
+
registry.lastUpdated = Date.now();
|
|
5958
|
+
}
|
|
5959
|
+
return removed;
|
|
5960
|
+
}
|
|
5961
|
+
function updateOracleStatus(registry, oracleId, status) {
|
|
5962
|
+
const oracle = registry.oracles.get(oracleId);
|
|
5963
|
+
if (!oracle) {
|
|
5964
|
+
return false;
|
|
5965
|
+
}
|
|
5966
|
+
oracle.status = status;
|
|
5967
|
+
registry.lastUpdated = Date.now();
|
|
5968
|
+
return true;
|
|
5969
|
+
}
|
|
5970
|
+
function getActiveOracles(registry) {
|
|
5971
|
+
return Array.from(registry.oracles.values()).filter(
|
|
5972
|
+
(oracle) => oracle.status === "active"
|
|
5973
|
+
);
|
|
5974
|
+
}
|
|
5975
|
+
function hasEnoughOracles(registry) {
|
|
5976
|
+
const activeCount = getActiveOracles(registry).length;
|
|
5977
|
+
return activeCount >= registry.threshold;
|
|
5978
|
+
}
|
|
5979
|
+
|
|
4541
5980
|
// src/index.ts
|
|
4542
|
-
var import_types31 = require("@sip-protocol/types");
|
|
4543
|
-
var import_types32 = require("@sip-protocol/types");
|
|
4544
5981
|
var import_types33 = require("@sip-protocol/types");
|
|
4545
5982
|
var import_types34 = require("@sip-protocol/types");
|
|
5983
|
+
var import_types35 = require("@sip-protocol/types");
|
|
5984
|
+
var import_types36 = require("@sip-protocol/types");
|
|
4546
5985
|
|
|
4547
5986
|
// src/solver/mock-solver.ts
|
|
4548
|
-
var
|
|
4549
|
-
var
|
|
5987
|
+
var import_types7 = require("@sip-protocol/types");
|
|
5988
|
+
var import_utils10 = require("@noble/hashes/utils");
|
|
4550
5989
|
var MockSolver = class {
|
|
4551
5990
|
info;
|
|
4552
5991
|
capabilities;
|
|
@@ -4628,7 +6067,7 @@ var MockSolver = class {
|
|
|
4628
6067
|
const spreadAmount = baseOutput * BigInt(Math.floor(this.spreadPercent * 1e4)) / 10000n;
|
|
4629
6068
|
const outputAmount = baseOutput + spreadAmount;
|
|
4630
6069
|
const feeAmount = outputAmount * BigInt(Math.floor(this.feePercent * 1e4)) / 10000n;
|
|
4631
|
-
const quoteId = `quote-${(0,
|
|
6070
|
+
const quoteId = `quote-${(0, import_utils10.bytesToHex)((0, import_utils10.randomBytes)(8))}`;
|
|
4632
6071
|
const now = Math.floor(Date.now() / 1e3);
|
|
4633
6072
|
const quote = {
|
|
4634
6073
|
quoteId,
|
|
@@ -4639,7 +6078,7 @@ var MockSolver = class {
|
|
|
4639
6078
|
expiry: now + 60,
|
|
4640
6079
|
// Quote valid for 1 minute
|
|
4641
6080
|
fee: feeAmount,
|
|
4642
|
-
signature: `0x${(0,
|
|
6081
|
+
signature: `0x${(0, import_utils10.bytesToHex)((0, import_utils10.randomBytes)(64))}`,
|
|
4643
6082
|
// Mock signature
|
|
4644
6083
|
validUntil: now + 60,
|
|
4645
6084
|
estimatedGas: 200000n
|
|
@@ -4671,25 +6110,25 @@ var MockSolver = class {
|
|
|
4671
6110
|
status.error = "Simulated failure for testing";
|
|
4672
6111
|
return {
|
|
4673
6112
|
intentId: intent.intentId,
|
|
4674
|
-
status:
|
|
6113
|
+
status: import_types7.IntentStatus.FAILED,
|
|
4675
6114
|
fulfilledAt: Math.floor(Date.now() / 1e3),
|
|
4676
6115
|
error: status.error
|
|
4677
6116
|
};
|
|
4678
6117
|
}
|
|
4679
|
-
const txHash = `0x${(0,
|
|
6118
|
+
const txHash = `0x${(0, import_utils10.bytesToHex)((0, import_utils10.randomBytes)(32))}`;
|
|
4680
6119
|
status.status = "completed";
|
|
4681
6120
|
status.txHash = txHash;
|
|
4682
6121
|
return {
|
|
4683
6122
|
intentId: intent.intentId,
|
|
4684
|
-
status:
|
|
6123
|
+
status: import_types7.IntentStatus.FULFILLED,
|
|
4685
6124
|
outputAmount: quote.outputAmount,
|
|
4686
6125
|
txHash: intent.privacyLevel === "transparent" ? txHash : void 0,
|
|
4687
6126
|
fulfillmentProof: {
|
|
4688
6127
|
type: "fulfillment",
|
|
4689
|
-
proof: `0x${(0,
|
|
6128
|
+
proof: `0x${(0, import_utils10.bytesToHex)((0, import_utils10.randomBytes)(128))}`,
|
|
4690
6129
|
publicInputs: [
|
|
4691
|
-
`0x${(0,
|
|
4692
|
-
`0x${(0,
|
|
6130
|
+
`0x${(0, import_utils10.bytesToHex)(new TextEncoder().encode(intent.intentId))}`,
|
|
6131
|
+
`0x${(0, import_utils10.bytesToHex)(new TextEncoder().encode(quote.quoteId))}`
|
|
4693
6132
|
]
|
|
4694
6133
|
},
|
|
4695
6134
|
fulfilledAt: Math.floor(Date.now() / 1e3)
|
|
@@ -4727,10 +6166,10 @@ function createMockSolver(config) {
|
|
|
4727
6166
|
}
|
|
4728
6167
|
|
|
4729
6168
|
// src/index.ts
|
|
4730
|
-
var
|
|
6169
|
+
var import_types37 = require("@sip-protocol/types");
|
|
4731
6170
|
|
|
4732
6171
|
// src/zcash/rpc-client.ts
|
|
4733
|
-
var
|
|
6172
|
+
var import_types8 = require("@sip-protocol/types");
|
|
4734
6173
|
var DEFAULT_CONFIG = {
|
|
4735
6174
|
host: "127.0.0.1",
|
|
4736
6175
|
port: 8232,
|
|
@@ -4750,19 +6189,19 @@ var ZcashRPCError = class extends Error {
|
|
|
4750
6189
|
* Check if error is due to insufficient funds
|
|
4751
6190
|
*/
|
|
4752
6191
|
isInsufficientFunds() {
|
|
4753
|
-
return this.code ===
|
|
6192
|
+
return this.code === import_types8.ZcashErrorCode.WALLET_INSUFFICIENT_FUNDS;
|
|
4754
6193
|
}
|
|
4755
6194
|
/**
|
|
4756
6195
|
* Check if error is due to invalid address
|
|
4757
6196
|
*/
|
|
4758
6197
|
isInvalidAddress() {
|
|
4759
|
-
return this.code ===
|
|
6198
|
+
return this.code === import_types8.ZcashErrorCode.INVALID_ADDRESS_OR_KEY;
|
|
4760
6199
|
}
|
|
4761
6200
|
/**
|
|
4762
6201
|
* Check if error is due to wallet being locked
|
|
4763
6202
|
*/
|
|
4764
6203
|
isWalletLocked() {
|
|
4765
|
-
return this.code ===
|
|
6204
|
+
return this.code === import_types8.ZcashErrorCode.WALLET_UNLOCK_NEEDED;
|
|
4766
6205
|
}
|
|
4767
6206
|
};
|
|
4768
6207
|
var ZcashRPCClient = class {
|
|
@@ -5149,7 +6588,7 @@ function createZcashClient(config) {
|
|
|
5149
6588
|
}
|
|
5150
6589
|
|
|
5151
6590
|
// src/zcash/shielded-service.ts
|
|
5152
|
-
var
|
|
6591
|
+
var import_types9 = require("@sip-protocol/types");
|
|
5153
6592
|
var ZcashShieldedService = class _ZcashShieldedService {
|
|
5154
6593
|
client;
|
|
5155
6594
|
config;
|
|
@@ -5335,7 +6774,7 @@ var ZcashShieldedService = class _ZcashShieldedService {
|
|
|
5335
6774
|
* Higher-level method that handles privacy level mapping.
|
|
5336
6775
|
*/
|
|
5337
6776
|
async sendWithPrivacy(to, amount, privacyLevel, memo) {
|
|
5338
|
-
if (privacyLevel ===
|
|
6777
|
+
if (privacyLevel === import_types9.PrivacyLevel.TRANSPARENT) {
|
|
5339
6778
|
throw new ValidationError(
|
|
5340
6779
|
"Transparent mode not supported for Zcash shielded service. Use standard RPC client.",
|
|
5341
6780
|
"privacyLevel",
|
|
@@ -5429,7 +6868,7 @@ var ZcashShieldedService = class _ZcashShieldedService {
|
|
|
5429
6868
|
const viewingKey = await this.exportViewingKey();
|
|
5430
6869
|
return {
|
|
5431
6870
|
viewingKey,
|
|
5432
|
-
privacyLevel:
|
|
6871
|
+
privacyLevel: import_types9.PrivacyLevel.COMPLIANT,
|
|
5433
6872
|
disclaimer: "This viewing key provides read-only access to transaction history. It cannot be used to spend funds. Share only with authorized auditors."
|
|
5434
6873
|
};
|
|
5435
6874
|
}
|
|
@@ -5515,11 +6954,11 @@ var ZcashShieldedService = class _ZcashShieldedService {
|
|
|
5515
6954
|
*/
|
|
5516
6955
|
mapPrivacyLevelToPolicy(level) {
|
|
5517
6956
|
switch (level) {
|
|
5518
|
-
case
|
|
6957
|
+
case import_types9.PrivacyLevel.TRANSPARENT:
|
|
5519
6958
|
return "NoPrivacy";
|
|
5520
|
-
case
|
|
6959
|
+
case import_types9.PrivacyLevel.SHIELDED:
|
|
5521
6960
|
return "FullPrivacy";
|
|
5522
|
-
case
|
|
6961
|
+
case import_types9.PrivacyLevel.COMPLIANT:
|
|
5523
6962
|
return "FullPrivacy";
|
|
5524
6963
|
default:
|
|
5525
6964
|
return "FullPrivacy";
|
|
@@ -5572,15 +7011,15 @@ function createZcashShieldedService(config) {
|
|
|
5572
7011
|
}
|
|
5573
7012
|
|
|
5574
7013
|
// src/zcash/index.ts
|
|
5575
|
-
var
|
|
7014
|
+
var import_types10 = require("@sip-protocol/types");
|
|
5576
7015
|
|
|
5577
7016
|
// src/index.ts
|
|
5578
|
-
var
|
|
7017
|
+
var import_types38 = require("@sip-protocol/types");
|
|
5579
7018
|
|
|
5580
7019
|
// src/payment/payment.ts
|
|
5581
|
-
var
|
|
5582
|
-
var
|
|
5583
|
-
var
|
|
7020
|
+
var import_types11 = require("@sip-protocol/types");
|
|
7021
|
+
var import_sha2569 = require("@noble/hashes/sha256");
|
|
7022
|
+
var import_utils11 = require("@noble/hashes/utils");
|
|
5584
7023
|
var import_chacha2 = require("@noble/ciphers/chacha.js");
|
|
5585
7024
|
var import_hkdf2 = require("@noble/hashes/hkdf");
|
|
5586
7025
|
|
|
@@ -5765,7 +7204,7 @@ var PaymentBuilder = class {
|
|
|
5765
7204
|
_amount;
|
|
5766
7205
|
_recipientMetaAddress;
|
|
5767
7206
|
_recipientAddress;
|
|
5768
|
-
_privacy =
|
|
7207
|
+
_privacy = import_types11.PrivacyLevel.SHIELDED;
|
|
5769
7208
|
_viewingKey;
|
|
5770
7209
|
_sourceChain;
|
|
5771
7210
|
_destinationChain;
|
|
@@ -6048,7 +7487,7 @@ async function createShieldedPayment(params, options) {
|
|
|
6048
7487
|
} else {
|
|
6049
7488
|
resolvedToken = token;
|
|
6050
7489
|
}
|
|
6051
|
-
if (privacy !==
|
|
7490
|
+
if (privacy !== import_types11.PrivacyLevel.TRANSPARENT && !recipientMetaAddress) {
|
|
6052
7491
|
throw new ValidationError(
|
|
6053
7492
|
"recipientMetaAddress is required for shielded/compliant privacy modes",
|
|
6054
7493
|
"recipientMetaAddress",
|
|
@@ -6056,7 +7495,7 @@ async function createShieldedPayment(params, options) {
|
|
|
6056
7495
|
"SIP_2008" /* MISSING_REQUIRED */
|
|
6057
7496
|
);
|
|
6058
7497
|
}
|
|
6059
|
-
if (privacy ===
|
|
7498
|
+
if (privacy === import_types11.PrivacyLevel.TRANSPARENT && !recipientAddress) {
|
|
6060
7499
|
throw new ValidationError(
|
|
6061
7500
|
"recipientAddress is required for transparent mode",
|
|
6062
7501
|
"recipientAddress",
|
|
@@ -6064,7 +7503,7 @@ async function createShieldedPayment(params, options) {
|
|
|
6064
7503
|
"SIP_2008" /* MISSING_REQUIRED */
|
|
6065
7504
|
);
|
|
6066
7505
|
}
|
|
6067
|
-
if (privacy ===
|
|
7506
|
+
if (privacy === import_types11.PrivacyLevel.COMPLIANT && !viewingKey) {
|
|
6068
7507
|
throw new ValidationError(
|
|
6069
7508
|
"viewingKey is required for compliant mode",
|
|
6070
7509
|
"viewingKey",
|
|
@@ -6076,8 +7515,8 @@ async function createShieldedPayment(params, options) {
|
|
|
6076
7515
|
let viewingKeyHash;
|
|
6077
7516
|
if (viewingKey) {
|
|
6078
7517
|
const keyHex = viewingKey.startsWith("0x") ? viewingKey.slice(2) : viewingKey;
|
|
6079
|
-
const keyBytes = (0,
|
|
6080
|
-
viewingKeyHash = `0x${(0,
|
|
7518
|
+
const keyBytes = (0, import_utils11.hexToBytes)(keyHex);
|
|
7519
|
+
viewingKeyHash = `0x${(0, import_utils11.bytesToHex)((0, import_sha2569.sha256)(keyBytes))}`;
|
|
6081
7520
|
}
|
|
6082
7521
|
const privacyConfig = getPrivacyConfig(
|
|
6083
7522
|
privacy,
|
|
@@ -6086,7 +7525,7 @@ async function createShieldedPayment(params, options) {
|
|
|
6086
7525
|
const now = Math.floor(Date.now() / 1e3);
|
|
6087
7526
|
const payment = {
|
|
6088
7527
|
paymentId,
|
|
6089
|
-
version:
|
|
7528
|
+
version: import_types11.SIP_VERSION,
|
|
6090
7529
|
privacyLevel: privacy,
|
|
6091
7530
|
createdAt: now,
|
|
6092
7531
|
expiry: now + ttl,
|
|
@@ -6097,7 +7536,7 @@ async function createShieldedPayment(params, options) {
|
|
|
6097
7536
|
purpose,
|
|
6098
7537
|
viewingKeyHash
|
|
6099
7538
|
};
|
|
6100
|
-
if (privacy !==
|
|
7539
|
+
if (privacy !== import_types11.PrivacyLevel.TRANSPARENT && recipientMetaAddress) {
|
|
6101
7540
|
const metaAddress = decodeStealthMetaAddress(recipientMetaAddress);
|
|
6102
7541
|
const { stealthAddress } = generateStealthAddress(metaAddress);
|
|
6103
7542
|
payment.recipientStealth = stealthAddress;
|
|
@@ -6114,10 +7553,10 @@ async function createShieldedPayment(params, options) {
|
|
|
6114
7553
|
payment.recipientAddress = recipientAddress;
|
|
6115
7554
|
payment.memo = memo;
|
|
6116
7555
|
}
|
|
6117
|
-
if (privacy !==
|
|
7556
|
+
if (privacy !== import_types11.PrivacyLevel.TRANSPARENT && proofProvider?.isReady) {
|
|
6118
7557
|
const hexToUint8 = (hex) => {
|
|
6119
7558
|
const cleanHex = hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
6120
|
-
return (0,
|
|
7559
|
+
return (0, import_utils11.hexToBytes)(cleanHex);
|
|
6121
7560
|
};
|
|
6122
7561
|
const fundingResult = await proofProvider.generateFundingProof({
|
|
6123
7562
|
balance: amount,
|
|
@@ -6144,17 +7583,17 @@ async function createShieldedPayment(params, options) {
|
|
|
6144
7583
|
}
|
|
6145
7584
|
function encryptMemo(memo, viewingKey) {
|
|
6146
7585
|
const keyHex = viewingKey.startsWith("0x") ? viewingKey.slice(2) : viewingKey;
|
|
6147
|
-
const keyBytes = (0,
|
|
6148
|
-
const encKey = (0, import_hkdf2.hkdf)(
|
|
7586
|
+
const keyBytes = (0, import_utils11.hexToBytes)(keyHex);
|
|
7587
|
+
const encKey = (0, import_hkdf2.hkdf)(import_sha2569.sha256, keyBytes, new Uint8Array(0), new Uint8Array(0), 32);
|
|
6149
7588
|
try {
|
|
6150
|
-
const nonce = (0,
|
|
7589
|
+
const nonce = (0, import_utils11.randomBytes)(24);
|
|
6151
7590
|
const cipher = (0, import_chacha2.xchacha20poly1305)(encKey, nonce);
|
|
6152
7591
|
const plaintext = new TextEncoder().encode(memo);
|
|
6153
7592
|
const ciphertext = cipher.encrypt(plaintext);
|
|
6154
7593
|
const result = new Uint8Array(nonce.length + ciphertext.length);
|
|
6155
7594
|
result.set(nonce);
|
|
6156
7595
|
result.set(ciphertext, nonce.length);
|
|
6157
|
-
return `0x${(0,
|
|
7596
|
+
return `0x${(0, import_utils11.bytesToHex)(result)}`;
|
|
6158
7597
|
} finally {
|
|
6159
7598
|
secureWipe(keyBytes);
|
|
6160
7599
|
secureWipe(encKey);
|
|
@@ -6162,11 +7601,11 @@ function encryptMemo(memo, viewingKey) {
|
|
|
6162
7601
|
}
|
|
6163
7602
|
function decryptMemo(encryptedMemo, viewingKey) {
|
|
6164
7603
|
const keyHex = viewingKey.startsWith("0x") ? viewingKey.slice(2) : viewingKey;
|
|
6165
|
-
const keyBytes = (0,
|
|
6166
|
-
const encKey = (0, import_hkdf2.hkdf)(
|
|
7604
|
+
const keyBytes = (0, import_utils11.hexToBytes)(keyHex);
|
|
7605
|
+
const encKey = (0, import_hkdf2.hkdf)(import_sha2569.sha256, keyBytes, new Uint8Array(0), new Uint8Array(0), 32);
|
|
6167
7606
|
try {
|
|
6168
7607
|
const dataHex = encryptedMemo.startsWith("0x") ? encryptedMemo.slice(2) : encryptedMemo;
|
|
6169
|
-
const data = (0,
|
|
7608
|
+
const data = (0, import_utils11.hexToBytes)(dataHex);
|
|
6170
7609
|
const nonce = data.slice(0, 24);
|
|
6171
7610
|
const ciphertext = data.slice(24);
|
|
6172
7611
|
const cipher = (0, import_chacha2.xchacha20poly1305)(encKey, nonce);
|
|
@@ -6180,7 +7619,7 @@ function decryptMemo(encryptedMemo, viewingKey) {
|
|
|
6180
7619
|
function trackPayment(payment) {
|
|
6181
7620
|
return {
|
|
6182
7621
|
...payment,
|
|
6183
|
-
status:
|
|
7622
|
+
status: import_types11.PaymentStatus.DRAFT
|
|
6184
7623
|
};
|
|
6185
7624
|
}
|
|
6186
7625
|
function isPaymentExpired(payment) {
|
|
@@ -6213,10 +7652,10 @@ function getPaymentSummary(payment) {
|
|
|
6213
7652
|
}
|
|
6214
7653
|
|
|
6215
7654
|
// src/treasury/treasury.ts
|
|
6216
|
-
var
|
|
6217
|
-
var
|
|
6218
|
-
var
|
|
6219
|
-
var
|
|
7655
|
+
var import_types12 = require("@sip-protocol/types");
|
|
7656
|
+
var import_secp256k15 = require("@noble/curves/secp256k1");
|
|
7657
|
+
var import_sha25610 = require("@noble/hashes/sha256");
|
|
7658
|
+
var import_utils12 = require("@noble/hashes/utils");
|
|
6220
7659
|
var DEFAULT_PROPOSAL_TTL = 7 * 24 * 60 * 60;
|
|
6221
7660
|
var Treasury = class _Treasury {
|
|
6222
7661
|
config;
|
|
@@ -6246,7 +7685,7 @@ var Treasury = class _Treasury {
|
|
|
6246
7685
|
...m,
|
|
6247
7686
|
addedAt: now
|
|
6248
7687
|
})),
|
|
6249
|
-
defaultPrivacy: params.defaultPrivacy ??
|
|
7688
|
+
defaultPrivacy: params.defaultPrivacy ?? import_types12.PrivacyLevel.SHIELDED,
|
|
6250
7689
|
masterViewingKey,
|
|
6251
7690
|
dailyLimit: params.dailyLimit,
|
|
6252
7691
|
transactionLimit: params.transactionLimit,
|
|
@@ -6325,7 +7764,7 @@ var Treasury = class _Treasury {
|
|
|
6325
7764
|
proposalId,
|
|
6326
7765
|
treasuryId: this.config.treasuryId,
|
|
6327
7766
|
type: "payment",
|
|
6328
|
-
status:
|
|
7767
|
+
status: import_types12.ProposalStatus.PENDING,
|
|
6329
7768
|
proposer: "",
|
|
6330
7769
|
// Should be set by caller
|
|
6331
7770
|
title: params.title,
|
|
@@ -6358,7 +7797,7 @@ var Treasury = class _Treasury {
|
|
|
6358
7797
|
proposalId,
|
|
6359
7798
|
treasuryId: this.config.treasuryId,
|
|
6360
7799
|
type: "batch_payment",
|
|
6361
|
-
status:
|
|
7800
|
+
status: import_types12.ProposalStatus.PENDING,
|
|
6362
7801
|
proposer: "",
|
|
6363
7802
|
title: params.title,
|
|
6364
7803
|
description: params.description,
|
|
@@ -6392,7 +7831,7 @@ var Treasury = class _Treasury {
|
|
|
6392
7831
|
* Get pending proposals
|
|
6393
7832
|
*/
|
|
6394
7833
|
getPendingProposals() {
|
|
6395
|
-
return this.getAllProposals().filter((p) => p.status ===
|
|
7834
|
+
return this.getAllProposals().filter((p) => p.status === import_types12.ProposalStatus.PENDING);
|
|
6396
7835
|
}
|
|
6397
7836
|
/**
|
|
6398
7837
|
* Sign a proposal
|
|
@@ -6423,7 +7862,7 @@ var Treasury = class _Treasury {
|
|
|
6423
7862
|
"SIP_2001" /* INVALID_INPUT */
|
|
6424
7863
|
);
|
|
6425
7864
|
}
|
|
6426
|
-
if (proposal.status !==
|
|
7865
|
+
if (proposal.status !== import_types12.ProposalStatus.PENDING) {
|
|
6427
7866
|
throw new ValidationError(
|
|
6428
7867
|
`proposal is not pending: ${proposal.status}`,
|
|
6429
7868
|
"proposalId",
|
|
@@ -6433,7 +7872,7 @@ var Treasury = class _Treasury {
|
|
|
6433
7872
|
}
|
|
6434
7873
|
const now = Math.floor(Date.now() / 1e3);
|
|
6435
7874
|
if (now > proposal.expiresAt) {
|
|
6436
|
-
proposal.status =
|
|
7875
|
+
proposal.status = import_types12.ProposalStatus.EXPIRED;
|
|
6437
7876
|
throw new ValidationError(
|
|
6438
7877
|
"proposal has expired",
|
|
6439
7878
|
"proposalId",
|
|
@@ -6465,9 +7904,9 @@ var Treasury = class _Treasury {
|
|
|
6465
7904
|
const approvals = proposal.signatures.filter((s) => s.approved).length;
|
|
6466
7905
|
const rejections = proposal.signatures.filter((s) => !s.approved).length;
|
|
6467
7906
|
if (approvals >= proposal.requiredSignatures) {
|
|
6468
|
-
proposal.status =
|
|
7907
|
+
proposal.status = import_types12.ProposalStatus.APPROVED;
|
|
6469
7908
|
} else if (rejections > this.config.totalSigners - proposal.requiredSignatures) {
|
|
6470
|
-
proposal.status =
|
|
7909
|
+
proposal.status = import_types12.ProposalStatus.REJECTED;
|
|
6471
7910
|
}
|
|
6472
7911
|
return proposal;
|
|
6473
7912
|
}
|
|
@@ -6484,7 +7923,7 @@ var Treasury = class _Treasury {
|
|
|
6484
7923
|
"SIP_2001" /* INVALID_INPUT */
|
|
6485
7924
|
);
|
|
6486
7925
|
}
|
|
6487
|
-
if (proposal.status !==
|
|
7926
|
+
if (proposal.status !== import_types12.ProposalStatus.APPROVED) {
|
|
6488
7927
|
throw new ValidationError(
|
|
6489
7928
|
`proposal is not approved: ${proposal.status}`,
|
|
6490
7929
|
"proposalId",
|
|
@@ -6497,8 +7936,8 @@ var Treasury = class _Treasury {
|
|
|
6497
7936
|
const payment = await createShieldedPayment({
|
|
6498
7937
|
token: proposal.payment.token,
|
|
6499
7938
|
amount: proposal.payment.amount,
|
|
6500
|
-
recipientMetaAddress: proposal.payment.privacy !==
|
|
6501
|
-
recipientAddress: proposal.payment.privacy ===
|
|
7939
|
+
recipientMetaAddress: proposal.payment.privacy !== import_types12.PrivacyLevel.TRANSPARENT ? proposal.payment.recipient : void 0,
|
|
7940
|
+
recipientAddress: proposal.payment.privacy === import_types12.PrivacyLevel.TRANSPARENT ? proposal.payment.recipient : void 0,
|
|
6502
7941
|
privacy: proposal.payment.privacy,
|
|
6503
7942
|
viewingKey: this.config.masterViewingKey?.key,
|
|
6504
7943
|
sourceChain: this.config.chain,
|
|
@@ -6511,8 +7950,8 @@ var Treasury = class _Treasury {
|
|
|
6511
7950
|
const payment = await createShieldedPayment({
|
|
6512
7951
|
token: proposal.batchPayment.token,
|
|
6513
7952
|
amount: recipient.amount,
|
|
6514
|
-
recipientMetaAddress: proposal.batchPayment.privacy !==
|
|
6515
|
-
recipientAddress: proposal.batchPayment.privacy ===
|
|
7953
|
+
recipientMetaAddress: proposal.batchPayment.privacy !== import_types12.PrivacyLevel.TRANSPARENT ? recipient.address : void 0,
|
|
7954
|
+
recipientAddress: proposal.batchPayment.privacy === import_types12.PrivacyLevel.TRANSPARENT ? recipient.address : void 0,
|
|
6516
7955
|
privacy: proposal.batchPayment.privacy,
|
|
6517
7956
|
viewingKey: this.config.masterViewingKey?.key,
|
|
6518
7957
|
sourceChain: this.config.chain,
|
|
@@ -6522,7 +7961,7 @@ var Treasury = class _Treasury {
|
|
|
6522
7961
|
payments.push(payment);
|
|
6523
7962
|
}
|
|
6524
7963
|
}
|
|
6525
|
-
proposal.status =
|
|
7964
|
+
proposal.status = import_types12.ProposalStatus.EXECUTED;
|
|
6526
7965
|
proposal.executedAt = Math.floor(Date.now() / 1e3);
|
|
6527
7966
|
proposal.resultPayments = payments;
|
|
6528
7967
|
return payments;
|
|
@@ -6551,7 +7990,7 @@ var Treasury = class _Treasury {
|
|
|
6551
7990
|
"SIP_2001" /* INVALID_INPUT */
|
|
6552
7991
|
);
|
|
6553
7992
|
}
|
|
6554
|
-
if (proposal.status !==
|
|
7993
|
+
if (proposal.status !== import_types12.ProposalStatus.PENDING) {
|
|
6555
7994
|
throw new ValidationError(
|
|
6556
7995
|
`proposal is not pending: ${proposal.status}`,
|
|
6557
7996
|
"proposalId",
|
|
@@ -6559,7 +7998,7 @@ var Treasury = class _Treasury {
|
|
|
6559
7998
|
"SIP_2001" /* INVALID_INPUT */
|
|
6560
7999
|
);
|
|
6561
8000
|
}
|
|
6562
|
-
proposal.status =
|
|
8001
|
+
proposal.status = import_types12.ProposalStatus.CANCELLED;
|
|
6563
8002
|
return proposal;
|
|
6564
8003
|
}
|
|
6565
8004
|
// ─── Auditor Access ──────────────────────────────────────────────────────────
|
|
@@ -6656,7 +8095,7 @@ var Treasury = class _Treasury {
|
|
|
6656
8095
|
getCommittedAmount(token) {
|
|
6657
8096
|
let committed = 0n;
|
|
6658
8097
|
for (const proposal of this.proposals.values()) {
|
|
6659
|
-
if (proposal.status !==
|
|
8098
|
+
if (proposal.status !== import_types12.ProposalStatus.PENDING) continue;
|
|
6660
8099
|
if (proposal.type === "payment" && proposal.payment) {
|
|
6661
8100
|
if (proposal.payment.token.symbol === token.symbol && proposal.payment.token.chain === token.chain) {
|
|
6662
8101
|
committed += proposal.payment.amount;
|
|
@@ -6707,12 +8146,12 @@ var Treasury = class _Treasury {
|
|
|
6707
8146
|
}
|
|
6708
8147
|
};
|
|
6709
8148
|
function generateTreasuryId() {
|
|
6710
|
-
const bytes = (0,
|
|
6711
|
-
return `treasury_${(0,
|
|
8149
|
+
const bytes = (0, import_utils12.randomBytes)(16);
|
|
8150
|
+
return `treasury_${(0, import_utils12.bytesToHex)(bytes)}`;
|
|
6712
8151
|
}
|
|
6713
8152
|
function generateProposalId() {
|
|
6714
|
-
const bytes = (0,
|
|
6715
|
-
return `prop_${(0,
|
|
8153
|
+
const bytes = (0, import_utils12.randomBytes)(16);
|
|
8154
|
+
return `prop_${(0, import_utils12.bytesToHex)(bytes)}`;
|
|
6716
8155
|
}
|
|
6717
8156
|
function computeProposalHash(proposal) {
|
|
6718
8157
|
const data = JSON.stringify({
|
|
@@ -6724,13 +8163,13 @@ function computeProposalHash(proposal) {
|
|
|
6724
8163
|
createdAt: proposal.createdAt,
|
|
6725
8164
|
expiresAt: proposal.expiresAt
|
|
6726
8165
|
}, (_, value) => typeof value === "bigint" ? value.toString() : value);
|
|
6727
|
-
return (0,
|
|
8166
|
+
return (0, import_sha25610.sha256)(new TextEncoder().encode(data));
|
|
6728
8167
|
}
|
|
6729
8168
|
function signMessage(messageHash, privateKey) {
|
|
6730
8169
|
const keyHex = privateKey.startsWith("0x") ? privateKey.slice(2) : privateKey;
|
|
6731
|
-
const keyBytes = (0,
|
|
8170
|
+
const keyBytes = (0, import_utils12.hexToBytes)(keyHex);
|
|
6732
8171
|
try {
|
|
6733
|
-
const signature =
|
|
8172
|
+
const signature = import_secp256k15.secp256k1.sign(messageHash, keyBytes);
|
|
6734
8173
|
return `0x${signature.toCompactHex()}`;
|
|
6735
8174
|
} finally {
|
|
6736
8175
|
secureWipe(keyBytes);
|
|
@@ -6740,9 +8179,9 @@ function verifySignature(messageHash, signature, publicKey) {
|
|
|
6740
8179
|
const sigHex = signature.startsWith("0x") ? signature.slice(2) : signature;
|
|
6741
8180
|
const pubKeyHex = publicKey.startsWith("0x") ? publicKey.slice(2) : publicKey;
|
|
6742
8181
|
try {
|
|
6743
|
-
const sigBytes = (0,
|
|
6744
|
-
const pubKeyBytes = (0,
|
|
6745
|
-
return
|
|
8182
|
+
const sigBytes = (0, import_utils12.hexToBytes)(sigHex);
|
|
8183
|
+
const pubKeyBytes = (0, import_utils12.hexToBytes)(pubKeyHex);
|
|
8184
|
+
return import_secp256k15.secp256k1.verify(sigBytes, messageHash, pubKeyBytes);
|
|
6746
8185
|
} catch {
|
|
6747
8186
|
return false;
|
|
6748
8187
|
}
|
|
@@ -6899,8 +8338,8 @@ function validateBatchProposalParams(params, config) {
|
|
|
6899
8338
|
}
|
|
6900
8339
|
|
|
6901
8340
|
// src/compliance/compliance-manager.ts
|
|
6902
|
-
var
|
|
6903
|
-
var
|
|
8341
|
+
var import_types13 = require("@sip-protocol/types");
|
|
8342
|
+
var import_utils13 = require("@noble/hashes/utils");
|
|
6904
8343
|
var DEFAULTS2 = {
|
|
6905
8344
|
riskThreshold: 70,
|
|
6906
8345
|
highValueThreshold: 10000000000n,
|
|
@@ -7267,7 +8706,7 @@ var ComplianceManager = class _ComplianceManager {
|
|
|
7267
8706
|
title: params.title,
|
|
7268
8707
|
description: params.description,
|
|
7269
8708
|
format: params.format,
|
|
7270
|
-
status:
|
|
8709
|
+
status: import_types13.ReportStatus.GENERATING,
|
|
7271
8710
|
requestedBy,
|
|
7272
8711
|
requestedAt: now,
|
|
7273
8712
|
startDate: params.startDate,
|
|
@@ -7296,10 +8735,10 @@ var ComplianceManager = class _ComplianceManager {
|
|
|
7296
8735
|
} else if (params.format === "csv") {
|
|
7297
8736
|
report.content = this.generateCSV(transactions);
|
|
7298
8737
|
}
|
|
7299
|
-
report.status =
|
|
8738
|
+
report.status = import_types13.ReportStatus.COMPLETED;
|
|
7300
8739
|
report.generatedAt = Math.floor(Date.now() / 1e3);
|
|
7301
8740
|
} catch (error) {
|
|
7302
|
-
report.status =
|
|
8741
|
+
report.status = import_types13.ReportStatus.FAILED;
|
|
7303
8742
|
report.error = error instanceof Error ? error.message : "Unknown error";
|
|
7304
8743
|
}
|
|
7305
8744
|
this.addAuditLog(requestedBy, "report_generated", {
|
|
@@ -7574,7 +9013,7 @@ var ComplianceManager = class _ComplianceManager {
|
|
|
7574
9013
|
}
|
|
7575
9014
|
};
|
|
7576
9015
|
function generateId(prefix) {
|
|
7577
|
-
return `${prefix}_${(0,
|
|
9016
|
+
return `${prefix}_${(0, import_utils13.bytesToHex)((0, import_utils13.randomBytes)(12))}`;
|
|
7578
9017
|
}
|
|
7579
9018
|
function validateRegisterAuditorParams(params) {
|
|
7580
9019
|
if (!params.organization?.trim()) {
|
|
@@ -7662,10 +9101,10 @@ function validateReportParams(params) {
|
|
|
7662
9101
|
}
|
|
7663
9102
|
|
|
7664
9103
|
// src/wallet/errors.ts
|
|
7665
|
-
var
|
|
9104
|
+
var import_types14 = require("@sip-protocol/types");
|
|
7666
9105
|
var WalletError = class extends SIPError {
|
|
7667
9106
|
walletCode;
|
|
7668
|
-
constructor(message, walletCode =
|
|
9107
|
+
constructor(message, walletCode = import_types14.WalletErrorCode.UNKNOWN, options) {
|
|
7669
9108
|
super(message, "SIP_7000" /* WALLET_ERROR */, options);
|
|
7670
9109
|
this.walletCode = walletCode;
|
|
7671
9110
|
this.name = "WalletError";
|
|
@@ -7675,10 +9114,10 @@ var WalletError = class extends SIPError {
|
|
|
7675
9114
|
*/
|
|
7676
9115
|
isConnectionError() {
|
|
7677
9116
|
const codes = [
|
|
7678
|
-
|
|
7679
|
-
|
|
7680
|
-
|
|
7681
|
-
|
|
9117
|
+
import_types14.WalletErrorCode.NOT_INSTALLED,
|
|
9118
|
+
import_types14.WalletErrorCode.CONNECTION_REJECTED,
|
|
9119
|
+
import_types14.WalletErrorCode.CONNECTION_FAILED,
|
|
9120
|
+
import_types14.WalletErrorCode.NOT_CONNECTED
|
|
7682
9121
|
];
|
|
7683
9122
|
return codes.includes(this.walletCode);
|
|
7684
9123
|
}
|
|
@@ -7687,9 +9126,9 @@ var WalletError = class extends SIPError {
|
|
|
7687
9126
|
*/
|
|
7688
9127
|
isSigningError() {
|
|
7689
9128
|
const codes = [
|
|
7690
|
-
|
|
7691
|
-
|
|
7692
|
-
|
|
9129
|
+
import_types14.WalletErrorCode.SIGNING_REJECTED,
|
|
9130
|
+
import_types14.WalletErrorCode.SIGNING_FAILED,
|
|
9131
|
+
import_types14.WalletErrorCode.INVALID_MESSAGE
|
|
7693
9132
|
];
|
|
7694
9133
|
return codes.includes(this.walletCode);
|
|
7695
9134
|
}
|
|
@@ -7698,10 +9137,10 @@ var WalletError = class extends SIPError {
|
|
|
7698
9137
|
*/
|
|
7699
9138
|
isTransactionError() {
|
|
7700
9139
|
const codes = [
|
|
7701
|
-
|
|
7702
|
-
|
|
7703
|
-
|
|
7704
|
-
|
|
9140
|
+
import_types14.WalletErrorCode.INSUFFICIENT_FUNDS,
|
|
9141
|
+
import_types14.WalletErrorCode.TRANSACTION_REJECTED,
|
|
9142
|
+
import_types14.WalletErrorCode.TRANSACTION_FAILED,
|
|
9143
|
+
import_types14.WalletErrorCode.INVALID_TRANSACTION
|
|
7705
9144
|
];
|
|
7706
9145
|
return codes.includes(this.walletCode);
|
|
7707
9146
|
}
|
|
@@ -7710,9 +9149,9 @@ var WalletError = class extends SIPError {
|
|
|
7710
9149
|
*/
|
|
7711
9150
|
isPrivacyError() {
|
|
7712
9151
|
const codes = [
|
|
7713
|
-
|
|
7714
|
-
|
|
7715
|
-
|
|
9152
|
+
import_types14.WalletErrorCode.STEALTH_NOT_SUPPORTED,
|
|
9153
|
+
import_types14.WalletErrorCode.VIEWING_KEY_NOT_SUPPORTED,
|
|
9154
|
+
import_types14.WalletErrorCode.SHIELDED_NOT_SUPPORTED
|
|
7716
9155
|
];
|
|
7717
9156
|
return codes.includes(this.walletCode);
|
|
7718
9157
|
}
|
|
@@ -7721,10 +9160,10 @@ var WalletError = class extends SIPError {
|
|
|
7721
9160
|
*/
|
|
7722
9161
|
isUserRejection() {
|
|
7723
9162
|
const codes = [
|
|
7724
|
-
|
|
7725
|
-
|
|
7726
|
-
|
|
7727
|
-
|
|
9163
|
+
import_types14.WalletErrorCode.CONNECTION_REJECTED,
|
|
9164
|
+
import_types14.WalletErrorCode.SIGNING_REJECTED,
|
|
9165
|
+
import_types14.WalletErrorCode.TRANSACTION_REJECTED,
|
|
9166
|
+
import_types14.WalletErrorCode.CHAIN_SWITCH_REJECTED
|
|
7728
9167
|
];
|
|
7729
9168
|
return codes.includes(this.walletCode);
|
|
7730
9169
|
}
|
|
@@ -7732,15 +9171,15 @@ var WalletError = class extends SIPError {
|
|
|
7732
9171
|
function notConnectedError() {
|
|
7733
9172
|
return new WalletError(
|
|
7734
9173
|
"Wallet not connected. Call connect() first.",
|
|
7735
|
-
|
|
9174
|
+
import_types14.WalletErrorCode.NOT_CONNECTED
|
|
7736
9175
|
);
|
|
7737
9176
|
}
|
|
7738
|
-
function featureNotSupportedError(feature, code =
|
|
9177
|
+
function featureNotSupportedError(feature, code = import_types14.WalletErrorCode.UNKNOWN) {
|
|
7739
9178
|
return new WalletError(`${feature} is not supported by this wallet`, code);
|
|
7740
9179
|
}
|
|
7741
9180
|
|
|
7742
9181
|
// src/wallet/base-adapter.ts
|
|
7743
|
-
var
|
|
9182
|
+
var import_types15 = require("@sip-protocol/types");
|
|
7744
9183
|
var BaseWalletAdapter = class {
|
|
7745
9184
|
_address = "";
|
|
7746
9185
|
_publicKey = "";
|
|
@@ -7903,12 +9342,12 @@ var MockWalletAdapter = class extends BaseWalletAdapter {
|
|
|
7903
9342
|
this._connectionState = "connecting";
|
|
7904
9343
|
if (this.shouldFailConnect) {
|
|
7905
9344
|
this.setError(
|
|
7906
|
-
|
|
9345
|
+
import_types15.WalletErrorCode.CONNECTION_FAILED,
|
|
7907
9346
|
"Mock connection failure"
|
|
7908
9347
|
);
|
|
7909
9348
|
throw new WalletError(
|
|
7910
9349
|
"Mock connection failure",
|
|
7911
|
-
|
|
9350
|
+
import_types15.WalletErrorCode.CONNECTION_FAILED
|
|
7912
9351
|
);
|
|
7913
9352
|
}
|
|
7914
9353
|
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
@@ -7920,7 +9359,7 @@ var MockWalletAdapter = class extends BaseWalletAdapter {
|
|
|
7920
9359
|
async signMessage(message) {
|
|
7921
9360
|
this.requireConnected();
|
|
7922
9361
|
if (this.shouldFailSign) {
|
|
7923
|
-
throw new WalletError("Mock signing failure",
|
|
9362
|
+
throw new WalletError("Mock signing failure", import_types15.WalletErrorCode.SIGNING_FAILED);
|
|
7924
9363
|
}
|
|
7925
9364
|
const mockSig = new Uint8Array(64);
|
|
7926
9365
|
for (let i = 0; i < 64; i++) {
|
|
@@ -7935,7 +9374,7 @@ var MockWalletAdapter = class extends BaseWalletAdapter {
|
|
|
7935
9374
|
async signTransaction(tx) {
|
|
7936
9375
|
this.requireConnected();
|
|
7937
9376
|
if (this.shouldFailSign) {
|
|
7938
|
-
throw new WalletError("Mock signing failure",
|
|
9377
|
+
throw new WalletError("Mock signing failure", import_types15.WalletErrorCode.SIGNING_FAILED);
|
|
7939
9378
|
}
|
|
7940
9379
|
const signature = await this.signMessage(
|
|
7941
9380
|
new TextEncoder().encode(JSON.stringify(tx.data))
|
|
@@ -8117,7 +9556,7 @@ function isPrivateWalletAdapter(adapter) {
|
|
|
8117
9556
|
}
|
|
8118
9557
|
|
|
8119
9558
|
// src/wallet/solana/adapter.ts
|
|
8120
|
-
var
|
|
9559
|
+
var import_types16 = require("@sip-protocol/types");
|
|
8121
9560
|
|
|
8122
9561
|
// src/wallet/solana/types.ts
|
|
8123
9562
|
function getSolanaProvider(wallet = "phantom") {
|
|
@@ -8238,19 +9677,19 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
|
|
|
8238
9677
|
}
|
|
8239
9678
|
if (!this.provider) {
|
|
8240
9679
|
this.setError(
|
|
8241
|
-
|
|
9680
|
+
import_types16.WalletErrorCode.NOT_INSTALLED,
|
|
8242
9681
|
`${this.walletName} wallet is not installed`
|
|
8243
9682
|
);
|
|
8244
9683
|
throw new WalletError(
|
|
8245
9684
|
`${this.walletName} wallet is not installed`,
|
|
8246
|
-
|
|
9685
|
+
import_types16.WalletErrorCode.NOT_INSTALLED
|
|
8247
9686
|
);
|
|
8248
9687
|
}
|
|
8249
9688
|
const { publicKey } = await this.provider.connect();
|
|
8250
9689
|
if (!publicKey) {
|
|
8251
9690
|
throw new WalletError(
|
|
8252
9691
|
"No public key returned from wallet",
|
|
8253
|
-
|
|
9692
|
+
import_types16.WalletErrorCode.CONNECTION_FAILED
|
|
8254
9693
|
);
|
|
8255
9694
|
}
|
|
8256
9695
|
this.setupEventHandlers();
|
|
@@ -8260,11 +9699,11 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
|
|
|
8260
9699
|
} catch (error) {
|
|
8261
9700
|
const message = error instanceof Error ? error.message : "Connection failed";
|
|
8262
9701
|
if (message.includes("User rejected") || message.includes("rejected")) {
|
|
8263
|
-
this.setError(
|
|
8264
|
-
throw new WalletError(message,
|
|
9702
|
+
this.setError(import_types16.WalletErrorCode.CONNECTION_REJECTED, message);
|
|
9703
|
+
throw new WalletError(message, import_types16.WalletErrorCode.CONNECTION_REJECTED);
|
|
8265
9704
|
}
|
|
8266
|
-
this.setError(
|
|
8267
|
-
throw error instanceof WalletError ? error : new WalletError(message,
|
|
9705
|
+
this.setError(import_types16.WalletErrorCode.CONNECTION_FAILED, message);
|
|
9706
|
+
throw error instanceof WalletError ? error : new WalletError(message, import_types16.WalletErrorCode.CONNECTION_FAILED, { cause: error });
|
|
8268
9707
|
}
|
|
8269
9708
|
}
|
|
8270
9709
|
/**
|
|
@@ -8287,7 +9726,7 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
|
|
|
8287
9726
|
async signMessage(message) {
|
|
8288
9727
|
this.requireConnected();
|
|
8289
9728
|
if (!this.provider) {
|
|
8290
|
-
throw new WalletError("Provider not available",
|
|
9729
|
+
throw new WalletError("Provider not available", import_types16.WalletErrorCode.NOT_CONNECTED);
|
|
8291
9730
|
}
|
|
8292
9731
|
try {
|
|
8293
9732
|
const { signature } = await this.provider.signMessage(message);
|
|
@@ -8298,9 +9737,9 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
|
|
|
8298
9737
|
} catch (error) {
|
|
8299
9738
|
const message2 = error instanceof Error ? error.message : "Signing failed";
|
|
8300
9739
|
if (message2.includes("User rejected") || message2.includes("rejected")) {
|
|
8301
|
-
throw new WalletError(message2,
|
|
9740
|
+
throw new WalletError(message2, import_types16.WalletErrorCode.SIGNING_REJECTED);
|
|
8302
9741
|
}
|
|
8303
|
-
throw new WalletError(message2,
|
|
9742
|
+
throw new WalletError(message2, import_types16.WalletErrorCode.SIGNING_FAILED, {
|
|
8304
9743
|
cause: error
|
|
8305
9744
|
});
|
|
8306
9745
|
}
|
|
@@ -8313,7 +9752,7 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
|
|
|
8313
9752
|
async signTransaction(tx) {
|
|
8314
9753
|
this.requireConnected();
|
|
8315
9754
|
if (!this.provider) {
|
|
8316
|
-
throw new WalletError("Provider not available",
|
|
9755
|
+
throw new WalletError("Provider not available", import_types16.WalletErrorCode.NOT_CONNECTED);
|
|
8317
9756
|
}
|
|
8318
9757
|
try {
|
|
8319
9758
|
const solTx = tx.data;
|
|
@@ -8332,9 +9771,9 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
|
|
|
8332
9771
|
} catch (error) {
|
|
8333
9772
|
const message = error instanceof Error ? error.message : "Signing failed";
|
|
8334
9773
|
if (message.includes("User rejected") || message.includes("rejected")) {
|
|
8335
|
-
throw new WalletError(message,
|
|
9774
|
+
throw new WalletError(message, import_types16.WalletErrorCode.SIGNING_REJECTED);
|
|
8336
9775
|
}
|
|
8337
|
-
throw new WalletError(message,
|
|
9776
|
+
throw new WalletError(message, import_types16.WalletErrorCode.SIGNING_FAILED, {
|
|
8338
9777
|
cause: error
|
|
8339
9778
|
});
|
|
8340
9779
|
}
|
|
@@ -8345,7 +9784,7 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
|
|
|
8345
9784
|
async signAndSendTransaction(tx) {
|
|
8346
9785
|
this.requireConnected();
|
|
8347
9786
|
if (!this.provider) {
|
|
8348
|
-
throw new WalletError("Provider not available",
|
|
9787
|
+
throw new WalletError("Provider not available", import_types16.WalletErrorCode.NOT_CONNECTED);
|
|
8349
9788
|
}
|
|
8350
9789
|
try {
|
|
8351
9790
|
const solTx = tx.data;
|
|
@@ -8360,12 +9799,12 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
|
|
|
8360
9799
|
} catch (error) {
|
|
8361
9800
|
const message = error instanceof Error ? error.message : "Transaction failed";
|
|
8362
9801
|
if (message.includes("User rejected") || message.includes("rejected")) {
|
|
8363
|
-
throw new WalletError(message,
|
|
9802
|
+
throw new WalletError(message, import_types16.WalletErrorCode.TRANSACTION_REJECTED);
|
|
8364
9803
|
}
|
|
8365
9804
|
if (message.includes("insufficient") || message.includes("Insufficient")) {
|
|
8366
|
-
throw new WalletError(message,
|
|
9805
|
+
throw new WalletError(message, import_types16.WalletErrorCode.INSUFFICIENT_FUNDS);
|
|
8367
9806
|
}
|
|
8368
|
-
throw new WalletError(message,
|
|
9807
|
+
throw new WalletError(message, import_types16.WalletErrorCode.TRANSACTION_FAILED, {
|
|
8369
9808
|
cause: error
|
|
8370
9809
|
});
|
|
8371
9810
|
}
|
|
@@ -8378,16 +9817,16 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
|
|
|
8378
9817
|
async signAllTransactions(transactions) {
|
|
8379
9818
|
this.requireConnected();
|
|
8380
9819
|
if (!this.provider) {
|
|
8381
|
-
throw new WalletError("Provider not available",
|
|
9820
|
+
throw new WalletError("Provider not available", import_types16.WalletErrorCode.NOT_CONNECTED);
|
|
8382
9821
|
}
|
|
8383
9822
|
try {
|
|
8384
9823
|
return await this.provider.signAllTransactions(transactions);
|
|
8385
9824
|
} catch (error) {
|
|
8386
9825
|
const message = error instanceof Error ? error.message : "Signing failed";
|
|
8387
9826
|
if (message.includes("User rejected") || message.includes("rejected")) {
|
|
8388
|
-
throw new WalletError(message,
|
|
9827
|
+
throw new WalletError(message, import_types16.WalletErrorCode.SIGNING_REJECTED);
|
|
8389
9828
|
}
|
|
8390
|
-
throw new WalletError(message,
|
|
9829
|
+
throw new WalletError(message, import_types16.WalletErrorCode.SIGNING_FAILED, {
|
|
8391
9830
|
cause: error
|
|
8392
9831
|
});
|
|
8393
9832
|
}
|
|
@@ -8408,7 +9847,7 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
|
|
|
8408
9847
|
} catch (error) {
|
|
8409
9848
|
throw new WalletError(
|
|
8410
9849
|
"Failed to get balance",
|
|
8411
|
-
|
|
9850
|
+
import_types16.WalletErrorCode.UNKNOWN,
|
|
8412
9851
|
{ cause: error }
|
|
8413
9852
|
);
|
|
8414
9853
|
}
|
|
@@ -8421,7 +9860,7 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
|
|
|
8421
9860
|
if (asset.chain !== "solana") {
|
|
8422
9861
|
throw new WalletError(
|
|
8423
9862
|
`Asset chain ${asset.chain} not supported by Solana adapter`,
|
|
8424
|
-
|
|
9863
|
+
import_types16.WalletErrorCode.UNSUPPORTED_CHAIN
|
|
8425
9864
|
);
|
|
8426
9865
|
}
|
|
8427
9866
|
if (!asset.address) {
|
|
@@ -8539,7 +9978,7 @@ function createSolanaAdapter(config = {}) {
|
|
|
8539
9978
|
}
|
|
8540
9979
|
|
|
8541
9980
|
// src/wallet/solana/mock.ts
|
|
8542
|
-
var
|
|
9981
|
+
var import_types18 = require("@sip-protocol/types");
|
|
8543
9982
|
var MockPublicKey = class {
|
|
8544
9983
|
base58;
|
|
8545
9984
|
bytes;
|
|
@@ -8605,8 +10044,8 @@ var MockSolanaAdapter = class extends BaseWalletAdapter {
|
|
|
8605
10044
|
this._connectionState = "connecting";
|
|
8606
10045
|
await this.simulateLatency();
|
|
8607
10046
|
if (this.shouldFailConnect) {
|
|
8608
|
-
this.setError(
|
|
8609
|
-
throw new WalletError("Mock connection failure",
|
|
10047
|
+
this.setError(import_types18.WalletErrorCode.CONNECTION_FAILED, "Mock connection failure");
|
|
10048
|
+
throw new WalletError("Mock connection failure", import_types18.WalletErrorCode.CONNECTION_FAILED);
|
|
8610
10049
|
}
|
|
8611
10050
|
const hexPubKey = "0x" + Buffer.from(this.mockPublicKey.toBytes()).toString("hex");
|
|
8612
10051
|
this.setConnected(this.mockAddress, hexPubKey);
|
|
@@ -8625,7 +10064,7 @@ var MockSolanaAdapter = class extends BaseWalletAdapter {
|
|
|
8625
10064
|
this.requireConnected();
|
|
8626
10065
|
await this.simulateLatency();
|
|
8627
10066
|
if (this.shouldFailSign) {
|
|
8628
|
-
throw new WalletError("Mock signing failure",
|
|
10067
|
+
throw new WalletError("Mock signing failure", import_types18.WalletErrorCode.SIGNING_REJECTED);
|
|
8629
10068
|
}
|
|
8630
10069
|
const mockSig = new Uint8Array(64);
|
|
8631
10070
|
for (let i = 0; i < 64; i++) {
|
|
@@ -8643,7 +10082,7 @@ var MockSolanaAdapter = class extends BaseWalletAdapter {
|
|
|
8643
10082
|
this.requireConnected();
|
|
8644
10083
|
await this.simulateLatency();
|
|
8645
10084
|
if (this.shouldFailSign) {
|
|
8646
|
-
throw new WalletError("Mock signing failure",
|
|
10085
|
+
throw new WalletError("Mock signing failure", import_types18.WalletErrorCode.SIGNING_REJECTED);
|
|
8647
10086
|
}
|
|
8648
10087
|
const solTx = tx.data;
|
|
8649
10088
|
this.signedTransactions.push(solTx);
|
|
@@ -8663,10 +10102,10 @@ var MockSolanaAdapter = class extends BaseWalletAdapter {
|
|
|
8663
10102
|
this.requireConnected();
|
|
8664
10103
|
await this.simulateLatency();
|
|
8665
10104
|
if (this.shouldFailSign) {
|
|
8666
|
-
throw new WalletError("Mock signing failure",
|
|
10105
|
+
throw new WalletError("Mock signing failure", import_types18.WalletErrorCode.SIGNING_REJECTED);
|
|
8667
10106
|
}
|
|
8668
10107
|
if (this.shouldFailTransaction) {
|
|
8669
|
-
throw new WalletError("Mock transaction failure",
|
|
10108
|
+
throw new WalletError("Mock transaction failure", import_types18.WalletErrorCode.TRANSACTION_FAILED);
|
|
8670
10109
|
}
|
|
8671
10110
|
const txSig = `mock_tx_${Date.now()}_${Math.random().toString(36).slice(2)}`;
|
|
8672
10111
|
this.sentTransactions.push(txSig);
|
|
@@ -8686,7 +10125,7 @@ var MockSolanaAdapter = class extends BaseWalletAdapter {
|
|
|
8686
10125
|
this.requireConnected();
|
|
8687
10126
|
await this.simulateLatency();
|
|
8688
10127
|
if (this.shouldFailSign) {
|
|
8689
|
-
throw new WalletError("Mock signing failure",
|
|
10128
|
+
throw new WalletError("Mock signing failure", import_types18.WalletErrorCode.SIGNING_REJECTED);
|
|
8690
10129
|
}
|
|
8691
10130
|
this.signedTransactions.push(...transactions);
|
|
8692
10131
|
return transactions.map((tx) => {
|
|
@@ -8713,7 +10152,7 @@ var MockSolanaAdapter = class extends BaseWalletAdapter {
|
|
|
8713
10152
|
if (asset.chain !== "solana") {
|
|
8714
10153
|
throw new WalletError(
|
|
8715
10154
|
`Asset chain ${asset.chain} not supported by Solana adapter`,
|
|
8716
|
-
|
|
10155
|
+
import_types18.WalletErrorCode.UNSUPPORTED_CHAIN
|
|
8717
10156
|
);
|
|
8718
10157
|
}
|
|
8719
10158
|
if (!asset.address) {
|
|
@@ -8882,7 +10321,7 @@ function createMockSolanaAdapter(config = {}) {
|
|
|
8882
10321
|
}
|
|
8883
10322
|
|
|
8884
10323
|
// src/wallet/ethereum/adapter.ts
|
|
8885
|
-
var
|
|
10324
|
+
var import_types20 = require("@sip-protocol/types");
|
|
8886
10325
|
|
|
8887
10326
|
// src/wallet/ethereum/types.ts
|
|
8888
10327
|
var EthereumChainId = {
|
|
@@ -9024,7 +10463,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9024
10463
|
this._connectionState = "error";
|
|
9025
10464
|
throw new WalletError(
|
|
9026
10465
|
`${this.walletType} wallet not found. Please install the extension.`,
|
|
9027
|
-
|
|
10466
|
+
import_types20.WalletErrorCode.NOT_INSTALLED
|
|
9028
10467
|
);
|
|
9029
10468
|
}
|
|
9030
10469
|
const accounts = await this.provider.request({
|
|
@@ -9034,7 +10473,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9034
10473
|
this._connectionState = "error";
|
|
9035
10474
|
throw new WalletError(
|
|
9036
10475
|
"No accounts returned from wallet",
|
|
9037
|
-
|
|
10476
|
+
import_types20.WalletErrorCode.CONNECTION_REJECTED
|
|
9038
10477
|
);
|
|
9039
10478
|
}
|
|
9040
10479
|
const address = normalizeAddress(accounts[0]);
|
|
@@ -9054,12 +10493,12 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9054
10493
|
if (rpcError.code === 4001) {
|
|
9055
10494
|
throw new WalletError(
|
|
9056
10495
|
"User rejected connection request",
|
|
9057
|
-
|
|
10496
|
+
import_types20.WalletErrorCode.CONNECTION_REJECTED
|
|
9058
10497
|
);
|
|
9059
10498
|
}
|
|
9060
10499
|
throw new WalletError(
|
|
9061
10500
|
`Failed to connect: ${rpcError.message || String(error)}`,
|
|
9062
|
-
|
|
10501
|
+
import_types20.WalletErrorCode.CONNECTION_FAILED
|
|
9063
10502
|
);
|
|
9064
10503
|
}
|
|
9065
10504
|
}
|
|
@@ -9079,7 +10518,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9079
10518
|
if (!this.provider) {
|
|
9080
10519
|
throw new WalletError(
|
|
9081
10520
|
"Provider not available",
|
|
9082
|
-
|
|
10521
|
+
import_types20.WalletErrorCode.NOT_CONNECTED
|
|
9083
10522
|
);
|
|
9084
10523
|
}
|
|
9085
10524
|
try {
|
|
@@ -9097,12 +10536,12 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9097
10536
|
if (rpcError.code === 4001) {
|
|
9098
10537
|
throw new WalletError(
|
|
9099
10538
|
"User rejected signing request",
|
|
9100
|
-
|
|
10539
|
+
import_types20.WalletErrorCode.SIGNING_REJECTED
|
|
9101
10540
|
);
|
|
9102
10541
|
}
|
|
9103
10542
|
throw new WalletError(
|
|
9104
10543
|
`Failed to sign message: ${rpcError.message || String(error)}`,
|
|
9105
|
-
|
|
10544
|
+
import_types20.WalletErrorCode.SIGNING_FAILED
|
|
9106
10545
|
);
|
|
9107
10546
|
}
|
|
9108
10547
|
}
|
|
@@ -9114,7 +10553,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9114
10553
|
if (!this.provider) {
|
|
9115
10554
|
throw new WalletError(
|
|
9116
10555
|
"Provider not available",
|
|
9117
|
-
|
|
10556
|
+
import_types20.WalletErrorCode.NOT_CONNECTED
|
|
9118
10557
|
);
|
|
9119
10558
|
}
|
|
9120
10559
|
try {
|
|
@@ -9131,12 +10570,12 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9131
10570
|
if (rpcError.code === 4001) {
|
|
9132
10571
|
throw new WalletError(
|
|
9133
10572
|
"User rejected signing request",
|
|
9134
|
-
|
|
10573
|
+
import_types20.WalletErrorCode.SIGNING_REJECTED
|
|
9135
10574
|
);
|
|
9136
10575
|
}
|
|
9137
10576
|
throw new WalletError(
|
|
9138
10577
|
`Failed to sign typed data: ${rpcError.message || String(error)}`,
|
|
9139
|
-
|
|
10578
|
+
import_types20.WalletErrorCode.SIGNING_FAILED
|
|
9140
10579
|
);
|
|
9141
10580
|
}
|
|
9142
10581
|
}
|
|
@@ -9148,7 +10587,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9148
10587
|
if (!this.provider) {
|
|
9149
10588
|
throw new WalletError(
|
|
9150
10589
|
"Provider not available",
|
|
9151
|
-
|
|
10590
|
+
import_types20.WalletErrorCode.NOT_CONNECTED
|
|
9152
10591
|
);
|
|
9153
10592
|
}
|
|
9154
10593
|
try {
|
|
@@ -9176,7 +10615,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9176
10615
|
if (rpcError.code === 4001) {
|
|
9177
10616
|
throw new WalletError(
|
|
9178
10617
|
"User rejected transaction signing",
|
|
9179
|
-
|
|
10618
|
+
import_types20.WalletErrorCode.SIGNING_REJECTED
|
|
9180
10619
|
);
|
|
9181
10620
|
}
|
|
9182
10621
|
if (rpcError.code === -32601 || rpcError.message?.includes("not supported")) {
|
|
@@ -9194,7 +10633,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9194
10633
|
}
|
|
9195
10634
|
throw new WalletError(
|
|
9196
10635
|
`Failed to sign transaction: ${rpcError.message || String(error)}`,
|
|
9197
|
-
|
|
10636
|
+
import_types20.WalletErrorCode.TRANSACTION_FAILED
|
|
9198
10637
|
);
|
|
9199
10638
|
}
|
|
9200
10639
|
}
|
|
@@ -9206,7 +10645,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9206
10645
|
if (!this.provider) {
|
|
9207
10646
|
throw new WalletError(
|
|
9208
10647
|
"Provider not available",
|
|
9209
|
-
|
|
10648
|
+
import_types20.WalletErrorCode.NOT_CONNECTED
|
|
9210
10649
|
);
|
|
9211
10650
|
}
|
|
9212
10651
|
try {
|
|
@@ -9228,12 +10667,12 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9228
10667
|
if (rpcError.code === 4001) {
|
|
9229
10668
|
throw new WalletError(
|
|
9230
10669
|
"User rejected transaction",
|
|
9231
|
-
|
|
10670
|
+
import_types20.WalletErrorCode.TRANSACTION_REJECTED
|
|
9232
10671
|
);
|
|
9233
10672
|
}
|
|
9234
10673
|
throw new WalletError(
|
|
9235
10674
|
`Failed to send transaction: ${rpcError.message || String(error)}`,
|
|
9236
|
-
|
|
10675
|
+
import_types20.WalletErrorCode.TRANSACTION_FAILED
|
|
9237
10676
|
);
|
|
9238
10677
|
}
|
|
9239
10678
|
}
|
|
@@ -9268,7 +10707,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9268
10707
|
} catch (error) {
|
|
9269
10708
|
throw new WalletError(
|
|
9270
10709
|
`Failed to fetch balance: ${String(error)}`,
|
|
9271
|
-
|
|
10710
|
+
import_types20.WalletErrorCode.UNKNOWN
|
|
9272
10711
|
);
|
|
9273
10712
|
}
|
|
9274
10713
|
}
|
|
@@ -9280,7 +10719,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9280
10719
|
if (asset.chain !== "ethereum") {
|
|
9281
10720
|
throw new WalletError(
|
|
9282
10721
|
`Asset chain ${asset.chain} not supported by Ethereum adapter`,
|
|
9283
|
-
|
|
10722
|
+
import_types20.WalletErrorCode.UNSUPPORTED_CHAIN
|
|
9284
10723
|
);
|
|
9285
10724
|
}
|
|
9286
10725
|
if (!asset.address) {
|
|
@@ -9305,7 +10744,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9305
10744
|
} catch (error) {
|
|
9306
10745
|
throw new WalletError(
|
|
9307
10746
|
`Failed to fetch token balance: ${String(error)}`,
|
|
9308
|
-
|
|
10747
|
+
import_types20.WalletErrorCode.UNKNOWN
|
|
9309
10748
|
);
|
|
9310
10749
|
}
|
|
9311
10750
|
}
|
|
@@ -9317,7 +10756,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9317
10756
|
if (!this.provider) {
|
|
9318
10757
|
throw new WalletError(
|
|
9319
10758
|
"Provider not available",
|
|
9320
|
-
|
|
10759
|
+
import_types20.WalletErrorCode.NOT_CONNECTED
|
|
9321
10760
|
);
|
|
9322
10761
|
}
|
|
9323
10762
|
try {
|
|
@@ -9332,18 +10771,18 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9332
10771
|
if (rpcError.code === 4001) {
|
|
9333
10772
|
throw new WalletError(
|
|
9334
10773
|
"User rejected chain switch",
|
|
9335
|
-
|
|
10774
|
+
import_types20.WalletErrorCode.CHAIN_SWITCH_REJECTED
|
|
9336
10775
|
);
|
|
9337
10776
|
}
|
|
9338
10777
|
if (rpcError.code === 4902) {
|
|
9339
10778
|
throw new WalletError(
|
|
9340
10779
|
`Chain ${chainId} not added to wallet`,
|
|
9341
|
-
|
|
10780
|
+
import_types20.WalletErrorCode.UNSUPPORTED_CHAIN
|
|
9342
10781
|
);
|
|
9343
10782
|
}
|
|
9344
10783
|
throw new WalletError(
|
|
9345
10784
|
`Failed to switch chain: ${rpcError.message || String(error)}`,
|
|
9346
|
-
|
|
10785
|
+
import_types20.WalletErrorCode.CHAIN_SWITCH_FAILED
|
|
9347
10786
|
);
|
|
9348
10787
|
}
|
|
9349
10788
|
}
|
|
@@ -9379,7 +10818,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9379
10818
|
}
|
|
9380
10819
|
throw new WalletError(
|
|
9381
10820
|
`Transaction ${txHash} not confirmed after ${maxAttempts * 5} seconds`,
|
|
9382
|
-
|
|
10821
|
+
import_types20.WalletErrorCode.TRANSACTION_FAILED
|
|
9383
10822
|
);
|
|
9384
10823
|
}
|
|
9385
10824
|
/**
|
|
@@ -9453,7 +10892,7 @@ function createEthereumAdapter(config) {
|
|
|
9453
10892
|
}
|
|
9454
10893
|
|
|
9455
10894
|
// src/wallet/ethereum/mock.ts
|
|
9456
|
-
var
|
|
10895
|
+
var import_types22 = require("@sip-protocol/types");
|
|
9457
10896
|
var MockEthereumAdapter = class extends BaseWalletAdapter {
|
|
9458
10897
|
chain = "ethereum";
|
|
9459
10898
|
name = "mock-ethereum";
|
|
@@ -9494,7 +10933,7 @@ var MockEthereumAdapter = class extends BaseWalletAdapter {
|
|
|
9494
10933
|
this._connectionState = "error";
|
|
9495
10934
|
throw new WalletError(
|
|
9496
10935
|
"Mock connection rejected",
|
|
9497
|
-
|
|
10936
|
+
import_types22.WalletErrorCode.CONNECTION_REJECTED
|
|
9498
10937
|
);
|
|
9499
10938
|
}
|
|
9500
10939
|
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
@@ -9506,7 +10945,7 @@ var MockEthereumAdapter = class extends BaseWalletAdapter {
|
|
|
9506
10945
|
this._connectionState = "error";
|
|
9507
10946
|
throw new WalletError(
|
|
9508
10947
|
`Mock connection failed: ${String(error)}`,
|
|
9509
|
-
|
|
10948
|
+
import_types22.WalletErrorCode.CONNECTION_FAILED
|
|
9510
10949
|
);
|
|
9511
10950
|
}
|
|
9512
10951
|
}
|
|
@@ -9524,7 +10963,7 @@ var MockEthereumAdapter = class extends BaseWalletAdapter {
|
|
|
9524
10963
|
if (this._shouldFailSign) {
|
|
9525
10964
|
throw new WalletError(
|
|
9526
10965
|
"Mock signing rejected",
|
|
9527
|
-
|
|
10966
|
+
import_types22.WalletErrorCode.SIGNING_REJECTED
|
|
9528
10967
|
);
|
|
9529
10968
|
}
|
|
9530
10969
|
const msgHex = Buffer.from(message).toString("hex");
|
|
@@ -9542,7 +10981,7 @@ var MockEthereumAdapter = class extends BaseWalletAdapter {
|
|
|
9542
10981
|
if (this._shouldFailSign) {
|
|
9543
10982
|
throw new WalletError(
|
|
9544
10983
|
"Mock signing rejected",
|
|
9545
|
-
|
|
10984
|
+
import_types22.WalletErrorCode.SIGNING_REJECTED
|
|
9546
10985
|
);
|
|
9547
10986
|
}
|
|
9548
10987
|
const mockSig = `0x${"1".repeat(130)}`;
|
|
@@ -9559,7 +10998,7 @@ var MockEthereumAdapter = class extends BaseWalletAdapter {
|
|
|
9559
10998
|
if (this._shouldFailSign) {
|
|
9560
10999
|
throw new WalletError(
|
|
9561
11000
|
"Mock signing rejected",
|
|
9562
|
-
|
|
11001
|
+
import_types22.WalletErrorCode.SIGNING_REJECTED
|
|
9563
11002
|
);
|
|
9564
11003
|
}
|
|
9565
11004
|
this._signedTransactions.push(tx);
|
|
@@ -9584,7 +11023,7 @@ var MockEthereumAdapter = class extends BaseWalletAdapter {
|
|
|
9584
11023
|
if (this._shouldFailTransaction) {
|
|
9585
11024
|
throw new WalletError(
|
|
9586
11025
|
"Mock transaction failed",
|
|
9587
|
-
|
|
11026
|
+
import_types22.WalletErrorCode.TRANSACTION_FAILED
|
|
9588
11027
|
);
|
|
9589
11028
|
}
|
|
9590
11029
|
this._signedTransactions.push(tx);
|
|
@@ -9614,7 +11053,7 @@ var MockEthereumAdapter = class extends BaseWalletAdapter {
|
|
|
9614
11053
|
if (asset.chain !== "ethereum") {
|
|
9615
11054
|
throw new WalletError(
|
|
9616
11055
|
`Asset chain ${asset.chain} not supported by Ethereum adapter`,
|
|
9617
|
-
|
|
11056
|
+
import_types22.WalletErrorCode.UNSUPPORTED_CHAIN
|
|
9618
11057
|
);
|
|
9619
11058
|
}
|
|
9620
11059
|
if (!asset.address) {
|
|
@@ -9893,7 +11332,7 @@ function getAvailableTransports() {
|
|
|
9893
11332
|
}
|
|
9894
11333
|
|
|
9895
11334
|
// src/wallet/hardware/ledger.ts
|
|
9896
|
-
var
|
|
11335
|
+
var import_types25 = require("@sip-protocol/types");
|
|
9897
11336
|
var LedgerWalletAdapter = class extends BaseWalletAdapter {
|
|
9898
11337
|
chain;
|
|
9899
11338
|
name = "ledger";
|
|
@@ -10046,7 +11485,7 @@ var LedgerWalletAdapter = class extends BaseWalletAdapter {
|
|
|
10046
11485
|
async getBalance() {
|
|
10047
11486
|
throw new WalletError(
|
|
10048
11487
|
"Hardware wallets do not track balances. Use an RPC provider.",
|
|
10049
|
-
|
|
11488
|
+
import_types25.WalletErrorCode.UNSUPPORTED_OPERATION
|
|
10050
11489
|
);
|
|
10051
11490
|
}
|
|
10052
11491
|
/**
|
|
@@ -10057,7 +11496,7 @@ var LedgerWalletAdapter = class extends BaseWalletAdapter {
|
|
|
10057
11496
|
async getTokenBalance(_asset) {
|
|
10058
11497
|
throw new WalletError(
|
|
10059
11498
|
"Hardware wallets do not track balances. Use an RPC provider.",
|
|
10060
|
-
|
|
11499
|
+
import_types25.WalletErrorCode.UNSUPPORTED_OPERATION
|
|
10061
11500
|
);
|
|
10062
11501
|
}
|
|
10063
11502
|
// ─── Account Management ─────────────────────────────────────────────────────
|
|
@@ -10345,7 +11784,7 @@ function createLedgerAdapter(config) {
|
|
|
10345
11784
|
}
|
|
10346
11785
|
|
|
10347
11786
|
// src/wallet/hardware/trezor.ts
|
|
10348
|
-
var
|
|
11787
|
+
var import_types27 = require("@sip-protocol/types");
|
|
10349
11788
|
var TrezorWalletAdapter = class extends BaseWalletAdapter {
|
|
10350
11789
|
chain;
|
|
10351
11790
|
name = "trezor";
|
|
@@ -10491,7 +11930,7 @@ var TrezorWalletAdapter = class extends BaseWalletAdapter {
|
|
|
10491
11930
|
async getBalance() {
|
|
10492
11931
|
throw new WalletError(
|
|
10493
11932
|
"Hardware wallets do not track balances. Use an RPC provider.",
|
|
10494
|
-
|
|
11933
|
+
import_types27.WalletErrorCode.UNSUPPORTED_OPERATION
|
|
10495
11934
|
);
|
|
10496
11935
|
}
|
|
10497
11936
|
/**
|
|
@@ -10502,7 +11941,7 @@ var TrezorWalletAdapter = class extends BaseWalletAdapter {
|
|
|
10502
11941
|
async getTokenBalance(_asset) {
|
|
10503
11942
|
throw new WalletError(
|
|
10504
11943
|
"Hardware wallets do not track balances. Use an RPC provider.",
|
|
10505
|
-
|
|
11944
|
+
import_types27.WalletErrorCode.UNSUPPORTED_OPERATION
|
|
10506
11945
|
);
|
|
10507
11946
|
}
|
|
10508
11947
|
// ─── Account Management ─────────────────────────────────────────────────────
|
|
@@ -10783,8 +12222,8 @@ function createTrezorAdapter(config) {
|
|
|
10783
12222
|
}
|
|
10784
12223
|
|
|
10785
12224
|
// src/wallet/hardware/mock.ts
|
|
10786
|
-
var
|
|
10787
|
-
var
|
|
12225
|
+
var import_types29 = require("@sip-protocol/types");
|
|
12226
|
+
var import_utils14 = require("@noble/hashes/utils");
|
|
10788
12227
|
var MockLedgerAdapter = class extends BaseWalletAdapter {
|
|
10789
12228
|
chain;
|
|
10790
12229
|
name = "mock-ledger";
|
|
@@ -10931,7 +12370,7 @@ var MockLedgerAdapter = class extends BaseWalletAdapter {
|
|
|
10931
12370
|
async getBalance() {
|
|
10932
12371
|
throw new WalletError(
|
|
10933
12372
|
"Hardware wallets do not track balances",
|
|
10934
|
-
|
|
12373
|
+
import_types29.WalletErrorCode.UNSUPPORTED_OPERATION
|
|
10935
12374
|
);
|
|
10936
12375
|
}
|
|
10937
12376
|
/**
|
|
@@ -10940,7 +12379,7 @@ var MockLedgerAdapter = class extends BaseWalletAdapter {
|
|
|
10940
12379
|
async getTokenBalance(_asset) {
|
|
10941
12380
|
throw new WalletError(
|
|
10942
12381
|
"Hardware wallets do not track balances",
|
|
10943
|
-
|
|
12382
|
+
import_types29.WalletErrorCode.UNSUPPORTED_OPERATION
|
|
10944
12383
|
);
|
|
10945
12384
|
}
|
|
10946
12385
|
/**
|
|
@@ -11029,15 +12468,15 @@ var MockLedgerAdapter = class extends BaseWalletAdapter {
|
|
|
11029
12468
|
}
|
|
11030
12469
|
}
|
|
11031
12470
|
generateMockAddress(index) {
|
|
11032
|
-
const bytes = (0,
|
|
12471
|
+
const bytes = (0, import_utils14.randomBytes)(20);
|
|
11033
12472
|
bytes[0] = index;
|
|
11034
|
-
return `0x${(0,
|
|
12473
|
+
return `0x${(0, import_utils14.bytesToHex)(bytes)}`;
|
|
11035
12474
|
}
|
|
11036
12475
|
generateMockPublicKey(index) {
|
|
11037
|
-
const bytes = (0,
|
|
12476
|
+
const bytes = (0, import_utils14.randomBytes)(33);
|
|
11038
12477
|
bytes[0] = 2;
|
|
11039
12478
|
bytes[1] = index;
|
|
11040
|
-
return `0x${(0,
|
|
12479
|
+
return `0x${(0, import_utils14.bytesToHex)(bytes)}`;
|
|
11041
12480
|
}
|
|
11042
12481
|
generateMockSignature(data) {
|
|
11043
12482
|
const sig = new Uint8Array(65);
|
|
@@ -11046,7 +12485,7 @@ var MockLedgerAdapter = class extends BaseWalletAdapter {
|
|
|
11046
12485
|
sig[32 + i] = (data[i % data.length] ?? 0) ^ i * 11;
|
|
11047
12486
|
}
|
|
11048
12487
|
sig[64] = 27;
|
|
11049
|
-
return `0x${(0,
|
|
12488
|
+
return `0x${(0, import_utils14.bytesToHex)(sig)}`;
|
|
11050
12489
|
}
|
|
11051
12490
|
delay(ms) {
|
|
11052
12491
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
@@ -11170,13 +12609,13 @@ var MockTrezorAdapter = class extends BaseWalletAdapter {
|
|
|
11170
12609
|
async getBalance() {
|
|
11171
12610
|
throw new WalletError(
|
|
11172
12611
|
"Hardware wallets do not track balances",
|
|
11173
|
-
|
|
12612
|
+
import_types29.WalletErrorCode.UNSUPPORTED_OPERATION
|
|
11174
12613
|
);
|
|
11175
12614
|
}
|
|
11176
12615
|
async getTokenBalance(_asset) {
|
|
11177
12616
|
throw new WalletError(
|
|
11178
12617
|
"Hardware wallets do not track balances",
|
|
11179
|
-
|
|
12618
|
+
import_types29.WalletErrorCode.UNSUPPORTED_OPERATION
|
|
11180
12619
|
);
|
|
11181
12620
|
}
|
|
11182
12621
|
async getAccounts(startIndex = 0, count = 5) {
|
|
@@ -11235,15 +12674,15 @@ var MockTrezorAdapter = class extends BaseWalletAdapter {
|
|
|
11235
12674
|
}
|
|
11236
12675
|
}
|
|
11237
12676
|
generateMockAddress(index) {
|
|
11238
|
-
const bytes = (0,
|
|
12677
|
+
const bytes = (0, import_utils14.randomBytes)(20);
|
|
11239
12678
|
bytes[0] = index + 100;
|
|
11240
|
-
return `0x${(0,
|
|
12679
|
+
return `0x${(0, import_utils14.bytesToHex)(bytes)}`;
|
|
11241
12680
|
}
|
|
11242
12681
|
generateMockPublicKey(index) {
|
|
11243
|
-
const bytes = (0,
|
|
12682
|
+
const bytes = (0, import_utils14.randomBytes)(33);
|
|
11244
12683
|
bytes[0] = 3;
|
|
11245
12684
|
bytes[1] = index + 100;
|
|
11246
|
-
return `0x${(0,
|
|
12685
|
+
return `0x${(0, import_utils14.bytesToHex)(bytes)}`;
|
|
11247
12686
|
}
|
|
11248
12687
|
generateMockSignature(data) {
|
|
11249
12688
|
const sig = new Uint8Array(65);
|
|
@@ -11252,7 +12691,7 @@ var MockTrezorAdapter = class extends BaseWalletAdapter {
|
|
|
11252
12691
|
sig[32 + i] = (data[i % data.length] ?? 0) ^ i * 17;
|
|
11253
12692
|
}
|
|
11254
12693
|
sig[64] = 28;
|
|
11255
|
-
return `0x${(0,
|
|
12694
|
+
return `0x${(0, import_utils14.bytesToHex)(sig)}`;
|
|
11256
12695
|
}
|
|
11257
12696
|
delay(ms) {
|
|
11258
12697
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
@@ -11266,12 +12705,17 @@ function createMockTrezorAdapter(config) {
|
|
|
11266
12705
|
}
|
|
11267
12706
|
|
|
11268
12707
|
// src/wallet/index.ts
|
|
11269
|
-
var
|
|
12708
|
+
var import_types32 = require("@sip-protocol/types");
|
|
11270
12709
|
// Annotate the CommonJS export names for ESM import in node:
|
|
11271
12710
|
0 && (module.exports = {
|
|
12711
|
+
ATTESTATION_VERSION,
|
|
11272
12712
|
BaseWalletAdapter,
|
|
12713
|
+
BrowserNoirProvider,
|
|
12714
|
+
CHAIN_NUMERIC_IDS,
|
|
11273
12715
|
ComplianceManager,
|
|
11274
12716
|
CryptoError,
|
|
12717
|
+
DEFAULT_THRESHOLD,
|
|
12718
|
+
DEFAULT_TOTAL_ORACLES,
|
|
11275
12719
|
DerivationPath,
|
|
11276
12720
|
EncryptionNotImplementedError,
|
|
11277
12721
|
ErrorCode,
|
|
@@ -11294,6 +12738,7 @@ var import_types30 = require("@sip-protocol/types");
|
|
|
11294
12738
|
NEARIntentsAdapter,
|
|
11295
12739
|
NetworkError,
|
|
11296
12740
|
NoirProofProvider,
|
|
12741
|
+
ORACLE_DOMAIN,
|
|
11297
12742
|
OneClickClient,
|
|
11298
12743
|
OneClickDepositMode,
|
|
11299
12744
|
OneClickErrorCode,
|
|
@@ -11325,11 +12770,16 @@ var import_types30 = require("@sip-protocol/types");
|
|
|
11325
12770
|
ZcashShieldedService,
|
|
11326
12771
|
addBlindings,
|
|
11327
12772
|
addCommitments,
|
|
12773
|
+
addOracle,
|
|
11328
12774
|
attachProofs,
|
|
11329
12775
|
base58ToHex,
|
|
12776
|
+
browserBytesToHex,
|
|
12777
|
+
browserHexToBytes,
|
|
12778
|
+
checkEd25519StealthAddress,
|
|
11330
12779
|
checkStealthAddress,
|
|
11331
12780
|
commit,
|
|
11332
12781
|
commitZero,
|
|
12782
|
+
computeAttestationHash,
|
|
11333
12783
|
createCommitment,
|
|
11334
12784
|
createEthereumAdapter,
|
|
11335
12785
|
createLedgerAdapter,
|
|
@@ -11342,6 +12792,7 @@ var import_types30 = require("@sip-protocol/types");
|
|
|
11342
12792
|
createMockSolver,
|
|
11343
12793
|
createMockTrezorAdapter,
|
|
11344
12794
|
createNEARIntentsAdapter,
|
|
12795
|
+
createOracleRegistry,
|
|
11345
12796
|
createProductionSIP,
|
|
11346
12797
|
createSIP,
|
|
11347
12798
|
createShieldedIntent,
|
|
@@ -11354,12 +12805,17 @@ var import_types30 = require("@sip-protocol/types");
|
|
|
11354
12805
|
decodeStealthMetaAddress,
|
|
11355
12806
|
decryptMemo,
|
|
11356
12807
|
decryptWithViewing,
|
|
12808
|
+
deriveEd25519StealthPrivateKey,
|
|
12809
|
+
deriveOracleId,
|
|
11357
12810
|
deriveStealthPrivateKey,
|
|
11358
12811
|
deriveViewingKey,
|
|
12812
|
+
deserializeAttestationMessage,
|
|
11359
12813
|
deserializeIntent,
|
|
11360
12814
|
deserializePayment,
|
|
11361
12815
|
detectEthereumWallets,
|
|
11362
12816
|
detectSolanaWallets,
|
|
12817
|
+
ed25519PublicKeyToNearAddress,
|
|
12818
|
+
ed25519PublicKeyToSolanaAddress,
|
|
11363
12819
|
encodeStealthMetaAddress,
|
|
11364
12820
|
encryptForViewing,
|
|
11365
12821
|
featureNotSupportedError,
|
|
@@ -11367,13 +12823,19 @@ var import_types30 = require("@sip-protocol/types");
|
|
|
11367
12823
|
fromHex,
|
|
11368
12824
|
fromStablecoinUnits,
|
|
11369
12825
|
generateBlinding,
|
|
12826
|
+
generateEd25519StealthAddress,
|
|
12827
|
+
generateEd25519StealthMetaAddress,
|
|
11370
12828
|
generateIntentId,
|
|
11371
12829
|
generateRandomBytes,
|
|
11372
12830
|
generateStealthAddress,
|
|
11373
12831
|
generateStealthMetaAddress,
|
|
11374
12832
|
generateViewingKey,
|
|
12833
|
+
getActiveOracles,
|
|
11375
12834
|
getAvailableTransports,
|
|
12835
|
+
getBrowserInfo,
|
|
12836
|
+
getChainNumericId,
|
|
11376
12837
|
getChainsForStablecoin,
|
|
12838
|
+
getCurveForChain,
|
|
11377
12839
|
getDefaultRpcEndpoint,
|
|
11378
12840
|
getDerivationPath,
|
|
11379
12841
|
getErrorMessage,
|
|
@@ -11390,10 +12852,13 @@ var import_types30 = require("@sip-protocol/types");
|
|
|
11390
12852
|
getStablecoinsForChain,
|
|
11391
12853
|
getSupportedStablecoins,
|
|
11392
12854
|
getTimeRemaining,
|
|
12855
|
+
hasEnoughOracles,
|
|
11393
12856
|
hasErrorCode,
|
|
11394
12857
|
hasRequiredProofs,
|
|
11395
12858
|
hash,
|
|
11396
12859
|
hexToNumber,
|
|
12860
|
+
isBrowser,
|
|
12861
|
+
isEd25519Chain,
|
|
11397
12862
|
isExpired,
|
|
11398
12863
|
isNonNegativeAmount,
|
|
11399
12864
|
isPaymentExpired,
|
|
@@ -11405,40 +12870,54 @@ var import_types30 = require("@sip-protocol/types");
|
|
|
11405
12870
|
isValidAmount,
|
|
11406
12871
|
isValidChainId,
|
|
11407
12872
|
isValidCompressedPublicKey,
|
|
12873
|
+
isValidEd25519PublicKey,
|
|
11408
12874
|
isValidHex,
|
|
11409
12875
|
isValidHexLength,
|
|
12876
|
+
isValidNearAccountId,
|
|
12877
|
+
isValidNearImplicitAddress,
|
|
11410
12878
|
isValidPrivacyLevel,
|
|
11411
12879
|
isValidPrivateKey,
|
|
11412
12880
|
isValidScalar,
|
|
11413
12881
|
isValidSlippage,
|
|
12882
|
+
isValidSolanaAddress,
|
|
11414
12883
|
isValidStealthMetaAddress,
|
|
12884
|
+
nearAddressToEd25519PublicKey,
|
|
11415
12885
|
normalizeAddress,
|
|
11416
12886
|
notConnectedError,
|
|
11417
12887
|
publicKeyToEthAddress,
|
|
11418
12888
|
registerWallet,
|
|
12889
|
+
removeOracle,
|
|
11419
12890
|
secureWipe,
|
|
11420
12891
|
secureWipeAll,
|
|
12892
|
+
serializeAttestationMessage,
|
|
11421
12893
|
serializeIntent,
|
|
11422
12894
|
serializePayment,
|
|
12895
|
+
signAttestationMessage,
|
|
12896
|
+
solanaAddressToEd25519PublicKey,
|
|
11423
12897
|
solanaPublicKeyToHex,
|
|
11424
12898
|
subtractBlindings,
|
|
11425
12899
|
subtractCommitments,
|
|
12900
|
+
supportsSharedArrayBuffer,
|
|
11426
12901
|
supportsViewingKey,
|
|
11427
12902
|
supportsWebBluetooth,
|
|
11428
12903
|
supportsWebHID,
|
|
11429
12904
|
supportsWebUSB,
|
|
12905
|
+
supportsWebWorkers,
|
|
11430
12906
|
toHex,
|
|
11431
12907
|
toStablecoinUnits,
|
|
11432
12908
|
trackIntent,
|
|
11433
12909
|
trackPayment,
|
|
12910
|
+
updateOracleStatus,
|
|
11434
12911
|
validateAsset,
|
|
11435
12912
|
validateCreateIntentParams,
|
|
11436
12913
|
validateIntentInput,
|
|
11437
12914
|
validateIntentOutput,
|
|
11438
12915
|
validateScalar,
|
|
11439
12916
|
validateViewingKey,
|
|
12917
|
+
verifyAttestation,
|
|
11440
12918
|
verifyCommitment,
|
|
11441
12919
|
verifyOpening,
|
|
12920
|
+
verifyOracleSignature,
|
|
11442
12921
|
walletRegistry,
|
|
11443
12922
|
withSecureBuffer,
|
|
11444
12923
|
withSecureBufferSync,
|