@sip-protocol/sdk 0.1.9 → 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 +1854 -378
- package/dist/index.mjs +262 -11114
- package/package.json +23 -14
- package/src/adapters/near-intents.ts +138 -30
- 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,28 +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;
|
|
2477
|
+
recipientAddress = publicKeyToEthAddress(stealthAddress.address);
|
|
2478
|
+
nativeRecipientAddress = recipientAddress;
|
|
2479
|
+
} else {
|
|
1987
2480
|
throw new ValidationError(
|
|
1988
|
-
`Stealth addresses are not supported for ${
|
|
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.`,
|
|
1989
2482
|
"outputAsset",
|
|
1990
|
-
{ outputChain
|
|
2483
|
+
{ outputChain, outputChainType }
|
|
1991
2484
|
);
|
|
1992
2485
|
}
|
|
1993
|
-
recipientAddress = publicKeyToEthAddress(stealthAddress.address);
|
|
1994
|
-
stealthData = stealthAddress;
|
|
1995
|
-
sharedSecret = secret;
|
|
1996
2486
|
if (!senderAddress) {
|
|
1997
|
-
const
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
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
|
+
}
|
|
2001
2517
|
} else {
|
|
2002
2518
|
throw new ValidationError(
|
|
2003
|
-
`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.`,
|
|
2004
2520
|
"senderAddress",
|
|
2005
|
-
{ inputChain
|
|
2521
|
+
{ inputChain, inputChainType }
|
|
2006
2522
|
);
|
|
2007
2523
|
}
|
|
2008
2524
|
}
|
|
@@ -2020,7 +2536,9 @@ var NEARIntentsAdapter = class {
|
|
|
2020
2536
|
request,
|
|
2021
2537
|
quoteRequest,
|
|
2022
2538
|
stealthAddress: stealthData,
|
|
2023
|
-
sharedSecret
|
|
2539
|
+
sharedSecret,
|
|
2540
|
+
curve,
|
|
2541
|
+
nativeRecipientAddress
|
|
2024
2542
|
};
|
|
2025
2543
|
}
|
|
2026
2544
|
/**
|
|
@@ -4285,7 +4803,739 @@ var NoirProofProvider = class {
|
|
|
4285
4803
|
}
|
|
4286
4804
|
try {
|
|
4287
4805
|
const proofHex = proof.proof.startsWith("0x") ? proof.proof.slice(2) : proof.proof;
|
|
4288
|
-
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);
|
|
4289
5539
|
const isValid = await backend.verifyProof({
|
|
4290
5540
|
proof: proofBytes,
|
|
4291
5541
|
publicInputs: proof.publicInputs.map(
|
|
@@ -4295,7 +5545,7 @@ var NoirProofProvider = class {
|
|
|
4295
5545
|
return isValid;
|
|
4296
5546
|
} catch (error) {
|
|
4297
5547
|
if (this.config.verbose) {
|
|
4298
|
-
console.error("[
|
|
5548
|
+
console.error("[BrowserNoirProvider] Verification error:", error);
|
|
4299
5549
|
}
|
|
4300
5550
|
return false;
|
|
4301
5551
|
}
|
|
@@ -4316,52 +5566,37 @@ var NoirProofProvider = class {
|
|
|
4316
5566
|
await this.fulfillmentBackend.destroy();
|
|
4317
5567
|
this.fulfillmentBackend = null;
|
|
4318
5568
|
}
|
|
5569
|
+
if (this.worker) {
|
|
5570
|
+
this.worker.terminate();
|
|
5571
|
+
this.worker = null;
|
|
5572
|
+
}
|
|
4319
5573
|
this.fundingNoir = null;
|
|
4320
5574
|
this.validityNoir = null;
|
|
4321
5575
|
this.fulfillmentNoir = null;
|
|
4322
5576
|
this._isReady = false;
|
|
4323
5577
|
}
|
|
4324
|
-
// ─── Private Methods
|
|
5578
|
+
// ─── Private Utility Methods ────────────────────────────────────────────────
|
|
4325
5579
|
ensureReady() {
|
|
4326
5580
|
if (!this._isReady) {
|
|
4327
5581
|
throw new ProofError(
|
|
4328
|
-
"
|
|
5582
|
+
"BrowserNoirProvider not initialized. Call initialize() first.",
|
|
4329
5583
|
"SIP_4004" /* PROOF_PROVIDER_NOT_READY */
|
|
4330
5584
|
);
|
|
4331
5585
|
}
|
|
4332
5586
|
}
|
|
4333
|
-
/**
|
|
4334
|
-
* Compute the commitment hash that the circuit expects
|
|
4335
|
-
*
|
|
4336
|
-
* The circuit computes:
|
|
4337
|
-
* 1. commitment = pedersen_commitment([balance, blinding])
|
|
4338
|
-
* 2. commitment_hash = pedersen_hash([commitment.x, commitment.y, asset_id])
|
|
4339
|
-
*
|
|
4340
|
-
* We need to compute this outside to pass as a public input.
|
|
4341
|
-
*
|
|
4342
|
-
* **IMPORTANT**: This SDK uses SHA256 as a deterministic stand-in for Pedersen hash.
|
|
4343
|
-
* Both the SDK and circuit MUST use the same hash function. The bundled circuit
|
|
4344
|
-
* artifacts are configured to use SHA256 for compatibility. If you use custom
|
|
4345
|
-
* circuits with actual Pedersen hashing, you must update this implementation.
|
|
4346
|
-
*
|
|
4347
|
-
* @see docs/specs/HASH-COMPATIBILITY.md for hash function requirements
|
|
4348
|
-
*/
|
|
4349
5587
|
async computeCommitmentHash(balance, blindingFactor, assetId) {
|
|
4350
5588
|
const blindingField = this.bytesToField(blindingFactor);
|
|
4351
|
-
const { sha256:
|
|
4352
|
-
const { bytesToHex:
|
|
5589
|
+
const { sha256: sha25611 } = await import("@noble/hashes/sha256");
|
|
5590
|
+
const { bytesToHex: nobleToHex } = await import("@noble/hashes/utils");
|
|
4353
5591
|
const preimage = new Uint8Array([
|
|
4354
5592
|
...this.bigintToBytes(balance, 8),
|
|
4355
5593
|
...blindingFactor.slice(0, 32),
|
|
4356
|
-
...
|
|
5594
|
+
...hexToBytes5(this.assetIdToField(assetId))
|
|
4357
5595
|
]);
|
|
4358
|
-
const hash2 =
|
|
4359
|
-
const commitmentHash =
|
|
5596
|
+
const hash2 = sha25611(preimage);
|
|
5597
|
+
const commitmentHash = nobleToHex(hash2);
|
|
4360
5598
|
return { commitmentHash, blindingField };
|
|
4361
5599
|
}
|
|
4362
|
-
/**
|
|
4363
|
-
* Convert asset ID to field element
|
|
4364
|
-
*/
|
|
4365
5600
|
assetIdToField(assetId) {
|
|
4366
5601
|
if (assetId.startsWith("0x")) {
|
|
4367
5602
|
return assetId.slice(2).padStart(64, "0");
|
|
@@ -4374,9 +5609,6 @@ var NoirProofProvider = class {
|
|
|
4374
5609
|
}
|
|
4375
5610
|
return result.toString(16).padStart(64, "0");
|
|
4376
5611
|
}
|
|
4377
|
-
/**
|
|
4378
|
-
* Convert bytes to field element string
|
|
4379
|
-
*/
|
|
4380
5612
|
bytesToField(bytes) {
|
|
4381
5613
|
let result = 0n;
|
|
4382
5614
|
const len = Math.min(bytes.length, 31);
|
|
@@ -4385,9 +5617,6 @@ var NoirProofProvider = class {
|
|
|
4385
5617
|
}
|
|
4386
5618
|
return result.toString();
|
|
4387
5619
|
}
|
|
4388
|
-
/**
|
|
4389
|
-
* Convert bigint to bytes
|
|
4390
|
-
*/
|
|
4391
5620
|
bigintToBytes(value, length) {
|
|
4392
5621
|
const bytes = new Uint8Array(length);
|
|
4393
5622
|
let v = value;
|
|
@@ -4397,27 +5626,10 @@ var NoirProofProvider = class {
|
|
|
4397
5626
|
}
|
|
4398
5627
|
return bytes;
|
|
4399
5628
|
}
|
|
4400
|
-
/**
|
|
4401
|
-
* Convert hex string to bytes
|
|
4402
|
-
*/
|
|
4403
|
-
hexToBytes(hex) {
|
|
4404
|
-
const h = hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
4405
|
-
const bytes = new Uint8Array(h.length / 2);
|
|
4406
|
-
for (let i = 0; i < bytes.length; i++) {
|
|
4407
|
-
bytes[i] = parseInt(h.slice(i * 2, i * 2 + 2), 16);
|
|
4408
|
-
}
|
|
4409
|
-
return bytes;
|
|
4410
|
-
}
|
|
4411
|
-
/**
|
|
4412
|
-
* Convert hex string to field element string
|
|
4413
|
-
*/
|
|
4414
5629
|
hexToField(hex) {
|
|
4415
5630
|
const h = hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
4416
5631
|
return h.padStart(64, "0");
|
|
4417
5632
|
}
|
|
4418
|
-
/**
|
|
4419
|
-
* Convert field string to 32-byte array
|
|
4420
|
-
*/
|
|
4421
5633
|
fieldToBytes32(field) {
|
|
4422
5634
|
const hex = field.padStart(64, "0");
|
|
4423
5635
|
const bytes = [];
|
|
@@ -4426,87 +5638,50 @@ var NoirProofProvider = class {
|
|
|
4426
5638
|
}
|
|
4427
5639
|
return bytes;
|
|
4428
5640
|
}
|
|
4429
|
-
/**
|
|
4430
|
-
* Compute sender commitment for validity proof
|
|
4431
|
-
*
|
|
4432
|
-
* Uses SHA256 for SDK-side computation. The bundled circuit artifacts
|
|
4433
|
-
* are compiled to use SHA256 for compatibility with this SDK.
|
|
4434
|
-
*
|
|
4435
|
-
* @see computeCommitmentHash for hash function compatibility notes
|
|
4436
|
-
*/
|
|
4437
5641
|
async computeSenderCommitment(senderAddressField, senderBlindingField) {
|
|
4438
|
-
const { sha256:
|
|
4439
|
-
const { bytesToHex:
|
|
4440
|
-
const addressBytes =
|
|
4441
|
-
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"));
|
|
4442
5646
|
const preimage = new Uint8Array([...addressBytes, ...blindingBytes]);
|
|
4443
|
-
const hash2 =
|
|
4444
|
-
const commitmentX =
|
|
4445
|
-
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");
|
|
4446
5650
|
return { commitmentX, commitmentY };
|
|
4447
5651
|
}
|
|
4448
|
-
/**
|
|
4449
|
-
* Compute nullifier for validity proof
|
|
4450
|
-
*
|
|
4451
|
-
* Uses SHA256 for SDK-side computation. The bundled circuit artifacts
|
|
4452
|
-
* are compiled to use SHA256 for compatibility with this SDK.
|
|
4453
|
-
*
|
|
4454
|
-
* @see computeCommitmentHash for hash function compatibility notes
|
|
4455
|
-
*/
|
|
4456
5652
|
async computeNullifier(senderSecretField, intentHashField, nonceField) {
|
|
4457
|
-
const { sha256:
|
|
4458
|
-
const { bytesToHex:
|
|
4459
|
-
const secretBytes =
|
|
4460
|
-
const intentBytes =
|
|
4461
|
-
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"));
|
|
4462
5658
|
const preimage = new Uint8Array([...secretBytes, ...intentBytes, ...nonceBytes]);
|
|
4463
|
-
const hash2 =
|
|
4464
|
-
return
|
|
5659
|
+
const hash2 = sha25611(preimage);
|
|
5660
|
+
return nobleToHex(hash2);
|
|
4465
5661
|
}
|
|
4466
|
-
/**
|
|
4467
|
-
* Compute output commitment for fulfillment proof
|
|
4468
|
-
*
|
|
4469
|
-
* Uses SHA256 for SDK-side computation. The bundled circuit artifacts
|
|
4470
|
-
* are compiled to use SHA256 for compatibility with this SDK.
|
|
4471
|
-
*
|
|
4472
|
-
* @see computeCommitmentHash for hash function compatibility notes
|
|
4473
|
-
*/
|
|
4474
5662
|
async computeOutputCommitment(outputAmount, outputBlinding) {
|
|
4475
|
-
const { sha256:
|
|
4476
|
-
const { bytesToHex:
|
|
5663
|
+
const { sha256: sha25611 } = await import("@noble/hashes/sha256");
|
|
5664
|
+
const { bytesToHex: nobleToHex } = await import("@noble/hashes/utils");
|
|
4477
5665
|
const amountBytes = this.bigintToBytes(outputAmount, 8);
|
|
4478
5666
|
const blindingBytes = outputBlinding.slice(0, 32);
|
|
4479
5667
|
const preimage = new Uint8Array([...amountBytes, ...blindingBytes]);
|
|
4480
|
-
const hash2 =
|
|
4481
|
-
const commitmentX =
|
|
4482
|
-
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");
|
|
4483
5671
|
return { commitmentX, commitmentY };
|
|
4484
5672
|
}
|
|
4485
|
-
/**
|
|
4486
|
-
* Compute solver ID from solver secret
|
|
4487
|
-
*
|
|
4488
|
-
* Uses SHA256 for SDK-side computation. The bundled circuit artifacts
|
|
4489
|
-
* are compiled to use SHA256 for compatibility with this SDK.
|
|
4490
|
-
*
|
|
4491
|
-
* @see computeCommitmentHash for hash function compatibility notes
|
|
4492
|
-
*/
|
|
4493
5673
|
async computeSolverId(solverSecretField) {
|
|
4494
|
-
const { sha256:
|
|
4495
|
-
const { bytesToHex:
|
|
4496
|
-
const secretBytes =
|
|
4497
|
-
const hash2 =
|
|
4498
|
-
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);
|
|
4499
5679
|
}
|
|
4500
|
-
/**
|
|
4501
|
-
* Compute oracle message hash for fulfillment proof
|
|
4502
|
-
*
|
|
4503
|
-
* Hash of attestation data that oracle signs
|
|
4504
|
-
*/
|
|
4505
5680
|
async computeOracleMessageHash(recipient, amount, txHash, blockNumber) {
|
|
4506
|
-
const { sha256:
|
|
4507
|
-
const recipientBytes =
|
|
5681
|
+
const { sha256: sha25611 } = await import("@noble/hashes/sha256");
|
|
5682
|
+
const recipientBytes = hexToBytes5(this.hexToField(recipient));
|
|
4508
5683
|
const amountBytes = this.bigintToBytes(amount, 8);
|
|
4509
|
-
const txHashBytes =
|
|
5684
|
+
const txHashBytes = hexToBytes5(this.hexToField(txHash));
|
|
4510
5685
|
const blockBytes = this.bigintToBytes(blockNumber, 8);
|
|
4511
5686
|
const preimage = new Uint8Array([
|
|
4512
5687
|
...recipientBytes,
|
|
@@ -4514,42 +5689,303 @@ var NoirProofProvider = class {
|
|
|
4514
5689
|
...txHashBytes,
|
|
4515
5690
|
...blockBytes
|
|
4516
5691
|
]);
|
|
4517
|
-
const hash2 =
|
|
5692
|
+
const hash2 = sha25611(preimage);
|
|
4518
5693
|
return Array.from(hash2);
|
|
4519
5694
|
}
|
|
4520
|
-
/**
|
|
4521
|
-
* Derive secp256k1 public key coordinates from a private key
|
|
4522
|
-
*
|
|
4523
|
-
* @param privateKey - 32-byte private key as Uint8Array
|
|
4524
|
-
* @returns X and Y coordinates as 32-byte arrays
|
|
4525
|
-
*/
|
|
4526
5695
|
getPublicKeyCoordinates(privateKey) {
|
|
4527
|
-
const uncompressedPubKey =
|
|
5696
|
+
const uncompressedPubKey = import_secp256k14.secp256k1.getPublicKey(privateKey, false);
|
|
4528
5697
|
const x = Array.from(uncompressedPubKey.slice(1, 33));
|
|
4529
5698
|
const y = Array.from(uncompressedPubKey.slice(33, 65));
|
|
4530
5699
|
return { x, y };
|
|
4531
5700
|
}
|
|
4532
|
-
/**
|
|
4533
|
-
* Derive public key coordinates from a field string (private key)
|
|
4534
|
-
*
|
|
4535
|
-
* @param privateKeyField - Private key as hex field string
|
|
4536
|
-
* @returns X and Y coordinates as 32-byte arrays
|
|
4537
|
-
*/
|
|
4538
|
-
getPublicKeyFromField(privateKeyField) {
|
|
4539
|
-
const privateKeyBytes = this.hexToBytes(privateKeyField.padStart(64, "0"));
|
|
4540
|
-
return this.getPublicKeyCoordinates(privateKeyBytes);
|
|
4541
|
-
}
|
|
4542
5701
|
};
|
|
4543
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
|
+
|
|
4544
5980
|
// src/index.ts
|
|
4545
|
-
var import_types31 = require("@sip-protocol/types");
|
|
4546
|
-
var import_types32 = require("@sip-protocol/types");
|
|
4547
5981
|
var import_types33 = require("@sip-protocol/types");
|
|
4548
5982
|
var import_types34 = require("@sip-protocol/types");
|
|
5983
|
+
var import_types35 = require("@sip-protocol/types");
|
|
5984
|
+
var import_types36 = require("@sip-protocol/types");
|
|
4549
5985
|
|
|
4550
5986
|
// src/solver/mock-solver.ts
|
|
4551
|
-
var
|
|
4552
|
-
var
|
|
5987
|
+
var import_types7 = require("@sip-protocol/types");
|
|
5988
|
+
var import_utils10 = require("@noble/hashes/utils");
|
|
4553
5989
|
var MockSolver = class {
|
|
4554
5990
|
info;
|
|
4555
5991
|
capabilities;
|
|
@@ -4631,7 +6067,7 @@ var MockSolver = class {
|
|
|
4631
6067
|
const spreadAmount = baseOutput * BigInt(Math.floor(this.spreadPercent * 1e4)) / 10000n;
|
|
4632
6068
|
const outputAmount = baseOutput + spreadAmount;
|
|
4633
6069
|
const feeAmount = outputAmount * BigInt(Math.floor(this.feePercent * 1e4)) / 10000n;
|
|
4634
|
-
const quoteId = `quote-${(0,
|
|
6070
|
+
const quoteId = `quote-${(0, import_utils10.bytesToHex)((0, import_utils10.randomBytes)(8))}`;
|
|
4635
6071
|
const now = Math.floor(Date.now() / 1e3);
|
|
4636
6072
|
const quote = {
|
|
4637
6073
|
quoteId,
|
|
@@ -4642,7 +6078,7 @@ var MockSolver = class {
|
|
|
4642
6078
|
expiry: now + 60,
|
|
4643
6079
|
// Quote valid for 1 minute
|
|
4644
6080
|
fee: feeAmount,
|
|
4645
|
-
signature: `0x${(0,
|
|
6081
|
+
signature: `0x${(0, import_utils10.bytesToHex)((0, import_utils10.randomBytes)(64))}`,
|
|
4646
6082
|
// Mock signature
|
|
4647
6083
|
validUntil: now + 60,
|
|
4648
6084
|
estimatedGas: 200000n
|
|
@@ -4674,25 +6110,25 @@ var MockSolver = class {
|
|
|
4674
6110
|
status.error = "Simulated failure for testing";
|
|
4675
6111
|
return {
|
|
4676
6112
|
intentId: intent.intentId,
|
|
4677
|
-
status:
|
|
6113
|
+
status: import_types7.IntentStatus.FAILED,
|
|
4678
6114
|
fulfilledAt: Math.floor(Date.now() / 1e3),
|
|
4679
6115
|
error: status.error
|
|
4680
6116
|
};
|
|
4681
6117
|
}
|
|
4682
|
-
const txHash = `0x${(0,
|
|
6118
|
+
const txHash = `0x${(0, import_utils10.bytesToHex)((0, import_utils10.randomBytes)(32))}`;
|
|
4683
6119
|
status.status = "completed";
|
|
4684
6120
|
status.txHash = txHash;
|
|
4685
6121
|
return {
|
|
4686
6122
|
intentId: intent.intentId,
|
|
4687
|
-
status:
|
|
6123
|
+
status: import_types7.IntentStatus.FULFILLED,
|
|
4688
6124
|
outputAmount: quote.outputAmount,
|
|
4689
6125
|
txHash: intent.privacyLevel === "transparent" ? txHash : void 0,
|
|
4690
6126
|
fulfillmentProof: {
|
|
4691
6127
|
type: "fulfillment",
|
|
4692
|
-
proof: `0x${(0,
|
|
6128
|
+
proof: `0x${(0, import_utils10.bytesToHex)((0, import_utils10.randomBytes)(128))}`,
|
|
4693
6129
|
publicInputs: [
|
|
4694
|
-
`0x${(0,
|
|
4695
|
-
`0x${(0,
|
|
6130
|
+
`0x${(0, import_utils10.bytesToHex)(new TextEncoder().encode(intent.intentId))}`,
|
|
6131
|
+
`0x${(0, import_utils10.bytesToHex)(new TextEncoder().encode(quote.quoteId))}`
|
|
4696
6132
|
]
|
|
4697
6133
|
},
|
|
4698
6134
|
fulfilledAt: Math.floor(Date.now() / 1e3)
|
|
@@ -4730,10 +6166,10 @@ function createMockSolver(config) {
|
|
|
4730
6166
|
}
|
|
4731
6167
|
|
|
4732
6168
|
// src/index.ts
|
|
4733
|
-
var
|
|
6169
|
+
var import_types37 = require("@sip-protocol/types");
|
|
4734
6170
|
|
|
4735
6171
|
// src/zcash/rpc-client.ts
|
|
4736
|
-
var
|
|
6172
|
+
var import_types8 = require("@sip-protocol/types");
|
|
4737
6173
|
var DEFAULT_CONFIG = {
|
|
4738
6174
|
host: "127.0.0.1",
|
|
4739
6175
|
port: 8232,
|
|
@@ -4753,19 +6189,19 @@ var ZcashRPCError = class extends Error {
|
|
|
4753
6189
|
* Check if error is due to insufficient funds
|
|
4754
6190
|
*/
|
|
4755
6191
|
isInsufficientFunds() {
|
|
4756
|
-
return this.code ===
|
|
6192
|
+
return this.code === import_types8.ZcashErrorCode.WALLET_INSUFFICIENT_FUNDS;
|
|
4757
6193
|
}
|
|
4758
6194
|
/**
|
|
4759
6195
|
* Check if error is due to invalid address
|
|
4760
6196
|
*/
|
|
4761
6197
|
isInvalidAddress() {
|
|
4762
|
-
return this.code ===
|
|
6198
|
+
return this.code === import_types8.ZcashErrorCode.INVALID_ADDRESS_OR_KEY;
|
|
4763
6199
|
}
|
|
4764
6200
|
/**
|
|
4765
6201
|
* Check if error is due to wallet being locked
|
|
4766
6202
|
*/
|
|
4767
6203
|
isWalletLocked() {
|
|
4768
|
-
return this.code ===
|
|
6204
|
+
return this.code === import_types8.ZcashErrorCode.WALLET_UNLOCK_NEEDED;
|
|
4769
6205
|
}
|
|
4770
6206
|
};
|
|
4771
6207
|
var ZcashRPCClient = class {
|
|
@@ -5152,7 +6588,7 @@ function createZcashClient(config) {
|
|
|
5152
6588
|
}
|
|
5153
6589
|
|
|
5154
6590
|
// src/zcash/shielded-service.ts
|
|
5155
|
-
var
|
|
6591
|
+
var import_types9 = require("@sip-protocol/types");
|
|
5156
6592
|
var ZcashShieldedService = class _ZcashShieldedService {
|
|
5157
6593
|
client;
|
|
5158
6594
|
config;
|
|
@@ -5338,7 +6774,7 @@ var ZcashShieldedService = class _ZcashShieldedService {
|
|
|
5338
6774
|
* Higher-level method that handles privacy level mapping.
|
|
5339
6775
|
*/
|
|
5340
6776
|
async sendWithPrivacy(to, amount, privacyLevel, memo) {
|
|
5341
|
-
if (privacyLevel ===
|
|
6777
|
+
if (privacyLevel === import_types9.PrivacyLevel.TRANSPARENT) {
|
|
5342
6778
|
throw new ValidationError(
|
|
5343
6779
|
"Transparent mode not supported for Zcash shielded service. Use standard RPC client.",
|
|
5344
6780
|
"privacyLevel",
|
|
@@ -5432,7 +6868,7 @@ var ZcashShieldedService = class _ZcashShieldedService {
|
|
|
5432
6868
|
const viewingKey = await this.exportViewingKey();
|
|
5433
6869
|
return {
|
|
5434
6870
|
viewingKey,
|
|
5435
|
-
privacyLevel:
|
|
6871
|
+
privacyLevel: import_types9.PrivacyLevel.COMPLIANT,
|
|
5436
6872
|
disclaimer: "This viewing key provides read-only access to transaction history. It cannot be used to spend funds. Share only with authorized auditors."
|
|
5437
6873
|
};
|
|
5438
6874
|
}
|
|
@@ -5518,11 +6954,11 @@ var ZcashShieldedService = class _ZcashShieldedService {
|
|
|
5518
6954
|
*/
|
|
5519
6955
|
mapPrivacyLevelToPolicy(level) {
|
|
5520
6956
|
switch (level) {
|
|
5521
|
-
case
|
|
6957
|
+
case import_types9.PrivacyLevel.TRANSPARENT:
|
|
5522
6958
|
return "NoPrivacy";
|
|
5523
|
-
case
|
|
6959
|
+
case import_types9.PrivacyLevel.SHIELDED:
|
|
5524
6960
|
return "FullPrivacy";
|
|
5525
|
-
case
|
|
6961
|
+
case import_types9.PrivacyLevel.COMPLIANT:
|
|
5526
6962
|
return "FullPrivacy";
|
|
5527
6963
|
default:
|
|
5528
6964
|
return "FullPrivacy";
|
|
@@ -5575,15 +7011,15 @@ function createZcashShieldedService(config) {
|
|
|
5575
7011
|
}
|
|
5576
7012
|
|
|
5577
7013
|
// src/zcash/index.ts
|
|
5578
|
-
var
|
|
7014
|
+
var import_types10 = require("@sip-protocol/types");
|
|
5579
7015
|
|
|
5580
7016
|
// src/index.ts
|
|
5581
|
-
var
|
|
7017
|
+
var import_types38 = require("@sip-protocol/types");
|
|
5582
7018
|
|
|
5583
7019
|
// src/payment/payment.ts
|
|
5584
|
-
var
|
|
5585
|
-
var
|
|
5586
|
-
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");
|
|
5587
7023
|
var import_chacha2 = require("@noble/ciphers/chacha.js");
|
|
5588
7024
|
var import_hkdf2 = require("@noble/hashes/hkdf");
|
|
5589
7025
|
|
|
@@ -5768,7 +7204,7 @@ var PaymentBuilder = class {
|
|
|
5768
7204
|
_amount;
|
|
5769
7205
|
_recipientMetaAddress;
|
|
5770
7206
|
_recipientAddress;
|
|
5771
|
-
_privacy =
|
|
7207
|
+
_privacy = import_types11.PrivacyLevel.SHIELDED;
|
|
5772
7208
|
_viewingKey;
|
|
5773
7209
|
_sourceChain;
|
|
5774
7210
|
_destinationChain;
|
|
@@ -6051,7 +7487,7 @@ async function createShieldedPayment(params, options) {
|
|
|
6051
7487
|
} else {
|
|
6052
7488
|
resolvedToken = token;
|
|
6053
7489
|
}
|
|
6054
|
-
if (privacy !==
|
|
7490
|
+
if (privacy !== import_types11.PrivacyLevel.TRANSPARENT && !recipientMetaAddress) {
|
|
6055
7491
|
throw new ValidationError(
|
|
6056
7492
|
"recipientMetaAddress is required for shielded/compliant privacy modes",
|
|
6057
7493
|
"recipientMetaAddress",
|
|
@@ -6059,7 +7495,7 @@ async function createShieldedPayment(params, options) {
|
|
|
6059
7495
|
"SIP_2008" /* MISSING_REQUIRED */
|
|
6060
7496
|
);
|
|
6061
7497
|
}
|
|
6062
|
-
if (privacy ===
|
|
7498
|
+
if (privacy === import_types11.PrivacyLevel.TRANSPARENT && !recipientAddress) {
|
|
6063
7499
|
throw new ValidationError(
|
|
6064
7500
|
"recipientAddress is required for transparent mode",
|
|
6065
7501
|
"recipientAddress",
|
|
@@ -6067,7 +7503,7 @@ async function createShieldedPayment(params, options) {
|
|
|
6067
7503
|
"SIP_2008" /* MISSING_REQUIRED */
|
|
6068
7504
|
);
|
|
6069
7505
|
}
|
|
6070
|
-
if (privacy ===
|
|
7506
|
+
if (privacy === import_types11.PrivacyLevel.COMPLIANT && !viewingKey) {
|
|
6071
7507
|
throw new ValidationError(
|
|
6072
7508
|
"viewingKey is required for compliant mode",
|
|
6073
7509
|
"viewingKey",
|
|
@@ -6079,8 +7515,8 @@ async function createShieldedPayment(params, options) {
|
|
|
6079
7515
|
let viewingKeyHash;
|
|
6080
7516
|
if (viewingKey) {
|
|
6081
7517
|
const keyHex = viewingKey.startsWith("0x") ? viewingKey.slice(2) : viewingKey;
|
|
6082
|
-
const keyBytes = (0,
|
|
6083
|
-
viewingKeyHash = `0x${(0,
|
|
7518
|
+
const keyBytes = (0, import_utils11.hexToBytes)(keyHex);
|
|
7519
|
+
viewingKeyHash = `0x${(0, import_utils11.bytesToHex)((0, import_sha2569.sha256)(keyBytes))}`;
|
|
6084
7520
|
}
|
|
6085
7521
|
const privacyConfig = getPrivacyConfig(
|
|
6086
7522
|
privacy,
|
|
@@ -6089,7 +7525,7 @@ async function createShieldedPayment(params, options) {
|
|
|
6089
7525
|
const now = Math.floor(Date.now() / 1e3);
|
|
6090
7526
|
const payment = {
|
|
6091
7527
|
paymentId,
|
|
6092
|
-
version:
|
|
7528
|
+
version: import_types11.SIP_VERSION,
|
|
6093
7529
|
privacyLevel: privacy,
|
|
6094
7530
|
createdAt: now,
|
|
6095
7531
|
expiry: now + ttl,
|
|
@@ -6100,7 +7536,7 @@ async function createShieldedPayment(params, options) {
|
|
|
6100
7536
|
purpose,
|
|
6101
7537
|
viewingKeyHash
|
|
6102
7538
|
};
|
|
6103
|
-
if (privacy !==
|
|
7539
|
+
if (privacy !== import_types11.PrivacyLevel.TRANSPARENT && recipientMetaAddress) {
|
|
6104
7540
|
const metaAddress = decodeStealthMetaAddress(recipientMetaAddress);
|
|
6105
7541
|
const { stealthAddress } = generateStealthAddress(metaAddress);
|
|
6106
7542
|
payment.recipientStealth = stealthAddress;
|
|
@@ -6117,10 +7553,10 @@ async function createShieldedPayment(params, options) {
|
|
|
6117
7553
|
payment.recipientAddress = recipientAddress;
|
|
6118
7554
|
payment.memo = memo;
|
|
6119
7555
|
}
|
|
6120
|
-
if (privacy !==
|
|
7556
|
+
if (privacy !== import_types11.PrivacyLevel.TRANSPARENT && proofProvider?.isReady) {
|
|
6121
7557
|
const hexToUint8 = (hex) => {
|
|
6122
7558
|
const cleanHex = hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
6123
|
-
return (0,
|
|
7559
|
+
return (0, import_utils11.hexToBytes)(cleanHex);
|
|
6124
7560
|
};
|
|
6125
7561
|
const fundingResult = await proofProvider.generateFundingProof({
|
|
6126
7562
|
balance: amount,
|
|
@@ -6147,17 +7583,17 @@ async function createShieldedPayment(params, options) {
|
|
|
6147
7583
|
}
|
|
6148
7584
|
function encryptMemo(memo, viewingKey) {
|
|
6149
7585
|
const keyHex = viewingKey.startsWith("0x") ? viewingKey.slice(2) : viewingKey;
|
|
6150
|
-
const keyBytes = (0,
|
|
6151
|
-
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);
|
|
6152
7588
|
try {
|
|
6153
|
-
const nonce = (0,
|
|
7589
|
+
const nonce = (0, import_utils11.randomBytes)(24);
|
|
6154
7590
|
const cipher = (0, import_chacha2.xchacha20poly1305)(encKey, nonce);
|
|
6155
7591
|
const plaintext = new TextEncoder().encode(memo);
|
|
6156
7592
|
const ciphertext = cipher.encrypt(plaintext);
|
|
6157
7593
|
const result = new Uint8Array(nonce.length + ciphertext.length);
|
|
6158
7594
|
result.set(nonce);
|
|
6159
7595
|
result.set(ciphertext, nonce.length);
|
|
6160
|
-
return `0x${(0,
|
|
7596
|
+
return `0x${(0, import_utils11.bytesToHex)(result)}`;
|
|
6161
7597
|
} finally {
|
|
6162
7598
|
secureWipe(keyBytes);
|
|
6163
7599
|
secureWipe(encKey);
|
|
@@ -6165,11 +7601,11 @@ function encryptMemo(memo, viewingKey) {
|
|
|
6165
7601
|
}
|
|
6166
7602
|
function decryptMemo(encryptedMemo, viewingKey) {
|
|
6167
7603
|
const keyHex = viewingKey.startsWith("0x") ? viewingKey.slice(2) : viewingKey;
|
|
6168
|
-
const keyBytes = (0,
|
|
6169
|
-
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);
|
|
6170
7606
|
try {
|
|
6171
7607
|
const dataHex = encryptedMemo.startsWith("0x") ? encryptedMemo.slice(2) : encryptedMemo;
|
|
6172
|
-
const data = (0,
|
|
7608
|
+
const data = (0, import_utils11.hexToBytes)(dataHex);
|
|
6173
7609
|
const nonce = data.slice(0, 24);
|
|
6174
7610
|
const ciphertext = data.slice(24);
|
|
6175
7611
|
const cipher = (0, import_chacha2.xchacha20poly1305)(encKey, nonce);
|
|
@@ -6183,7 +7619,7 @@ function decryptMemo(encryptedMemo, viewingKey) {
|
|
|
6183
7619
|
function trackPayment(payment) {
|
|
6184
7620
|
return {
|
|
6185
7621
|
...payment,
|
|
6186
|
-
status:
|
|
7622
|
+
status: import_types11.PaymentStatus.DRAFT
|
|
6187
7623
|
};
|
|
6188
7624
|
}
|
|
6189
7625
|
function isPaymentExpired(payment) {
|
|
@@ -6216,10 +7652,10 @@ function getPaymentSummary(payment) {
|
|
|
6216
7652
|
}
|
|
6217
7653
|
|
|
6218
7654
|
// src/treasury/treasury.ts
|
|
6219
|
-
var
|
|
6220
|
-
var
|
|
6221
|
-
var
|
|
6222
|
-
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");
|
|
6223
7659
|
var DEFAULT_PROPOSAL_TTL = 7 * 24 * 60 * 60;
|
|
6224
7660
|
var Treasury = class _Treasury {
|
|
6225
7661
|
config;
|
|
@@ -6249,7 +7685,7 @@ var Treasury = class _Treasury {
|
|
|
6249
7685
|
...m,
|
|
6250
7686
|
addedAt: now
|
|
6251
7687
|
})),
|
|
6252
|
-
defaultPrivacy: params.defaultPrivacy ??
|
|
7688
|
+
defaultPrivacy: params.defaultPrivacy ?? import_types12.PrivacyLevel.SHIELDED,
|
|
6253
7689
|
masterViewingKey,
|
|
6254
7690
|
dailyLimit: params.dailyLimit,
|
|
6255
7691
|
transactionLimit: params.transactionLimit,
|
|
@@ -6328,7 +7764,7 @@ var Treasury = class _Treasury {
|
|
|
6328
7764
|
proposalId,
|
|
6329
7765
|
treasuryId: this.config.treasuryId,
|
|
6330
7766
|
type: "payment",
|
|
6331
|
-
status:
|
|
7767
|
+
status: import_types12.ProposalStatus.PENDING,
|
|
6332
7768
|
proposer: "",
|
|
6333
7769
|
// Should be set by caller
|
|
6334
7770
|
title: params.title,
|
|
@@ -6361,7 +7797,7 @@ var Treasury = class _Treasury {
|
|
|
6361
7797
|
proposalId,
|
|
6362
7798
|
treasuryId: this.config.treasuryId,
|
|
6363
7799
|
type: "batch_payment",
|
|
6364
|
-
status:
|
|
7800
|
+
status: import_types12.ProposalStatus.PENDING,
|
|
6365
7801
|
proposer: "",
|
|
6366
7802
|
title: params.title,
|
|
6367
7803
|
description: params.description,
|
|
@@ -6395,7 +7831,7 @@ var Treasury = class _Treasury {
|
|
|
6395
7831
|
* Get pending proposals
|
|
6396
7832
|
*/
|
|
6397
7833
|
getPendingProposals() {
|
|
6398
|
-
return this.getAllProposals().filter((p) => p.status ===
|
|
7834
|
+
return this.getAllProposals().filter((p) => p.status === import_types12.ProposalStatus.PENDING);
|
|
6399
7835
|
}
|
|
6400
7836
|
/**
|
|
6401
7837
|
* Sign a proposal
|
|
@@ -6426,7 +7862,7 @@ var Treasury = class _Treasury {
|
|
|
6426
7862
|
"SIP_2001" /* INVALID_INPUT */
|
|
6427
7863
|
);
|
|
6428
7864
|
}
|
|
6429
|
-
if (proposal.status !==
|
|
7865
|
+
if (proposal.status !== import_types12.ProposalStatus.PENDING) {
|
|
6430
7866
|
throw new ValidationError(
|
|
6431
7867
|
`proposal is not pending: ${proposal.status}`,
|
|
6432
7868
|
"proposalId",
|
|
@@ -6436,7 +7872,7 @@ var Treasury = class _Treasury {
|
|
|
6436
7872
|
}
|
|
6437
7873
|
const now = Math.floor(Date.now() / 1e3);
|
|
6438
7874
|
if (now > proposal.expiresAt) {
|
|
6439
|
-
proposal.status =
|
|
7875
|
+
proposal.status = import_types12.ProposalStatus.EXPIRED;
|
|
6440
7876
|
throw new ValidationError(
|
|
6441
7877
|
"proposal has expired",
|
|
6442
7878
|
"proposalId",
|
|
@@ -6468,9 +7904,9 @@ var Treasury = class _Treasury {
|
|
|
6468
7904
|
const approvals = proposal.signatures.filter((s) => s.approved).length;
|
|
6469
7905
|
const rejections = proposal.signatures.filter((s) => !s.approved).length;
|
|
6470
7906
|
if (approvals >= proposal.requiredSignatures) {
|
|
6471
|
-
proposal.status =
|
|
7907
|
+
proposal.status = import_types12.ProposalStatus.APPROVED;
|
|
6472
7908
|
} else if (rejections > this.config.totalSigners - proposal.requiredSignatures) {
|
|
6473
|
-
proposal.status =
|
|
7909
|
+
proposal.status = import_types12.ProposalStatus.REJECTED;
|
|
6474
7910
|
}
|
|
6475
7911
|
return proposal;
|
|
6476
7912
|
}
|
|
@@ -6487,7 +7923,7 @@ var Treasury = class _Treasury {
|
|
|
6487
7923
|
"SIP_2001" /* INVALID_INPUT */
|
|
6488
7924
|
);
|
|
6489
7925
|
}
|
|
6490
|
-
if (proposal.status !==
|
|
7926
|
+
if (proposal.status !== import_types12.ProposalStatus.APPROVED) {
|
|
6491
7927
|
throw new ValidationError(
|
|
6492
7928
|
`proposal is not approved: ${proposal.status}`,
|
|
6493
7929
|
"proposalId",
|
|
@@ -6500,8 +7936,8 @@ var Treasury = class _Treasury {
|
|
|
6500
7936
|
const payment = await createShieldedPayment({
|
|
6501
7937
|
token: proposal.payment.token,
|
|
6502
7938
|
amount: proposal.payment.amount,
|
|
6503
|
-
recipientMetaAddress: proposal.payment.privacy !==
|
|
6504
|
-
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,
|
|
6505
7941
|
privacy: proposal.payment.privacy,
|
|
6506
7942
|
viewingKey: this.config.masterViewingKey?.key,
|
|
6507
7943
|
sourceChain: this.config.chain,
|
|
@@ -6514,8 +7950,8 @@ var Treasury = class _Treasury {
|
|
|
6514
7950
|
const payment = await createShieldedPayment({
|
|
6515
7951
|
token: proposal.batchPayment.token,
|
|
6516
7952
|
amount: recipient.amount,
|
|
6517
|
-
recipientMetaAddress: proposal.batchPayment.privacy !==
|
|
6518
|
-
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,
|
|
6519
7955
|
privacy: proposal.batchPayment.privacy,
|
|
6520
7956
|
viewingKey: this.config.masterViewingKey?.key,
|
|
6521
7957
|
sourceChain: this.config.chain,
|
|
@@ -6525,7 +7961,7 @@ var Treasury = class _Treasury {
|
|
|
6525
7961
|
payments.push(payment);
|
|
6526
7962
|
}
|
|
6527
7963
|
}
|
|
6528
|
-
proposal.status =
|
|
7964
|
+
proposal.status = import_types12.ProposalStatus.EXECUTED;
|
|
6529
7965
|
proposal.executedAt = Math.floor(Date.now() / 1e3);
|
|
6530
7966
|
proposal.resultPayments = payments;
|
|
6531
7967
|
return payments;
|
|
@@ -6554,7 +7990,7 @@ var Treasury = class _Treasury {
|
|
|
6554
7990
|
"SIP_2001" /* INVALID_INPUT */
|
|
6555
7991
|
);
|
|
6556
7992
|
}
|
|
6557
|
-
if (proposal.status !==
|
|
7993
|
+
if (proposal.status !== import_types12.ProposalStatus.PENDING) {
|
|
6558
7994
|
throw new ValidationError(
|
|
6559
7995
|
`proposal is not pending: ${proposal.status}`,
|
|
6560
7996
|
"proposalId",
|
|
@@ -6562,7 +7998,7 @@ var Treasury = class _Treasury {
|
|
|
6562
7998
|
"SIP_2001" /* INVALID_INPUT */
|
|
6563
7999
|
);
|
|
6564
8000
|
}
|
|
6565
|
-
proposal.status =
|
|
8001
|
+
proposal.status = import_types12.ProposalStatus.CANCELLED;
|
|
6566
8002
|
return proposal;
|
|
6567
8003
|
}
|
|
6568
8004
|
// ─── Auditor Access ──────────────────────────────────────────────────────────
|
|
@@ -6659,7 +8095,7 @@ var Treasury = class _Treasury {
|
|
|
6659
8095
|
getCommittedAmount(token) {
|
|
6660
8096
|
let committed = 0n;
|
|
6661
8097
|
for (const proposal of this.proposals.values()) {
|
|
6662
|
-
if (proposal.status !==
|
|
8098
|
+
if (proposal.status !== import_types12.ProposalStatus.PENDING) continue;
|
|
6663
8099
|
if (proposal.type === "payment" && proposal.payment) {
|
|
6664
8100
|
if (proposal.payment.token.symbol === token.symbol && proposal.payment.token.chain === token.chain) {
|
|
6665
8101
|
committed += proposal.payment.amount;
|
|
@@ -6710,12 +8146,12 @@ var Treasury = class _Treasury {
|
|
|
6710
8146
|
}
|
|
6711
8147
|
};
|
|
6712
8148
|
function generateTreasuryId() {
|
|
6713
|
-
const bytes = (0,
|
|
6714
|
-
return `treasury_${(0,
|
|
8149
|
+
const bytes = (0, import_utils12.randomBytes)(16);
|
|
8150
|
+
return `treasury_${(0, import_utils12.bytesToHex)(bytes)}`;
|
|
6715
8151
|
}
|
|
6716
8152
|
function generateProposalId() {
|
|
6717
|
-
const bytes = (0,
|
|
6718
|
-
return `prop_${(0,
|
|
8153
|
+
const bytes = (0, import_utils12.randomBytes)(16);
|
|
8154
|
+
return `prop_${(0, import_utils12.bytesToHex)(bytes)}`;
|
|
6719
8155
|
}
|
|
6720
8156
|
function computeProposalHash(proposal) {
|
|
6721
8157
|
const data = JSON.stringify({
|
|
@@ -6727,13 +8163,13 @@ function computeProposalHash(proposal) {
|
|
|
6727
8163
|
createdAt: proposal.createdAt,
|
|
6728
8164
|
expiresAt: proposal.expiresAt
|
|
6729
8165
|
}, (_, value) => typeof value === "bigint" ? value.toString() : value);
|
|
6730
|
-
return (0,
|
|
8166
|
+
return (0, import_sha25610.sha256)(new TextEncoder().encode(data));
|
|
6731
8167
|
}
|
|
6732
8168
|
function signMessage(messageHash, privateKey) {
|
|
6733
8169
|
const keyHex = privateKey.startsWith("0x") ? privateKey.slice(2) : privateKey;
|
|
6734
|
-
const keyBytes = (0,
|
|
8170
|
+
const keyBytes = (0, import_utils12.hexToBytes)(keyHex);
|
|
6735
8171
|
try {
|
|
6736
|
-
const signature =
|
|
8172
|
+
const signature = import_secp256k15.secp256k1.sign(messageHash, keyBytes);
|
|
6737
8173
|
return `0x${signature.toCompactHex()}`;
|
|
6738
8174
|
} finally {
|
|
6739
8175
|
secureWipe(keyBytes);
|
|
@@ -6743,9 +8179,9 @@ function verifySignature(messageHash, signature, publicKey) {
|
|
|
6743
8179
|
const sigHex = signature.startsWith("0x") ? signature.slice(2) : signature;
|
|
6744
8180
|
const pubKeyHex = publicKey.startsWith("0x") ? publicKey.slice(2) : publicKey;
|
|
6745
8181
|
try {
|
|
6746
|
-
const sigBytes = (0,
|
|
6747
|
-
const pubKeyBytes = (0,
|
|
6748
|
-
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);
|
|
6749
8185
|
} catch {
|
|
6750
8186
|
return false;
|
|
6751
8187
|
}
|
|
@@ -6902,8 +8338,8 @@ function validateBatchProposalParams(params, config) {
|
|
|
6902
8338
|
}
|
|
6903
8339
|
|
|
6904
8340
|
// src/compliance/compliance-manager.ts
|
|
6905
|
-
var
|
|
6906
|
-
var
|
|
8341
|
+
var import_types13 = require("@sip-protocol/types");
|
|
8342
|
+
var import_utils13 = require("@noble/hashes/utils");
|
|
6907
8343
|
var DEFAULTS2 = {
|
|
6908
8344
|
riskThreshold: 70,
|
|
6909
8345
|
highValueThreshold: 10000000000n,
|
|
@@ -7270,7 +8706,7 @@ var ComplianceManager = class _ComplianceManager {
|
|
|
7270
8706
|
title: params.title,
|
|
7271
8707
|
description: params.description,
|
|
7272
8708
|
format: params.format,
|
|
7273
|
-
status:
|
|
8709
|
+
status: import_types13.ReportStatus.GENERATING,
|
|
7274
8710
|
requestedBy,
|
|
7275
8711
|
requestedAt: now,
|
|
7276
8712
|
startDate: params.startDate,
|
|
@@ -7299,10 +8735,10 @@ var ComplianceManager = class _ComplianceManager {
|
|
|
7299
8735
|
} else if (params.format === "csv") {
|
|
7300
8736
|
report.content = this.generateCSV(transactions);
|
|
7301
8737
|
}
|
|
7302
|
-
report.status =
|
|
8738
|
+
report.status = import_types13.ReportStatus.COMPLETED;
|
|
7303
8739
|
report.generatedAt = Math.floor(Date.now() / 1e3);
|
|
7304
8740
|
} catch (error) {
|
|
7305
|
-
report.status =
|
|
8741
|
+
report.status = import_types13.ReportStatus.FAILED;
|
|
7306
8742
|
report.error = error instanceof Error ? error.message : "Unknown error";
|
|
7307
8743
|
}
|
|
7308
8744
|
this.addAuditLog(requestedBy, "report_generated", {
|
|
@@ -7577,7 +9013,7 @@ var ComplianceManager = class _ComplianceManager {
|
|
|
7577
9013
|
}
|
|
7578
9014
|
};
|
|
7579
9015
|
function generateId(prefix) {
|
|
7580
|
-
return `${prefix}_${(0,
|
|
9016
|
+
return `${prefix}_${(0, import_utils13.bytesToHex)((0, import_utils13.randomBytes)(12))}`;
|
|
7581
9017
|
}
|
|
7582
9018
|
function validateRegisterAuditorParams(params) {
|
|
7583
9019
|
if (!params.organization?.trim()) {
|
|
@@ -7665,10 +9101,10 @@ function validateReportParams(params) {
|
|
|
7665
9101
|
}
|
|
7666
9102
|
|
|
7667
9103
|
// src/wallet/errors.ts
|
|
7668
|
-
var
|
|
9104
|
+
var import_types14 = require("@sip-protocol/types");
|
|
7669
9105
|
var WalletError = class extends SIPError {
|
|
7670
9106
|
walletCode;
|
|
7671
|
-
constructor(message, walletCode =
|
|
9107
|
+
constructor(message, walletCode = import_types14.WalletErrorCode.UNKNOWN, options) {
|
|
7672
9108
|
super(message, "SIP_7000" /* WALLET_ERROR */, options);
|
|
7673
9109
|
this.walletCode = walletCode;
|
|
7674
9110
|
this.name = "WalletError";
|
|
@@ -7678,10 +9114,10 @@ var WalletError = class extends SIPError {
|
|
|
7678
9114
|
*/
|
|
7679
9115
|
isConnectionError() {
|
|
7680
9116
|
const codes = [
|
|
7681
|
-
|
|
7682
|
-
|
|
7683
|
-
|
|
7684
|
-
|
|
9117
|
+
import_types14.WalletErrorCode.NOT_INSTALLED,
|
|
9118
|
+
import_types14.WalletErrorCode.CONNECTION_REJECTED,
|
|
9119
|
+
import_types14.WalletErrorCode.CONNECTION_FAILED,
|
|
9120
|
+
import_types14.WalletErrorCode.NOT_CONNECTED
|
|
7685
9121
|
];
|
|
7686
9122
|
return codes.includes(this.walletCode);
|
|
7687
9123
|
}
|
|
@@ -7690,9 +9126,9 @@ var WalletError = class extends SIPError {
|
|
|
7690
9126
|
*/
|
|
7691
9127
|
isSigningError() {
|
|
7692
9128
|
const codes = [
|
|
7693
|
-
|
|
7694
|
-
|
|
7695
|
-
|
|
9129
|
+
import_types14.WalletErrorCode.SIGNING_REJECTED,
|
|
9130
|
+
import_types14.WalletErrorCode.SIGNING_FAILED,
|
|
9131
|
+
import_types14.WalletErrorCode.INVALID_MESSAGE
|
|
7696
9132
|
];
|
|
7697
9133
|
return codes.includes(this.walletCode);
|
|
7698
9134
|
}
|
|
@@ -7701,10 +9137,10 @@ var WalletError = class extends SIPError {
|
|
|
7701
9137
|
*/
|
|
7702
9138
|
isTransactionError() {
|
|
7703
9139
|
const codes = [
|
|
7704
|
-
|
|
7705
|
-
|
|
7706
|
-
|
|
7707
|
-
|
|
9140
|
+
import_types14.WalletErrorCode.INSUFFICIENT_FUNDS,
|
|
9141
|
+
import_types14.WalletErrorCode.TRANSACTION_REJECTED,
|
|
9142
|
+
import_types14.WalletErrorCode.TRANSACTION_FAILED,
|
|
9143
|
+
import_types14.WalletErrorCode.INVALID_TRANSACTION
|
|
7708
9144
|
];
|
|
7709
9145
|
return codes.includes(this.walletCode);
|
|
7710
9146
|
}
|
|
@@ -7713,9 +9149,9 @@ var WalletError = class extends SIPError {
|
|
|
7713
9149
|
*/
|
|
7714
9150
|
isPrivacyError() {
|
|
7715
9151
|
const codes = [
|
|
7716
|
-
|
|
7717
|
-
|
|
7718
|
-
|
|
9152
|
+
import_types14.WalletErrorCode.STEALTH_NOT_SUPPORTED,
|
|
9153
|
+
import_types14.WalletErrorCode.VIEWING_KEY_NOT_SUPPORTED,
|
|
9154
|
+
import_types14.WalletErrorCode.SHIELDED_NOT_SUPPORTED
|
|
7719
9155
|
];
|
|
7720
9156
|
return codes.includes(this.walletCode);
|
|
7721
9157
|
}
|
|
@@ -7724,10 +9160,10 @@ var WalletError = class extends SIPError {
|
|
|
7724
9160
|
*/
|
|
7725
9161
|
isUserRejection() {
|
|
7726
9162
|
const codes = [
|
|
7727
|
-
|
|
7728
|
-
|
|
7729
|
-
|
|
7730
|
-
|
|
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
|
|
7731
9167
|
];
|
|
7732
9168
|
return codes.includes(this.walletCode);
|
|
7733
9169
|
}
|
|
@@ -7735,15 +9171,15 @@ var WalletError = class extends SIPError {
|
|
|
7735
9171
|
function notConnectedError() {
|
|
7736
9172
|
return new WalletError(
|
|
7737
9173
|
"Wallet not connected. Call connect() first.",
|
|
7738
|
-
|
|
9174
|
+
import_types14.WalletErrorCode.NOT_CONNECTED
|
|
7739
9175
|
);
|
|
7740
9176
|
}
|
|
7741
|
-
function featureNotSupportedError(feature, code =
|
|
9177
|
+
function featureNotSupportedError(feature, code = import_types14.WalletErrorCode.UNKNOWN) {
|
|
7742
9178
|
return new WalletError(`${feature} is not supported by this wallet`, code);
|
|
7743
9179
|
}
|
|
7744
9180
|
|
|
7745
9181
|
// src/wallet/base-adapter.ts
|
|
7746
|
-
var
|
|
9182
|
+
var import_types15 = require("@sip-protocol/types");
|
|
7747
9183
|
var BaseWalletAdapter = class {
|
|
7748
9184
|
_address = "";
|
|
7749
9185
|
_publicKey = "";
|
|
@@ -7906,12 +9342,12 @@ var MockWalletAdapter = class extends BaseWalletAdapter {
|
|
|
7906
9342
|
this._connectionState = "connecting";
|
|
7907
9343
|
if (this.shouldFailConnect) {
|
|
7908
9344
|
this.setError(
|
|
7909
|
-
|
|
9345
|
+
import_types15.WalletErrorCode.CONNECTION_FAILED,
|
|
7910
9346
|
"Mock connection failure"
|
|
7911
9347
|
);
|
|
7912
9348
|
throw new WalletError(
|
|
7913
9349
|
"Mock connection failure",
|
|
7914
|
-
|
|
9350
|
+
import_types15.WalletErrorCode.CONNECTION_FAILED
|
|
7915
9351
|
);
|
|
7916
9352
|
}
|
|
7917
9353
|
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
@@ -7923,7 +9359,7 @@ var MockWalletAdapter = class extends BaseWalletAdapter {
|
|
|
7923
9359
|
async signMessage(message) {
|
|
7924
9360
|
this.requireConnected();
|
|
7925
9361
|
if (this.shouldFailSign) {
|
|
7926
|
-
throw new WalletError("Mock signing failure",
|
|
9362
|
+
throw new WalletError("Mock signing failure", import_types15.WalletErrorCode.SIGNING_FAILED);
|
|
7927
9363
|
}
|
|
7928
9364
|
const mockSig = new Uint8Array(64);
|
|
7929
9365
|
for (let i = 0; i < 64; i++) {
|
|
@@ -7938,7 +9374,7 @@ var MockWalletAdapter = class extends BaseWalletAdapter {
|
|
|
7938
9374
|
async signTransaction(tx) {
|
|
7939
9375
|
this.requireConnected();
|
|
7940
9376
|
if (this.shouldFailSign) {
|
|
7941
|
-
throw new WalletError("Mock signing failure",
|
|
9377
|
+
throw new WalletError("Mock signing failure", import_types15.WalletErrorCode.SIGNING_FAILED);
|
|
7942
9378
|
}
|
|
7943
9379
|
const signature = await this.signMessage(
|
|
7944
9380
|
new TextEncoder().encode(JSON.stringify(tx.data))
|
|
@@ -8120,7 +9556,7 @@ function isPrivateWalletAdapter(adapter) {
|
|
|
8120
9556
|
}
|
|
8121
9557
|
|
|
8122
9558
|
// src/wallet/solana/adapter.ts
|
|
8123
|
-
var
|
|
9559
|
+
var import_types16 = require("@sip-protocol/types");
|
|
8124
9560
|
|
|
8125
9561
|
// src/wallet/solana/types.ts
|
|
8126
9562
|
function getSolanaProvider(wallet = "phantom") {
|
|
@@ -8241,19 +9677,19 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
|
|
|
8241
9677
|
}
|
|
8242
9678
|
if (!this.provider) {
|
|
8243
9679
|
this.setError(
|
|
8244
|
-
|
|
9680
|
+
import_types16.WalletErrorCode.NOT_INSTALLED,
|
|
8245
9681
|
`${this.walletName} wallet is not installed`
|
|
8246
9682
|
);
|
|
8247
9683
|
throw new WalletError(
|
|
8248
9684
|
`${this.walletName} wallet is not installed`,
|
|
8249
|
-
|
|
9685
|
+
import_types16.WalletErrorCode.NOT_INSTALLED
|
|
8250
9686
|
);
|
|
8251
9687
|
}
|
|
8252
9688
|
const { publicKey } = await this.provider.connect();
|
|
8253
9689
|
if (!publicKey) {
|
|
8254
9690
|
throw new WalletError(
|
|
8255
9691
|
"No public key returned from wallet",
|
|
8256
|
-
|
|
9692
|
+
import_types16.WalletErrorCode.CONNECTION_FAILED
|
|
8257
9693
|
);
|
|
8258
9694
|
}
|
|
8259
9695
|
this.setupEventHandlers();
|
|
@@ -8263,11 +9699,11 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
|
|
|
8263
9699
|
} catch (error) {
|
|
8264
9700
|
const message = error instanceof Error ? error.message : "Connection failed";
|
|
8265
9701
|
if (message.includes("User rejected") || message.includes("rejected")) {
|
|
8266
|
-
this.setError(
|
|
8267
|
-
throw new WalletError(message,
|
|
9702
|
+
this.setError(import_types16.WalletErrorCode.CONNECTION_REJECTED, message);
|
|
9703
|
+
throw new WalletError(message, import_types16.WalletErrorCode.CONNECTION_REJECTED);
|
|
8268
9704
|
}
|
|
8269
|
-
this.setError(
|
|
8270
|
-
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 });
|
|
8271
9707
|
}
|
|
8272
9708
|
}
|
|
8273
9709
|
/**
|
|
@@ -8290,7 +9726,7 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
|
|
|
8290
9726
|
async signMessage(message) {
|
|
8291
9727
|
this.requireConnected();
|
|
8292
9728
|
if (!this.provider) {
|
|
8293
|
-
throw new WalletError("Provider not available",
|
|
9729
|
+
throw new WalletError("Provider not available", import_types16.WalletErrorCode.NOT_CONNECTED);
|
|
8294
9730
|
}
|
|
8295
9731
|
try {
|
|
8296
9732
|
const { signature } = await this.provider.signMessage(message);
|
|
@@ -8301,9 +9737,9 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
|
|
|
8301
9737
|
} catch (error) {
|
|
8302
9738
|
const message2 = error instanceof Error ? error.message : "Signing failed";
|
|
8303
9739
|
if (message2.includes("User rejected") || message2.includes("rejected")) {
|
|
8304
|
-
throw new WalletError(message2,
|
|
9740
|
+
throw new WalletError(message2, import_types16.WalletErrorCode.SIGNING_REJECTED);
|
|
8305
9741
|
}
|
|
8306
|
-
throw new WalletError(message2,
|
|
9742
|
+
throw new WalletError(message2, import_types16.WalletErrorCode.SIGNING_FAILED, {
|
|
8307
9743
|
cause: error
|
|
8308
9744
|
});
|
|
8309
9745
|
}
|
|
@@ -8316,7 +9752,7 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
|
|
|
8316
9752
|
async signTransaction(tx) {
|
|
8317
9753
|
this.requireConnected();
|
|
8318
9754
|
if (!this.provider) {
|
|
8319
|
-
throw new WalletError("Provider not available",
|
|
9755
|
+
throw new WalletError("Provider not available", import_types16.WalletErrorCode.NOT_CONNECTED);
|
|
8320
9756
|
}
|
|
8321
9757
|
try {
|
|
8322
9758
|
const solTx = tx.data;
|
|
@@ -8335,9 +9771,9 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
|
|
|
8335
9771
|
} catch (error) {
|
|
8336
9772
|
const message = error instanceof Error ? error.message : "Signing failed";
|
|
8337
9773
|
if (message.includes("User rejected") || message.includes("rejected")) {
|
|
8338
|
-
throw new WalletError(message,
|
|
9774
|
+
throw new WalletError(message, import_types16.WalletErrorCode.SIGNING_REJECTED);
|
|
8339
9775
|
}
|
|
8340
|
-
throw new WalletError(message,
|
|
9776
|
+
throw new WalletError(message, import_types16.WalletErrorCode.SIGNING_FAILED, {
|
|
8341
9777
|
cause: error
|
|
8342
9778
|
});
|
|
8343
9779
|
}
|
|
@@ -8348,7 +9784,7 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
|
|
|
8348
9784
|
async signAndSendTransaction(tx) {
|
|
8349
9785
|
this.requireConnected();
|
|
8350
9786
|
if (!this.provider) {
|
|
8351
|
-
throw new WalletError("Provider not available",
|
|
9787
|
+
throw new WalletError("Provider not available", import_types16.WalletErrorCode.NOT_CONNECTED);
|
|
8352
9788
|
}
|
|
8353
9789
|
try {
|
|
8354
9790
|
const solTx = tx.data;
|
|
@@ -8363,12 +9799,12 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
|
|
|
8363
9799
|
} catch (error) {
|
|
8364
9800
|
const message = error instanceof Error ? error.message : "Transaction failed";
|
|
8365
9801
|
if (message.includes("User rejected") || message.includes("rejected")) {
|
|
8366
|
-
throw new WalletError(message,
|
|
9802
|
+
throw new WalletError(message, import_types16.WalletErrorCode.TRANSACTION_REJECTED);
|
|
8367
9803
|
}
|
|
8368
9804
|
if (message.includes("insufficient") || message.includes("Insufficient")) {
|
|
8369
|
-
throw new WalletError(message,
|
|
9805
|
+
throw new WalletError(message, import_types16.WalletErrorCode.INSUFFICIENT_FUNDS);
|
|
8370
9806
|
}
|
|
8371
|
-
throw new WalletError(message,
|
|
9807
|
+
throw new WalletError(message, import_types16.WalletErrorCode.TRANSACTION_FAILED, {
|
|
8372
9808
|
cause: error
|
|
8373
9809
|
});
|
|
8374
9810
|
}
|
|
@@ -8381,16 +9817,16 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
|
|
|
8381
9817
|
async signAllTransactions(transactions) {
|
|
8382
9818
|
this.requireConnected();
|
|
8383
9819
|
if (!this.provider) {
|
|
8384
|
-
throw new WalletError("Provider not available",
|
|
9820
|
+
throw new WalletError("Provider not available", import_types16.WalletErrorCode.NOT_CONNECTED);
|
|
8385
9821
|
}
|
|
8386
9822
|
try {
|
|
8387
9823
|
return await this.provider.signAllTransactions(transactions);
|
|
8388
9824
|
} catch (error) {
|
|
8389
9825
|
const message = error instanceof Error ? error.message : "Signing failed";
|
|
8390
9826
|
if (message.includes("User rejected") || message.includes("rejected")) {
|
|
8391
|
-
throw new WalletError(message,
|
|
9827
|
+
throw new WalletError(message, import_types16.WalletErrorCode.SIGNING_REJECTED);
|
|
8392
9828
|
}
|
|
8393
|
-
throw new WalletError(message,
|
|
9829
|
+
throw new WalletError(message, import_types16.WalletErrorCode.SIGNING_FAILED, {
|
|
8394
9830
|
cause: error
|
|
8395
9831
|
});
|
|
8396
9832
|
}
|
|
@@ -8411,7 +9847,7 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
|
|
|
8411
9847
|
} catch (error) {
|
|
8412
9848
|
throw new WalletError(
|
|
8413
9849
|
"Failed to get balance",
|
|
8414
|
-
|
|
9850
|
+
import_types16.WalletErrorCode.UNKNOWN,
|
|
8415
9851
|
{ cause: error }
|
|
8416
9852
|
);
|
|
8417
9853
|
}
|
|
@@ -8424,7 +9860,7 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
|
|
|
8424
9860
|
if (asset.chain !== "solana") {
|
|
8425
9861
|
throw new WalletError(
|
|
8426
9862
|
`Asset chain ${asset.chain} not supported by Solana adapter`,
|
|
8427
|
-
|
|
9863
|
+
import_types16.WalletErrorCode.UNSUPPORTED_CHAIN
|
|
8428
9864
|
);
|
|
8429
9865
|
}
|
|
8430
9866
|
if (!asset.address) {
|
|
@@ -8542,7 +9978,7 @@ function createSolanaAdapter(config = {}) {
|
|
|
8542
9978
|
}
|
|
8543
9979
|
|
|
8544
9980
|
// src/wallet/solana/mock.ts
|
|
8545
|
-
var
|
|
9981
|
+
var import_types18 = require("@sip-protocol/types");
|
|
8546
9982
|
var MockPublicKey = class {
|
|
8547
9983
|
base58;
|
|
8548
9984
|
bytes;
|
|
@@ -8608,8 +10044,8 @@ var MockSolanaAdapter = class extends BaseWalletAdapter {
|
|
|
8608
10044
|
this._connectionState = "connecting";
|
|
8609
10045
|
await this.simulateLatency();
|
|
8610
10046
|
if (this.shouldFailConnect) {
|
|
8611
|
-
this.setError(
|
|
8612
|
-
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);
|
|
8613
10049
|
}
|
|
8614
10050
|
const hexPubKey = "0x" + Buffer.from(this.mockPublicKey.toBytes()).toString("hex");
|
|
8615
10051
|
this.setConnected(this.mockAddress, hexPubKey);
|
|
@@ -8628,7 +10064,7 @@ var MockSolanaAdapter = class extends BaseWalletAdapter {
|
|
|
8628
10064
|
this.requireConnected();
|
|
8629
10065
|
await this.simulateLatency();
|
|
8630
10066
|
if (this.shouldFailSign) {
|
|
8631
|
-
throw new WalletError("Mock signing failure",
|
|
10067
|
+
throw new WalletError("Mock signing failure", import_types18.WalletErrorCode.SIGNING_REJECTED);
|
|
8632
10068
|
}
|
|
8633
10069
|
const mockSig = new Uint8Array(64);
|
|
8634
10070
|
for (let i = 0; i < 64; i++) {
|
|
@@ -8646,7 +10082,7 @@ var MockSolanaAdapter = class extends BaseWalletAdapter {
|
|
|
8646
10082
|
this.requireConnected();
|
|
8647
10083
|
await this.simulateLatency();
|
|
8648
10084
|
if (this.shouldFailSign) {
|
|
8649
|
-
throw new WalletError("Mock signing failure",
|
|
10085
|
+
throw new WalletError("Mock signing failure", import_types18.WalletErrorCode.SIGNING_REJECTED);
|
|
8650
10086
|
}
|
|
8651
10087
|
const solTx = tx.data;
|
|
8652
10088
|
this.signedTransactions.push(solTx);
|
|
@@ -8666,10 +10102,10 @@ var MockSolanaAdapter = class extends BaseWalletAdapter {
|
|
|
8666
10102
|
this.requireConnected();
|
|
8667
10103
|
await this.simulateLatency();
|
|
8668
10104
|
if (this.shouldFailSign) {
|
|
8669
|
-
throw new WalletError("Mock signing failure",
|
|
10105
|
+
throw new WalletError("Mock signing failure", import_types18.WalletErrorCode.SIGNING_REJECTED);
|
|
8670
10106
|
}
|
|
8671
10107
|
if (this.shouldFailTransaction) {
|
|
8672
|
-
throw new WalletError("Mock transaction failure",
|
|
10108
|
+
throw new WalletError("Mock transaction failure", import_types18.WalletErrorCode.TRANSACTION_FAILED);
|
|
8673
10109
|
}
|
|
8674
10110
|
const txSig = `mock_tx_${Date.now()}_${Math.random().toString(36).slice(2)}`;
|
|
8675
10111
|
this.sentTransactions.push(txSig);
|
|
@@ -8689,7 +10125,7 @@ var MockSolanaAdapter = class extends BaseWalletAdapter {
|
|
|
8689
10125
|
this.requireConnected();
|
|
8690
10126
|
await this.simulateLatency();
|
|
8691
10127
|
if (this.shouldFailSign) {
|
|
8692
|
-
throw new WalletError("Mock signing failure",
|
|
10128
|
+
throw new WalletError("Mock signing failure", import_types18.WalletErrorCode.SIGNING_REJECTED);
|
|
8693
10129
|
}
|
|
8694
10130
|
this.signedTransactions.push(...transactions);
|
|
8695
10131
|
return transactions.map((tx) => {
|
|
@@ -8716,7 +10152,7 @@ var MockSolanaAdapter = class extends BaseWalletAdapter {
|
|
|
8716
10152
|
if (asset.chain !== "solana") {
|
|
8717
10153
|
throw new WalletError(
|
|
8718
10154
|
`Asset chain ${asset.chain} not supported by Solana adapter`,
|
|
8719
|
-
|
|
10155
|
+
import_types18.WalletErrorCode.UNSUPPORTED_CHAIN
|
|
8720
10156
|
);
|
|
8721
10157
|
}
|
|
8722
10158
|
if (!asset.address) {
|
|
@@ -8885,7 +10321,7 @@ function createMockSolanaAdapter(config = {}) {
|
|
|
8885
10321
|
}
|
|
8886
10322
|
|
|
8887
10323
|
// src/wallet/ethereum/adapter.ts
|
|
8888
|
-
var
|
|
10324
|
+
var import_types20 = require("@sip-protocol/types");
|
|
8889
10325
|
|
|
8890
10326
|
// src/wallet/ethereum/types.ts
|
|
8891
10327
|
var EthereumChainId = {
|
|
@@ -9027,7 +10463,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9027
10463
|
this._connectionState = "error";
|
|
9028
10464
|
throw new WalletError(
|
|
9029
10465
|
`${this.walletType} wallet not found. Please install the extension.`,
|
|
9030
|
-
|
|
10466
|
+
import_types20.WalletErrorCode.NOT_INSTALLED
|
|
9031
10467
|
);
|
|
9032
10468
|
}
|
|
9033
10469
|
const accounts = await this.provider.request({
|
|
@@ -9037,7 +10473,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9037
10473
|
this._connectionState = "error";
|
|
9038
10474
|
throw new WalletError(
|
|
9039
10475
|
"No accounts returned from wallet",
|
|
9040
|
-
|
|
10476
|
+
import_types20.WalletErrorCode.CONNECTION_REJECTED
|
|
9041
10477
|
);
|
|
9042
10478
|
}
|
|
9043
10479
|
const address = normalizeAddress(accounts[0]);
|
|
@@ -9057,12 +10493,12 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9057
10493
|
if (rpcError.code === 4001) {
|
|
9058
10494
|
throw new WalletError(
|
|
9059
10495
|
"User rejected connection request",
|
|
9060
|
-
|
|
10496
|
+
import_types20.WalletErrorCode.CONNECTION_REJECTED
|
|
9061
10497
|
);
|
|
9062
10498
|
}
|
|
9063
10499
|
throw new WalletError(
|
|
9064
10500
|
`Failed to connect: ${rpcError.message || String(error)}`,
|
|
9065
|
-
|
|
10501
|
+
import_types20.WalletErrorCode.CONNECTION_FAILED
|
|
9066
10502
|
);
|
|
9067
10503
|
}
|
|
9068
10504
|
}
|
|
@@ -9082,7 +10518,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9082
10518
|
if (!this.provider) {
|
|
9083
10519
|
throw new WalletError(
|
|
9084
10520
|
"Provider not available",
|
|
9085
|
-
|
|
10521
|
+
import_types20.WalletErrorCode.NOT_CONNECTED
|
|
9086
10522
|
);
|
|
9087
10523
|
}
|
|
9088
10524
|
try {
|
|
@@ -9100,12 +10536,12 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9100
10536
|
if (rpcError.code === 4001) {
|
|
9101
10537
|
throw new WalletError(
|
|
9102
10538
|
"User rejected signing request",
|
|
9103
|
-
|
|
10539
|
+
import_types20.WalletErrorCode.SIGNING_REJECTED
|
|
9104
10540
|
);
|
|
9105
10541
|
}
|
|
9106
10542
|
throw new WalletError(
|
|
9107
10543
|
`Failed to sign message: ${rpcError.message || String(error)}`,
|
|
9108
|
-
|
|
10544
|
+
import_types20.WalletErrorCode.SIGNING_FAILED
|
|
9109
10545
|
);
|
|
9110
10546
|
}
|
|
9111
10547
|
}
|
|
@@ -9117,7 +10553,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9117
10553
|
if (!this.provider) {
|
|
9118
10554
|
throw new WalletError(
|
|
9119
10555
|
"Provider not available",
|
|
9120
|
-
|
|
10556
|
+
import_types20.WalletErrorCode.NOT_CONNECTED
|
|
9121
10557
|
);
|
|
9122
10558
|
}
|
|
9123
10559
|
try {
|
|
@@ -9134,12 +10570,12 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9134
10570
|
if (rpcError.code === 4001) {
|
|
9135
10571
|
throw new WalletError(
|
|
9136
10572
|
"User rejected signing request",
|
|
9137
|
-
|
|
10573
|
+
import_types20.WalletErrorCode.SIGNING_REJECTED
|
|
9138
10574
|
);
|
|
9139
10575
|
}
|
|
9140
10576
|
throw new WalletError(
|
|
9141
10577
|
`Failed to sign typed data: ${rpcError.message || String(error)}`,
|
|
9142
|
-
|
|
10578
|
+
import_types20.WalletErrorCode.SIGNING_FAILED
|
|
9143
10579
|
);
|
|
9144
10580
|
}
|
|
9145
10581
|
}
|
|
@@ -9151,7 +10587,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9151
10587
|
if (!this.provider) {
|
|
9152
10588
|
throw new WalletError(
|
|
9153
10589
|
"Provider not available",
|
|
9154
|
-
|
|
10590
|
+
import_types20.WalletErrorCode.NOT_CONNECTED
|
|
9155
10591
|
);
|
|
9156
10592
|
}
|
|
9157
10593
|
try {
|
|
@@ -9179,7 +10615,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9179
10615
|
if (rpcError.code === 4001) {
|
|
9180
10616
|
throw new WalletError(
|
|
9181
10617
|
"User rejected transaction signing",
|
|
9182
|
-
|
|
10618
|
+
import_types20.WalletErrorCode.SIGNING_REJECTED
|
|
9183
10619
|
);
|
|
9184
10620
|
}
|
|
9185
10621
|
if (rpcError.code === -32601 || rpcError.message?.includes("not supported")) {
|
|
@@ -9197,7 +10633,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9197
10633
|
}
|
|
9198
10634
|
throw new WalletError(
|
|
9199
10635
|
`Failed to sign transaction: ${rpcError.message || String(error)}`,
|
|
9200
|
-
|
|
10636
|
+
import_types20.WalletErrorCode.TRANSACTION_FAILED
|
|
9201
10637
|
);
|
|
9202
10638
|
}
|
|
9203
10639
|
}
|
|
@@ -9209,7 +10645,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9209
10645
|
if (!this.provider) {
|
|
9210
10646
|
throw new WalletError(
|
|
9211
10647
|
"Provider not available",
|
|
9212
|
-
|
|
10648
|
+
import_types20.WalletErrorCode.NOT_CONNECTED
|
|
9213
10649
|
);
|
|
9214
10650
|
}
|
|
9215
10651
|
try {
|
|
@@ -9231,12 +10667,12 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9231
10667
|
if (rpcError.code === 4001) {
|
|
9232
10668
|
throw new WalletError(
|
|
9233
10669
|
"User rejected transaction",
|
|
9234
|
-
|
|
10670
|
+
import_types20.WalletErrorCode.TRANSACTION_REJECTED
|
|
9235
10671
|
);
|
|
9236
10672
|
}
|
|
9237
10673
|
throw new WalletError(
|
|
9238
10674
|
`Failed to send transaction: ${rpcError.message || String(error)}`,
|
|
9239
|
-
|
|
10675
|
+
import_types20.WalletErrorCode.TRANSACTION_FAILED
|
|
9240
10676
|
);
|
|
9241
10677
|
}
|
|
9242
10678
|
}
|
|
@@ -9271,7 +10707,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9271
10707
|
} catch (error) {
|
|
9272
10708
|
throw new WalletError(
|
|
9273
10709
|
`Failed to fetch balance: ${String(error)}`,
|
|
9274
|
-
|
|
10710
|
+
import_types20.WalletErrorCode.UNKNOWN
|
|
9275
10711
|
);
|
|
9276
10712
|
}
|
|
9277
10713
|
}
|
|
@@ -9283,7 +10719,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9283
10719
|
if (asset.chain !== "ethereum") {
|
|
9284
10720
|
throw new WalletError(
|
|
9285
10721
|
`Asset chain ${asset.chain} not supported by Ethereum adapter`,
|
|
9286
|
-
|
|
10722
|
+
import_types20.WalletErrorCode.UNSUPPORTED_CHAIN
|
|
9287
10723
|
);
|
|
9288
10724
|
}
|
|
9289
10725
|
if (!asset.address) {
|
|
@@ -9308,7 +10744,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9308
10744
|
} catch (error) {
|
|
9309
10745
|
throw new WalletError(
|
|
9310
10746
|
`Failed to fetch token balance: ${String(error)}`,
|
|
9311
|
-
|
|
10747
|
+
import_types20.WalletErrorCode.UNKNOWN
|
|
9312
10748
|
);
|
|
9313
10749
|
}
|
|
9314
10750
|
}
|
|
@@ -9320,7 +10756,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9320
10756
|
if (!this.provider) {
|
|
9321
10757
|
throw new WalletError(
|
|
9322
10758
|
"Provider not available",
|
|
9323
|
-
|
|
10759
|
+
import_types20.WalletErrorCode.NOT_CONNECTED
|
|
9324
10760
|
);
|
|
9325
10761
|
}
|
|
9326
10762
|
try {
|
|
@@ -9335,18 +10771,18 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9335
10771
|
if (rpcError.code === 4001) {
|
|
9336
10772
|
throw new WalletError(
|
|
9337
10773
|
"User rejected chain switch",
|
|
9338
|
-
|
|
10774
|
+
import_types20.WalletErrorCode.CHAIN_SWITCH_REJECTED
|
|
9339
10775
|
);
|
|
9340
10776
|
}
|
|
9341
10777
|
if (rpcError.code === 4902) {
|
|
9342
10778
|
throw new WalletError(
|
|
9343
10779
|
`Chain ${chainId} not added to wallet`,
|
|
9344
|
-
|
|
10780
|
+
import_types20.WalletErrorCode.UNSUPPORTED_CHAIN
|
|
9345
10781
|
);
|
|
9346
10782
|
}
|
|
9347
10783
|
throw new WalletError(
|
|
9348
10784
|
`Failed to switch chain: ${rpcError.message || String(error)}`,
|
|
9349
|
-
|
|
10785
|
+
import_types20.WalletErrorCode.CHAIN_SWITCH_FAILED
|
|
9350
10786
|
);
|
|
9351
10787
|
}
|
|
9352
10788
|
}
|
|
@@ -9382,7 +10818,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9382
10818
|
}
|
|
9383
10819
|
throw new WalletError(
|
|
9384
10820
|
`Transaction ${txHash} not confirmed after ${maxAttempts * 5} seconds`,
|
|
9385
|
-
|
|
10821
|
+
import_types20.WalletErrorCode.TRANSACTION_FAILED
|
|
9386
10822
|
);
|
|
9387
10823
|
}
|
|
9388
10824
|
/**
|
|
@@ -9456,7 +10892,7 @@ function createEthereumAdapter(config) {
|
|
|
9456
10892
|
}
|
|
9457
10893
|
|
|
9458
10894
|
// src/wallet/ethereum/mock.ts
|
|
9459
|
-
var
|
|
10895
|
+
var import_types22 = require("@sip-protocol/types");
|
|
9460
10896
|
var MockEthereumAdapter = class extends BaseWalletAdapter {
|
|
9461
10897
|
chain = "ethereum";
|
|
9462
10898
|
name = "mock-ethereum";
|
|
@@ -9497,7 +10933,7 @@ var MockEthereumAdapter = class extends BaseWalletAdapter {
|
|
|
9497
10933
|
this._connectionState = "error";
|
|
9498
10934
|
throw new WalletError(
|
|
9499
10935
|
"Mock connection rejected",
|
|
9500
|
-
|
|
10936
|
+
import_types22.WalletErrorCode.CONNECTION_REJECTED
|
|
9501
10937
|
);
|
|
9502
10938
|
}
|
|
9503
10939
|
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
@@ -9509,7 +10945,7 @@ var MockEthereumAdapter = class extends BaseWalletAdapter {
|
|
|
9509
10945
|
this._connectionState = "error";
|
|
9510
10946
|
throw new WalletError(
|
|
9511
10947
|
`Mock connection failed: ${String(error)}`,
|
|
9512
|
-
|
|
10948
|
+
import_types22.WalletErrorCode.CONNECTION_FAILED
|
|
9513
10949
|
);
|
|
9514
10950
|
}
|
|
9515
10951
|
}
|
|
@@ -9527,7 +10963,7 @@ var MockEthereumAdapter = class extends BaseWalletAdapter {
|
|
|
9527
10963
|
if (this._shouldFailSign) {
|
|
9528
10964
|
throw new WalletError(
|
|
9529
10965
|
"Mock signing rejected",
|
|
9530
|
-
|
|
10966
|
+
import_types22.WalletErrorCode.SIGNING_REJECTED
|
|
9531
10967
|
);
|
|
9532
10968
|
}
|
|
9533
10969
|
const msgHex = Buffer.from(message).toString("hex");
|
|
@@ -9545,7 +10981,7 @@ var MockEthereumAdapter = class extends BaseWalletAdapter {
|
|
|
9545
10981
|
if (this._shouldFailSign) {
|
|
9546
10982
|
throw new WalletError(
|
|
9547
10983
|
"Mock signing rejected",
|
|
9548
|
-
|
|
10984
|
+
import_types22.WalletErrorCode.SIGNING_REJECTED
|
|
9549
10985
|
);
|
|
9550
10986
|
}
|
|
9551
10987
|
const mockSig = `0x${"1".repeat(130)}`;
|
|
@@ -9562,7 +10998,7 @@ var MockEthereumAdapter = class extends BaseWalletAdapter {
|
|
|
9562
10998
|
if (this._shouldFailSign) {
|
|
9563
10999
|
throw new WalletError(
|
|
9564
11000
|
"Mock signing rejected",
|
|
9565
|
-
|
|
11001
|
+
import_types22.WalletErrorCode.SIGNING_REJECTED
|
|
9566
11002
|
);
|
|
9567
11003
|
}
|
|
9568
11004
|
this._signedTransactions.push(tx);
|
|
@@ -9587,7 +11023,7 @@ var MockEthereumAdapter = class extends BaseWalletAdapter {
|
|
|
9587
11023
|
if (this._shouldFailTransaction) {
|
|
9588
11024
|
throw new WalletError(
|
|
9589
11025
|
"Mock transaction failed",
|
|
9590
|
-
|
|
11026
|
+
import_types22.WalletErrorCode.TRANSACTION_FAILED
|
|
9591
11027
|
);
|
|
9592
11028
|
}
|
|
9593
11029
|
this._signedTransactions.push(tx);
|
|
@@ -9617,7 +11053,7 @@ var MockEthereumAdapter = class extends BaseWalletAdapter {
|
|
|
9617
11053
|
if (asset.chain !== "ethereum") {
|
|
9618
11054
|
throw new WalletError(
|
|
9619
11055
|
`Asset chain ${asset.chain} not supported by Ethereum adapter`,
|
|
9620
|
-
|
|
11056
|
+
import_types22.WalletErrorCode.UNSUPPORTED_CHAIN
|
|
9621
11057
|
);
|
|
9622
11058
|
}
|
|
9623
11059
|
if (!asset.address) {
|
|
@@ -9896,7 +11332,7 @@ function getAvailableTransports() {
|
|
|
9896
11332
|
}
|
|
9897
11333
|
|
|
9898
11334
|
// src/wallet/hardware/ledger.ts
|
|
9899
|
-
var
|
|
11335
|
+
var import_types25 = require("@sip-protocol/types");
|
|
9900
11336
|
var LedgerWalletAdapter = class extends BaseWalletAdapter {
|
|
9901
11337
|
chain;
|
|
9902
11338
|
name = "ledger";
|
|
@@ -10049,7 +11485,7 @@ var LedgerWalletAdapter = class extends BaseWalletAdapter {
|
|
|
10049
11485
|
async getBalance() {
|
|
10050
11486
|
throw new WalletError(
|
|
10051
11487
|
"Hardware wallets do not track balances. Use an RPC provider.",
|
|
10052
|
-
|
|
11488
|
+
import_types25.WalletErrorCode.UNSUPPORTED_OPERATION
|
|
10053
11489
|
);
|
|
10054
11490
|
}
|
|
10055
11491
|
/**
|
|
@@ -10060,7 +11496,7 @@ var LedgerWalletAdapter = class extends BaseWalletAdapter {
|
|
|
10060
11496
|
async getTokenBalance(_asset) {
|
|
10061
11497
|
throw new WalletError(
|
|
10062
11498
|
"Hardware wallets do not track balances. Use an RPC provider.",
|
|
10063
|
-
|
|
11499
|
+
import_types25.WalletErrorCode.UNSUPPORTED_OPERATION
|
|
10064
11500
|
);
|
|
10065
11501
|
}
|
|
10066
11502
|
// ─── Account Management ─────────────────────────────────────────────────────
|
|
@@ -10348,7 +11784,7 @@ function createLedgerAdapter(config) {
|
|
|
10348
11784
|
}
|
|
10349
11785
|
|
|
10350
11786
|
// src/wallet/hardware/trezor.ts
|
|
10351
|
-
var
|
|
11787
|
+
var import_types27 = require("@sip-protocol/types");
|
|
10352
11788
|
var TrezorWalletAdapter = class extends BaseWalletAdapter {
|
|
10353
11789
|
chain;
|
|
10354
11790
|
name = "trezor";
|
|
@@ -10494,7 +11930,7 @@ var TrezorWalletAdapter = class extends BaseWalletAdapter {
|
|
|
10494
11930
|
async getBalance() {
|
|
10495
11931
|
throw new WalletError(
|
|
10496
11932
|
"Hardware wallets do not track balances. Use an RPC provider.",
|
|
10497
|
-
|
|
11933
|
+
import_types27.WalletErrorCode.UNSUPPORTED_OPERATION
|
|
10498
11934
|
);
|
|
10499
11935
|
}
|
|
10500
11936
|
/**
|
|
@@ -10505,7 +11941,7 @@ var TrezorWalletAdapter = class extends BaseWalletAdapter {
|
|
|
10505
11941
|
async getTokenBalance(_asset) {
|
|
10506
11942
|
throw new WalletError(
|
|
10507
11943
|
"Hardware wallets do not track balances. Use an RPC provider.",
|
|
10508
|
-
|
|
11944
|
+
import_types27.WalletErrorCode.UNSUPPORTED_OPERATION
|
|
10509
11945
|
);
|
|
10510
11946
|
}
|
|
10511
11947
|
// ─── Account Management ─────────────────────────────────────────────────────
|
|
@@ -10786,8 +12222,8 @@ function createTrezorAdapter(config) {
|
|
|
10786
12222
|
}
|
|
10787
12223
|
|
|
10788
12224
|
// src/wallet/hardware/mock.ts
|
|
10789
|
-
var
|
|
10790
|
-
var
|
|
12225
|
+
var import_types29 = require("@sip-protocol/types");
|
|
12226
|
+
var import_utils14 = require("@noble/hashes/utils");
|
|
10791
12227
|
var MockLedgerAdapter = class extends BaseWalletAdapter {
|
|
10792
12228
|
chain;
|
|
10793
12229
|
name = "mock-ledger";
|
|
@@ -10934,7 +12370,7 @@ var MockLedgerAdapter = class extends BaseWalletAdapter {
|
|
|
10934
12370
|
async getBalance() {
|
|
10935
12371
|
throw new WalletError(
|
|
10936
12372
|
"Hardware wallets do not track balances",
|
|
10937
|
-
|
|
12373
|
+
import_types29.WalletErrorCode.UNSUPPORTED_OPERATION
|
|
10938
12374
|
);
|
|
10939
12375
|
}
|
|
10940
12376
|
/**
|
|
@@ -10943,7 +12379,7 @@ var MockLedgerAdapter = class extends BaseWalletAdapter {
|
|
|
10943
12379
|
async getTokenBalance(_asset) {
|
|
10944
12380
|
throw new WalletError(
|
|
10945
12381
|
"Hardware wallets do not track balances",
|
|
10946
|
-
|
|
12382
|
+
import_types29.WalletErrorCode.UNSUPPORTED_OPERATION
|
|
10947
12383
|
);
|
|
10948
12384
|
}
|
|
10949
12385
|
/**
|
|
@@ -11032,15 +12468,15 @@ var MockLedgerAdapter = class extends BaseWalletAdapter {
|
|
|
11032
12468
|
}
|
|
11033
12469
|
}
|
|
11034
12470
|
generateMockAddress(index) {
|
|
11035
|
-
const bytes = (0,
|
|
12471
|
+
const bytes = (0, import_utils14.randomBytes)(20);
|
|
11036
12472
|
bytes[0] = index;
|
|
11037
|
-
return `0x${(0,
|
|
12473
|
+
return `0x${(0, import_utils14.bytesToHex)(bytes)}`;
|
|
11038
12474
|
}
|
|
11039
12475
|
generateMockPublicKey(index) {
|
|
11040
|
-
const bytes = (0,
|
|
12476
|
+
const bytes = (0, import_utils14.randomBytes)(33);
|
|
11041
12477
|
bytes[0] = 2;
|
|
11042
12478
|
bytes[1] = index;
|
|
11043
|
-
return `0x${(0,
|
|
12479
|
+
return `0x${(0, import_utils14.bytesToHex)(bytes)}`;
|
|
11044
12480
|
}
|
|
11045
12481
|
generateMockSignature(data) {
|
|
11046
12482
|
const sig = new Uint8Array(65);
|
|
@@ -11049,7 +12485,7 @@ var MockLedgerAdapter = class extends BaseWalletAdapter {
|
|
|
11049
12485
|
sig[32 + i] = (data[i % data.length] ?? 0) ^ i * 11;
|
|
11050
12486
|
}
|
|
11051
12487
|
sig[64] = 27;
|
|
11052
|
-
return `0x${(0,
|
|
12488
|
+
return `0x${(0, import_utils14.bytesToHex)(sig)}`;
|
|
11053
12489
|
}
|
|
11054
12490
|
delay(ms) {
|
|
11055
12491
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
@@ -11173,13 +12609,13 @@ var MockTrezorAdapter = class extends BaseWalletAdapter {
|
|
|
11173
12609
|
async getBalance() {
|
|
11174
12610
|
throw new WalletError(
|
|
11175
12611
|
"Hardware wallets do not track balances",
|
|
11176
|
-
|
|
12612
|
+
import_types29.WalletErrorCode.UNSUPPORTED_OPERATION
|
|
11177
12613
|
);
|
|
11178
12614
|
}
|
|
11179
12615
|
async getTokenBalance(_asset) {
|
|
11180
12616
|
throw new WalletError(
|
|
11181
12617
|
"Hardware wallets do not track balances",
|
|
11182
|
-
|
|
12618
|
+
import_types29.WalletErrorCode.UNSUPPORTED_OPERATION
|
|
11183
12619
|
);
|
|
11184
12620
|
}
|
|
11185
12621
|
async getAccounts(startIndex = 0, count = 5) {
|
|
@@ -11238,15 +12674,15 @@ var MockTrezorAdapter = class extends BaseWalletAdapter {
|
|
|
11238
12674
|
}
|
|
11239
12675
|
}
|
|
11240
12676
|
generateMockAddress(index) {
|
|
11241
|
-
const bytes = (0,
|
|
12677
|
+
const bytes = (0, import_utils14.randomBytes)(20);
|
|
11242
12678
|
bytes[0] = index + 100;
|
|
11243
|
-
return `0x${(0,
|
|
12679
|
+
return `0x${(0, import_utils14.bytesToHex)(bytes)}`;
|
|
11244
12680
|
}
|
|
11245
12681
|
generateMockPublicKey(index) {
|
|
11246
|
-
const bytes = (0,
|
|
12682
|
+
const bytes = (0, import_utils14.randomBytes)(33);
|
|
11247
12683
|
bytes[0] = 3;
|
|
11248
12684
|
bytes[1] = index + 100;
|
|
11249
|
-
return `0x${(0,
|
|
12685
|
+
return `0x${(0, import_utils14.bytesToHex)(bytes)}`;
|
|
11250
12686
|
}
|
|
11251
12687
|
generateMockSignature(data) {
|
|
11252
12688
|
const sig = new Uint8Array(65);
|
|
@@ -11255,7 +12691,7 @@ var MockTrezorAdapter = class extends BaseWalletAdapter {
|
|
|
11255
12691
|
sig[32 + i] = (data[i % data.length] ?? 0) ^ i * 17;
|
|
11256
12692
|
}
|
|
11257
12693
|
sig[64] = 28;
|
|
11258
|
-
return `0x${(0,
|
|
12694
|
+
return `0x${(0, import_utils14.bytesToHex)(sig)}`;
|
|
11259
12695
|
}
|
|
11260
12696
|
delay(ms) {
|
|
11261
12697
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
@@ -11269,12 +12705,17 @@ function createMockTrezorAdapter(config) {
|
|
|
11269
12705
|
}
|
|
11270
12706
|
|
|
11271
12707
|
// src/wallet/index.ts
|
|
11272
|
-
var
|
|
12708
|
+
var import_types32 = require("@sip-protocol/types");
|
|
11273
12709
|
// Annotate the CommonJS export names for ESM import in node:
|
|
11274
12710
|
0 && (module.exports = {
|
|
12711
|
+
ATTESTATION_VERSION,
|
|
11275
12712
|
BaseWalletAdapter,
|
|
12713
|
+
BrowserNoirProvider,
|
|
12714
|
+
CHAIN_NUMERIC_IDS,
|
|
11276
12715
|
ComplianceManager,
|
|
11277
12716
|
CryptoError,
|
|
12717
|
+
DEFAULT_THRESHOLD,
|
|
12718
|
+
DEFAULT_TOTAL_ORACLES,
|
|
11278
12719
|
DerivationPath,
|
|
11279
12720
|
EncryptionNotImplementedError,
|
|
11280
12721
|
ErrorCode,
|
|
@@ -11297,6 +12738,7 @@ var import_types30 = require("@sip-protocol/types");
|
|
|
11297
12738
|
NEARIntentsAdapter,
|
|
11298
12739
|
NetworkError,
|
|
11299
12740
|
NoirProofProvider,
|
|
12741
|
+
ORACLE_DOMAIN,
|
|
11300
12742
|
OneClickClient,
|
|
11301
12743
|
OneClickDepositMode,
|
|
11302
12744
|
OneClickErrorCode,
|
|
@@ -11328,11 +12770,16 @@ var import_types30 = require("@sip-protocol/types");
|
|
|
11328
12770
|
ZcashShieldedService,
|
|
11329
12771
|
addBlindings,
|
|
11330
12772
|
addCommitments,
|
|
12773
|
+
addOracle,
|
|
11331
12774
|
attachProofs,
|
|
11332
12775
|
base58ToHex,
|
|
12776
|
+
browserBytesToHex,
|
|
12777
|
+
browserHexToBytes,
|
|
12778
|
+
checkEd25519StealthAddress,
|
|
11333
12779
|
checkStealthAddress,
|
|
11334
12780
|
commit,
|
|
11335
12781
|
commitZero,
|
|
12782
|
+
computeAttestationHash,
|
|
11336
12783
|
createCommitment,
|
|
11337
12784
|
createEthereumAdapter,
|
|
11338
12785
|
createLedgerAdapter,
|
|
@@ -11345,6 +12792,7 @@ var import_types30 = require("@sip-protocol/types");
|
|
|
11345
12792
|
createMockSolver,
|
|
11346
12793
|
createMockTrezorAdapter,
|
|
11347
12794
|
createNEARIntentsAdapter,
|
|
12795
|
+
createOracleRegistry,
|
|
11348
12796
|
createProductionSIP,
|
|
11349
12797
|
createSIP,
|
|
11350
12798
|
createShieldedIntent,
|
|
@@ -11357,12 +12805,17 @@ var import_types30 = require("@sip-protocol/types");
|
|
|
11357
12805
|
decodeStealthMetaAddress,
|
|
11358
12806
|
decryptMemo,
|
|
11359
12807
|
decryptWithViewing,
|
|
12808
|
+
deriveEd25519StealthPrivateKey,
|
|
12809
|
+
deriveOracleId,
|
|
11360
12810
|
deriveStealthPrivateKey,
|
|
11361
12811
|
deriveViewingKey,
|
|
12812
|
+
deserializeAttestationMessage,
|
|
11362
12813
|
deserializeIntent,
|
|
11363
12814
|
deserializePayment,
|
|
11364
12815
|
detectEthereumWallets,
|
|
11365
12816
|
detectSolanaWallets,
|
|
12817
|
+
ed25519PublicKeyToNearAddress,
|
|
12818
|
+
ed25519PublicKeyToSolanaAddress,
|
|
11366
12819
|
encodeStealthMetaAddress,
|
|
11367
12820
|
encryptForViewing,
|
|
11368
12821
|
featureNotSupportedError,
|
|
@@ -11370,13 +12823,19 @@ var import_types30 = require("@sip-protocol/types");
|
|
|
11370
12823
|
fromHex,
|
|
11371
12824
|
fromStablecoinUnits,
|
|
11372
12825
|
generateBlinding,
|
|
12826
|
+
generateEd25519StealthAddress,
|
|
12827
|
+
generateEd25519StealthMetaAddress,
|
|
11373
12828
|
generateIntentId,
|
|
11374
12829
|
generateRandomBytes,
|
|
11375
12830
|
generateStealthAddress,
|
|
11376
12831
|
generateStealthMetaAddress,
|
|
11377
12832
|
generateViewingKey,
|
|
12833
|
+
getActiveOracles,
|
|
11378
12834
|
getAvailableTransports,
|
|
12835
|
+
getBrowserInfo,
|
|
12836
|
+
getChainNumericId,
|
|
11379
12837
|
getChainsForStablecoin,
|
|
12838
|
+
getCurveForChain,
|
|
11380
12839
|
getDefaultRpcEndpoint,
|
|
11381
12840
|
getDerivationPath,
|
|
11382
12841
|
getErrorMessage,
|
|
@@ -11393,10 +12852,13 @@ var import_types30 = require("@sip-protocol/types");
|
|
|
11393
12852
|
getStablecoinsForChain,
|
|
11394
12853
|
getSupportedStablecoins,
|
|
11395
12854
|
getTimeRemaining,
|
|
12855
|
+
hasEnoughOracles,
|
|
11396
12856
|
hasErrorCode,
|
|
11397
12857
|
hasRequiredProofs,
|
|
11398
12858
|
hash,
|
|
11399
12859
|
hexToNumber,
|
|
12860
|
+
isBrowser,
|
|
12861
|
+
isEd25519Chain,
|
|
11400
12862
|
isExpired,
|
|
11401
12863
|
isNonNegativeAmount,
|
|
11402
12864
|
isPaymentExpired,
|
|
@@ -11408,40 +12870,54 @@ var import_types30 = require("@sip-protocol/types");
|
|
|
11408
12870
|
isValidAmount,
|
|
11409
12871
|
isValidChainId,
|
|
11410
12872
|
isValidCompressedPublicKey,
|
|
12873
|
+
isValidEd25519PublicKey,
|
|
11411
12874
|
isValidHex,
|
|
11412
12875
|
isValidHexLength,
|
|
12876
|
+
isValidNearAccountId,
|
|
12877
|
+
isValidNearImplicitAddress,
|
|
11413
12878
|
isValidPrivacyLevel,
|
|
11414
12879
|
isValidPrivateKey,
|
|
11415
12880
|
isValidScalar,
|
|
11416
12881
|
isValidSlippage,
|
|
12882
|
+
isValidSolanaAddress,
|
|
11417
12883
|
isValidStealthMetaAddress,
|
|
12884
|
+
nearAddressToEd25519PublicKey,
|
|
11418
12885
|
normalizeAddress,
|
|
11419
12886
|
notConnectedError,
|
|
11420
12887
|
publicKeyToEthAddress,
|
|
11421
12888
|
registerWallet,
|
|
12889
|
+
removeOracle,
|
|
11422
12890
|
secureWipe,
|
|
11423
12891
|
secureWipeAll,
|
|
12892
|
+
serializeAttestationMessage,
|
|
11424
12893
|
serializeIntent,
|
|
11425
12894
|
serializePayment,
|
|
12895
|
+
signAttestationMessage,
|
|
12896
|
+
solanaAddressToEd25519PublicKey,
|
|
11426
12897
|
solanaPublicKeyToHex,
|
|
11427
12898
|
subtractBlindings,
|
|
11428
12899
|
subtractCommitments,
|
|
12900
|
+
supportsSharedArrayBuffer,
|
|
11429
12901
|
supportsViewingKey,
|
|
11430
12902
|
supportsWebBluetooth,
|
|
11431
12903
|
supportsWebHID,
|
|
11432
12904
|
supportsWebUSB,
|
|
12905
|
+
supportsWebWorkers,
|
|
11433
12906
|
toHex,
|
|
11434
12907
|
toStablecoinUnits,
|
|
11435
12908
|
trackIntent,
|
|
11436
12909
|
trackPayment,
|
|
12910
|
+
updateOracleStatus,
|
|
11437
12911
|
validateAsset,
|
|
11438
12912
|
validateCreateIntentParams,
|
|
11439
12913
|
validateIntentInput,
|
|
11440
12914
|
validateIntentOutput,
|
|
11441
12915
|
validateScalar,
|
|
11442
12916
|
validateViewingKey,
|
|
12917
|
+
verifyAttestation,
|
|
11443
12918
|
verifyCommitment,
|
|
11444
12919
|
verifyOpening,
|
|
12920
|
+
verifyOracleSignature,
|
|
11445
12921
|
walletRegistry,
|
|
11446
12922
|
withSecureBuffer,
|
|
11447
12923
|
withSecureBufferSync,
|