@sip-protocol/sdk 0.2.10 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.d.mts +1 -1
- package/dist/browser.d.ts +1 -1
- package/dist/browser.js +1643 -266
- package/dist/browser.mjs +259 -5
- package/dist/chunk-4IFOPYJF.mjs +11950 -0
- package/dist/chunk-4VJHI66K.mjs +12120 -0
- package/dist/chunk-5BAS4D44.mjs +10283 -0
- package/dist/chunk-6WOV2YNG.mjs +10179 -0
- package/dist/chunk-7IMRM7LN.mjs +12149 -0
- package/dist/chunk-DU7LQDD2.mjs +10148 -0
- package/dist/{chunk-AV37IZST.mjs → chunk-JNNXNTSS.mjs} +14 -0
- package/dist/chunk-KXN6IWL5.mjs +10736 -0
- package/dist/chunk-MR7HRCRS.mjs +10165 -0
- package/dist/chunk-NDGUWOOZ.mjs +10157 -0
- package/dist/chunk-O4Y2ZUDL.mjs +12721 -0
- package/dist/chunk-UPTISVCY.mjs +10304 -0
- package/dist/chunk-VITVG25F.mjs +982 -0
- package/dist/chunk-VXSHK7US.mjs +10158 -0
- package/dist/chunk-W3YXIQ7L.mjs +11950 -0
- package/dist/chunk-YZCK337Y.mjs +12155 -0
- package/dist/index-Ba7njCU3.d.ts +6925 -0
- package/dist/index-Co26-vbG.d.mts +6925 -0
- package/dist/index-DAgedMrt.d.ts +6927 -0
- package/dist/index-DW7AQwcU.d.mts +6927 -0
- package/dist/{index-CAhjA4kh.d.mts → index-DqZoHYKI.d.mts} +362 -6
- package/dist/index-dTtK_DTl.d.ts +6762 -0
- package/dist/index-jnkYu-Z4.d.mts +6762 -0
- package/dist/{index-BFOKTz2z.d.ts → index-vB1N1mHd.d.ts} +362 -6
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1340 -199
- package/dist/index.mjs +19 -1
- package/dist/noir-BHQtFvRk.d.mts +467 -0
- package/dist/noir-BHQtFvRk.d.ts +467 -0
- package/package.json +14 -14
- package/src/index.ts +32 -0
- package/src/proofs/worker.ts +240 -4
- package/src/settlement/README.md +439 -0
- package/src/settlement/backends/direct-chain.ts +569 -0
- package/src/settlement/backends/index.ts +22 -0
- package/src/settlement/backends/near-intents.ts +480 -0
- package/src/settlement/backends/zcash-native.ts +516 -0
- package/src/settlement/index.ts +47 -0
- package/src/settlement/interface.ts +397 -0
- package/src/settlement/registry.ts +269 -0
- package/src/settlement/router.ts +383 -0
- package/src/zcash/bridge.ts +20 -2
- package/src/zcash/swap-service.ts +20 -2
- package/LICENSE +0 -21
package/dist/browser.js
CHANGED
|
@@ -47,7 +47,7 @@ __export(browser_exports, {
|
|
|
47
47
|
HardwareWalletError: () => HardwareWalletError,
|
|
48
48
|
IntentBuilder: () => IntentBuilder,
|
|
49
49
|
IntentError: () => IntentError,
|
|
50
|
-
IntentStatus: () =>
|
|
50
|
+
IntentStatus: () => import_types37.IntentStatus,
|
|
51
51
|
LedgerWalletAdapter: () => LedgerWalletAdapter,
|
|
52
52
|
MockEthereumAdapter: () => MockEthereumAdapter,
|
|
53
53
|
MockLedgerAdapter: () => MockLedgerAdapter,
|
|
@@ -56,37 +56,43 @@ __export(browser_exports, {
|
|
|
56
56
|
MockSolver: () => MockSolver,
|
|
57
57
|
MockTrezorAdapter: () => MockTrezorAdapter,
|
|
58
58
|
MockWalletAdapter: () => MockWalletAdapter,
|
|
59
|
-
NATIVE_TOKENS: () =>
|
|
59
|
+
NATIVE_TOKENS: () => import_types37.NATIVE_TOKENS,
|
|
60
60
|
NEARIntentsAdapter: () => NEARIntentsAdapter,
|
|
61
|
+
NEARIntentsBackend: () => NEARIntentsBackend,
|
|
61
62
|
NetworkError: () => NetworkError,
|
|
62
63
|
ORACLE_DOMAIN: () => ORACLE_DOMAIN,
|
|
63
64
|
OneClickClient: () => OneClickClient,
|
|
64
|
-
OneClickDepositMode: () =>
|
|
65
|
-
OneClickErrorCode: () =>
|
|
66
|
-
OneClickSwapStatus: () =>
|
|
67
|
-
OneClickSwapType: () =>
|
|
65
|
+
OneClickDepositMode: () => import_types41.OneClickDepositMode,
|
|
66
|
+
OneClickErrorCode: () => import_types41.OneClickErrorCode,
|
|
67
|
+
OneClickSwapStatus: () => import_types41.OneClickSwapStatus,
|
|
68
|
+
OneClickSwapType: () => import_types41.OneClickSwapType,
|
|
68
69
|
PaymentBuilder: () => PaymentBuilder,
|
|
69
|
-
PaymentStatus: () =>
|
|
70
|
-
PrivacyLevel: () =>
|
|
70
|
+
PaymentStatus: () => import_types38.PaymentStatus,
|
|
71
|
+
PrivacyLevel: () => import_types37.PrivacyLevel,
|
|
71
72
|
ProofError: () => ProofError,
|
|
72
73
|
ProofGenerationError: () => ProofGenerationError,
|
|
73
74
|
ProofNotImplementedError: () => ProofNotImplementedError,
|
|
74
75
|
ProofWorker: () => ProofWorker,
|
|
75
|
-
ProposalStatus: () =>
|
|
76
|
-
ReportStatus: () =>
|
|
76
|
+
ProposalStatus: () => import_types39.ProposalStatus,
|
|
77
|
+
ReportStatus: () => import_types40.ReportStatus,
|
|
77
78
|
SIP: () => SIP,
|
|
78
79
|
SIPError: () => SIPError,
|
|
79
|
-
SIP_VERSION: () =>
|
|
80
|
+
SIP_VERSION: () => import_types37.SIP_VERSION,
|
|
80
81
|
STABLECOIN_ADDRESSES: () => STABLECOIN_ADDRESSES,
|
|
81
82
|
STABLECOIN_DECIMALS: () => STABLECOIN_DECIMALS,
|
|
82
83
|
STABLECOIN_INFO: () => STABLECOIN_INFO,
|
|
84
|
+
SettlementRegistry: () => SettlementRegistry,
|
|
85
|
+
SettlementRegistryError: () => SettlementRegistryError,
|
|
86
|
+
SmartRouter: () => SmartRouter,
|
|
83
87
|
SolanaWalletAdapter: () => SolanaWalletAdapter,
|
|
88
|
+
SwapStatus: () => SwapStatus,
|
|
84
89
|
Treasury: () => Treasury,
|
|
85
90
|
TrezorWalletAdapter: () => TrezorWalletAdapter,
|
|
86
91
|
ValidationError: () => ValidationError,
|
|
87
92
|
WalletError: () => WalletError,
|
|
88
|
-
WalletErrorCode: () =>
|
|
89
|
-
ZcashErrorCode: () =>
|
|
93
|
+
WalletErrorCode: () => import_types36.WalletErrorCode,
|
|
94
|
+
ZcashErrorCode: () => import_types42.ZcashErrorCode,
|
|
95
|
+
ZcashNativeBackend: () => ZcashNativeBackend,
|
|
90
96
|
ZcashRPCClient: () => ZcashRPCClient,
|
|
91
97
|
ZcashRPCError: () => ZcashRPCError,
|
|
92
98
|
ZcashShieldedService: () => ZcashShieldedService,
|
|
@@ -116,16 +122,19 @@ __export(browser_exports, {
|
|
|
116
122
|
createMockSolver: () => createMockSolver,
|
|
117
123
|
createMockTrezorAdapter: () => createMockTrezorAdapter,
|
|
118
124
|
createNEARIntentsAdapter: () => createNEARIntentsAdapter,
|
|
125
|
+
createNEARIntentsBackend: () => createNEARIntentsBackend,
|
|
119
126
|
createOracleRegistry: () => createOracleRegistry,
|
|
120
127
|
createProductionSIP: () => createProductionSIP,
|
|
121
128
|
createSIP: () => createSIP,
|
|
122
129
|
createShieldedIntent: () => createShieldedIntent,
|
|
123
130
|
createShieldedPayment: () => createShieldedPayment,
|
|
131
|
+
createSmartRouter: () => createSmartRouter,
|
|
124
132
|
createSolanaAdapter: () => createSolanaAdapter,
|
|
125
133
|
createTrezorAdapter: () => createTrezorAdapter,
|
|
126
134
|
createWalletFactory: () => createWalletFactory,
|
|
127
135
|
createWorkerBlobURL: () => createWorkerBlobURL,
|
|
128
136
|
createZcashClient: () => createZcashClient,
|
|
137
|
+
createZcashNativeBackend: () => createZcashNativeBackend,
|
|
129
138
|
createZcashShieldedService: () => createZcashShieldedService,
|
|
130
139
|
createZcashSwapService: () => createZcashSwapService,
|
|
131
140
|
decodeStealthMetaAddress: () => decodeStealthMetaAddress,
|
|
@@ -193,7 +202,7 @@ __export(browser_exports, {
|
|
|
193
202
|
isExpired: () => isExpired,
|
|
194
203
|
isNonNegativeAmount: () => isNonNegativeAmount,
|
|
195
204
|
isPaymentExpired: () => isPaymentExpired,
|
|
196
|
-
isPrivate: () =>
|
|
205
|
+
isPrivate: () => import_types37.isPrivate,
|
|
197
206
|
isPrivateWalletAdapter: () => isPrivateWalletAdapter,
|
|
198
207
|
isSIPError: () => isSIPError,
|
|
199
208
|
isStablecoin: () => isStablecoin,
|
|
@@ -231,7 +240,7 @@ __export(browser_exports, {
|
|
|
231
240
|
subtractCommitments: () => subtractCommitments,
|
|
232
241
|
supportsSharedArrayBuffer: () => supportsSharedArrayBuffer,
|
|
233
242
|
supportsTouch: () => supportsTouch,
|
|
234
|
-
supportsViewingKey: () =>
|
|
243
|
+
supportsViewingKey: () => import_types37.supportsViewingKey,
|
|
235
244
|
supportsWASMBulkMemory: () => supportsWASMBulkMemory,
|
|
236
245
|
supportsWASMSimd: () => supportsWASMSimd,
|
|
237
246
|
supportsWebBluetooth: () => supportsWebBluetooth,
|
|
@@ -4061,10 +4070,10 @@ function hasEnoughOracles(registry) {
|
|
|
4061
4070
|
}
|
|
4062
4071
|
|
|
4063
4072
|
// src/index.ts
|
|
4064
|
-
var import_types34 = require("@sip-protocol/types");
|
|
4065
|
-
var import_types35 = require("@sip-protocol/types");
|
|
4066
|
-
var import_types36 = require("@sip-protocol/types");
|
|
4067
4073
|
var import_types37 = require("@sip-protocol/types");
|
|
4074
|
+
var import_types38 = require("@sip-protocol/types");
|
|
4075
|
+
var import_types39 = require("@sip-protocol/types");
|
|
4076
|
+
var import_types40 = require("@sip-protocol/types");
|
|
4068
4077
|
|
|
4069
4078
|
// src/solver/mock-solver.ts
|
|
4070
4079
|
var import_types7 = require("@sip-protocol/types");
|
|
@@ -4166,93 +4175,1210 @@ var MockSolver = class {
|
|
|
4166
4175
|
validUntil: now + 60,
|
|
4167
4176
|
estimatedGas: 200000n
|
|
4168
4177
|
};
|
|
4169
|
-
return quote;
|
|
4178
|
+
return quote;
|
|
4179
|
+
}
|
|
4180
|
+
/**
|
|
4181
|
+
* Fulfill an intent with the given quote
|
|
4182
|
+
*
|
|
4183
|
+
* In production, this would:
|
|
4184
|
+
* 1. Lock collateral
|
|
4185
|
+
* 2. Execute the swap on destination chain
|
|
4186
|
+
* 3. Generate fulfillment proof
|
|
4187
|
+
* 4. Release collateral after verification
|
|
4188
|
+
*
|
|
4189
|
+
* Privacy preserved:
|
|
4190
|
+
* - Funds go to stealth address (unlinkable)
|
|
4191
|
+
* - Solver never learns recipient's real identity
|
|
4192
|
+
*/
|
|
4193
|
+
async fulfill(intent, quote) {
|
|
4194
|
+
const status = {
|
|
4195
|
+
intentId: intent.intentId,
|
|
4196
|
+
status: "executing"
|
|
4197
|
+
};
|
|
4198
|
+
this.pendingFulfillments.set(intent.intentId, status);
|
|
4199
|
+
await this.delay(this.executionDelay);
|
|
4200
|
+
if (Math.random() < this.failureRate) {
|
|
4201
|
+
status.status = "failed";
|
|
4202
|
+
status.error = "Simulated failure for testing";
|
|
4203
|
+
return {
|
|
4204
|
+
intentId: intent.intentId,
|
|
4205
|
+
status: import_types7.IntentStatus.FAILED,
|
|
4206
|
+
fulfilledAt: Math.floor(Date.now() / 1e3),
|
|
4207
|
+
error: status.error
|
|
4208
|
+
};
|
|
4209
|
+
}
|
|
4210
|
+
const txHash = `0x${(0, import_utils10.bytesToHex)((0, import_utils10.randomBytes)(32))}`;
|
|
4211
|
+
status.status = "completed";
|
|
4212
|
+
status.txHash = txHash;
|
|
4213
|
+
return {
|
|
4214
|
+
intentId: intent.intentId,
|
|
4215
|
+
status: import_types7.IntentStatus.FULFILLED,
|
|
4216
|
+
outputAmount: quote.outputAmount,
|
|
4217
|
+
txHash: intent.privacyLevel === "transparent" ? txHash : void 0,
|
|
4218
|
+
fulfillmentProof: {
|
|
4219
|
+
type: "fulfillment",
|
|
4220
|
+
proof: `0x${(0, import_utils10.bytesToHex)((0, import_utils10.randomBytes)(128))}`,
|
|
4221
|
+
publicInputs: [
|
|
4222
|
+
`0x${(0, import_utils10.bytesToHex)(new TextEncoder().encode(intent.intentId))}`,
|
|
4223
|
+
`0x${(0, import_utils10.bytesToHex)(new TextEncoder().encode(quote.quoteId))}`
|
|
4224
|
+
]
|
|
4225
|
+
},
|
|
4226
|
+
fulfilledAt: Math.floor(Date.now() / 1e3)
|
|
4227
|
+
};
|
|
4228
|
+
}
|
|
4229
|
+
/**
|
|
4230
|
+
* Cancel a pending fulfillment
|
|
4231
|
+
*/
|
|
4232
|
+
async cancel(intentId) {
|
|
4233
|
+
const status = this.pendingFulfillments.get(intentId);
|
|
4234
|
+
if (!status || status.status !== "pending") {
|
|
4235
|
+
return false;
|
|
4236
|
+
}
|
|
4237
|
+
status.status = "cancelled";
|
|
4238
|
+
return true;
|
|
4239
|
+
}
|
|
4240
|
+
/**
|
|
4241
|
+
* Get fulfillment status
|
|
4242
|
+
*/
|
|
4243
|
+
async getStatus(intentId) {
|
|
4244
|
+
return this.pendingFulfillments.get(intentId) ?? null;
|
|
4245
|
+
}
|
|
4246
|
+
/**
|
|
4247
|
+
* Reset solver state (for testing)
|
|
4248
|
+
*/
|
|
4249
|
+
reset() {
|
|
4250
|
+
this.pendingFulfillments.clear();
|
|
4251
|
+
}
|
|
4252
|
+
delay(ms) {
|
|
4253
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
4254
|
+
}
|
|
4255
|
+
};
|
|
4256
|
+
function createMockSolver(config) {
|
|
4257
|
+
return new MockSolver(config);
|
|
4258
|
+
}
|
|
4259
|
+
|
|
4260
|
+
// src/index.ts
|
|
4261
|
+
var import_types41 = require("@sip-protocol/types");
|
|
4262
|
+
|
|
4263
|
+
// src/settlement/interface.ts
|
|
4264
|
+
var SwapStatus = /* @__PURE__ */ ((SwapStatus2) => {
|
|
4265
|
+
SwapStatus2["PENDING_DEPOSIT"] = "pending_deposit";
|
|
4266
|
+
SwapStatus2["DEPOSIT_CONFIRMED"] = "deposit_confirmed";
|
|
4267
|
+
SwapStatus2["IN_PROGRESS"] = "in_progress";
|
|
4268
|
+
SwapStatus2["SUCCESS"] = "success";
|
|
4269
|
+
SwapStatus2["FAILED"] = "failed";
|
|
4270
|
+
SwapStatus2["CANCELLED"] = "cancelled";
|
|
4271
|
+
SwapStatus2["REFUNDING"] = "refunding";
|
|
4272
|
+
SwapStatus2["REFUNDED"] = "refunded";
|
|
4273
|
+
return SwapStatus2;
|
|
4274
|
+
})(SwapStatus || {});
|
|
4275
|
+
|
|
4276
|
+
// src/settlement/registry.ts
|
|
4277
|
+
var SettlementRegistryError = class extends Error {
|
|
4278
|
+
constructor(message) {
|
|
4279
|
+
super(message);
|
|
4280
|
+
this.name = "SettlementRegistryError";
|
|
4281
|
+
}
|
|
4282
|
+
};
|
|
4283
|
+
var SettlementRegistry = class {
|
|
4284
|
+
backends = /* @__PURE__ */ new Map();
|
|
4285
|
+
/**
|
|
4286
|
+
* Register a settlement backend
|
|
4287
|
+
*
|
|
4288
|
+
* @param backend - Settlement backend to register
|
|
4289
|
+
* @throws {SettlementRegistryError} If backend with same name already exists
|
|
4290
|
+
*
|
|
4291
|
+
* @example
|
|
4292
|
+
* ```typescript
|
|
4293
|
+
* registry.register(nearIntentsBackend)
|
|
4294
|
+
* ```
|
|
4295
|
+
*/
|
|
4296
|
+
register(backend) {
|
|
4297
|
+
if (this.backends.has(backend.name)) {
|
|
4298
|
+
throw new SettlementRegistryError(
|
|
4299
|
+
`Backend '${backend.name}' is already registered`
|
|
4300
|
+
);
|
|
4301
|
+
}
|
|
4302
|
+
this.backends.set(backend.name, backend);
|
|
4303
|
+
}
|
|
4304
|
+
/**
|
|
4305
|
+
* Get a settlement backend by name
|
|
4306
|
+
*
|
|
4307
|
+
* @param name - Backend name
|
|
4308
|
+
* @returns Settlement backend
|
|
4309
|
+
* @throws {SettlementRegistryError} If backend is not found
|
|
4310
|
+
*
|
|
4311
|
+
* @example
|
|
4312
|
+
* ```typescript
|
|
4313
|
+
* const backend = registry.get('near-intents')
|
|
4314
|
+
* ```
|
|
4315
|
+
*/
|
|
4316
|
+
get(name) {
|
|
4317
|
+
const backend = this.backends.get(name);
|
|
4318
|
+
if (!backend) {
|
|
4319
|
+
throw new SettlementRegistryError(`Backend '${name}' not found`);
|
|
4320
|
+
}
|
|
4321
|
+
return backend;
|
|
4322
|
+
}
|
|
4323
|
+
/**
|
|
4324
|
+
* List all registered backend names
|
|
4325
|
+
*
|
|
4326
|
+
* @returns Array of backend names
|
|
4327
|
+
*
|
|
4328
|
+
* @example
|
|
4329
|
+
* ```typescript
|
|
4330
|
+
* const names = registry.list()
|
|
4331
|
+
* // ['near-intents', 'zcash', 'thorchain']
|
|
4332
|
+
* ```
|
|
4333
|
+
*/
|
|
4334
|
+
list() {
|
|
4335
|
+
return Array.from(this.backends.keys());
|
|
4336
|
+
}
|
|
4337
|
+
/**
|
|
4338
|
+
* Get the best backend for a specific route
|
|
4339
|
+
*
|
|
4340
|
+
* Selection criteria (in order of priority):
|
|
4341
|
+
* 1. Backends that support both source and destination chains
|
|
4342
|
+
* 2. Backends with faster average execution time
|
|
4343
|
+
* 3. First registered backend (if no execution time info)
|
|
4344
|
+
*
|
|
4345
|
+
* @param fromChain - Source chain
|
|
4346
|
+
* @param toChain - Destination chain
|
|
4347
|
+
* @returns Best settlement backend for the route
|
|
4348
|
+
* @throws {SettlementRegistryError} If no backend supports the route
|
|
4349
|
+
*
|
|
4350
|
+
* @example
|
|
4351
|
+
* ```typescript
|
|
4352
|
+
* const backend = registry.getBestForRoute('ethereum', 'solana')
|
|
4353
|
+
* const quote = await backend.getQuote({ ... })
|
|
4354
|
+
* ```
|
|
4355
|
+
*/
|
|
4356
|
+
getBestForRoute(fromChain, toChain) {
|
|
4357
|
+
const supportedBackends = [];
|
|
4358
|
+
for (const backend of Array.from(this.backends.values())) {
|
|
4359
|
+
const { supportedSourceChains, supportedDestinationChains } = backend.capabilities;
|
|
4360
|
+
const supportsSource = supportedSourceChains.includes(fromChain);
|
|
4361
|
+
const supportsDestination = supportedDestinationChains.includes(toChain);
|
|
4362
|
+
if (supportsSource && supportsDestination) {
|
|
4363
|
+
supportedBackends.push(backend);
|
|
4364
|
+
}
|
|
4365
|
+
}
|
|
4366
|
+
if (supportedBackends.length === 0) {
|
|
4367
|
+
throw new SettlementRegistryError(
|
|
4368
|
+
`No backend supports route from '${fromChain}' to '${toChain}'`
|
|
4369
|
+
);
|
|
4370
|
+
}
|
|
4371
|
+
if (supportedBackends.length === 1) {
|
|
4372
|
+
return supportedBackends[0];
|
|
4373
|
+
}
|
|
4374
|
+
supportedBackends.sort((a, b) => {
|
|
4375
|
+
const timeA = a.capabilities.averageExecutionTime ?? Infinity;
|
|
4376
|
+
const timeB = b.capabilities.averageExecutionTime ?? Infinity;
|
|
4377
|
+
return timeA - timeB;
|
|
4378
|
+
});
|
|
4379
|
+
return supportedBackends[0];
|
|
4380
|
+
}
|
|
4381
|
+
/**
|
|
4382
|
+
* Get all supported routes across all registered backends
|
|
4383
|
+
*
|
|
4384
|
+
* @returns Array of supported routes
|
|
4385
|
+
*
|
|
4386
|
+
* @example
|
|
4387
|
+
* ```typescript
|
|
4388
|
+
* const routes = registry.getSupportedRoutes()
|
|
4389
|
+
* // [
|
|
4390
|
+
* // { fromChain: 'ethereum', toChain: 'solana', backend: 'near-intents' },
|
|
4391
|
+
* // { fromChain: 'solana', toChain: 'ethereum', backend: 'near-intents' },
|
|
4392
|
+
* // { fromChain: 'ethereum', toChain: 'zcash', backend: 'zcash' },
|
|
4393
|
+
* // ...
|
|
4394
|
+
* // ]
|
|
4395
|
+
* ```
|
|
4396
|
+
*/
|
|
4397
|
+
getSupportedRoutes() {
|
|
4398
|
+
const routes = [];
|
|
4399
|
+
for (const backend of Array.from(this.backends.values())) {
|
|
4400
|
+
const { supportedSourceChains, supportedDestinationChains } = backend.capabilities;
|
|
4401
|
+
for (const fromChain of supportedSourceChains) {
|
|
4402
|
+
for (const toChain of supportedDestinationChains) {
|
|
4403
|
+
routes.push({
|
|
4404
|
+
fromChain,
|
|
4405
|
+
toChain,
|
|
4406
|
+
backend: backend.name
|
|
4407
|
+
});
|
|
4408
|
+
}
|
|
4409
|
+
}
|
|
4410
|
+
}
|
|
4411
|
+
return routes;
|
|
4412
|
+
}
|
|
4413
|
+
/**
|
|
4414
|
+
* Check if a backend is registered
|
|
4415
|
+
*
|
|
4416
|
+
* @param name - Backend name
|
|
4417
|
+
* @returns True if backend is registered
|
|
4418
|
+
*
|
|
4419
|
+
* @example
|
|
4420
|
+
* ```typescript
|
|
4421
|
+
* if (registry.has('near-intents')) {
|
|
4422
|
+
* const backend = registry.get('near-intents')
|
|
4423
|
+
* }
|
|
4424
|
+
* ```
|
|
4425
|
+
*/
|
|
4426
|
+
has(name) {
|
|
4427
|
+
return this.backends.has(name);
|
|
4428
|
+
}
|
|
4429
|
+
/**
|
|
4430
|
+
* Unregister a settlement backend
|
|
4431
|
+
*
|
|
4432
|
+
* @param name - Backend name to unregister
|
|
4433
|
+
* @returns True if backend was unregistered, false if not found
|
|
4434
|
+
*
|
|
4435
|
+
* @example
|
|
4436
|
+
* ```typescript
|
|
4437
|
+
* registry.unregister('near-intents')
|
|
4438
|
+
* ```
|
|
4439
|
+
*/
|
|
4440
|
+
unregister(name) {
|
|
4441
|
+
return this.backends.delete(name);
|
|
4442
|
+
}
|
|
4443
|
+
/**
|
|
4444
|
+
* Clear all registered backends
|
|
4445
|
+
*
|
|
4446
|
+
* @example
|
|
4447
|
+
* ```typescript
|
|
4448
|
+
* registry.clear()
|
|
4449
|
+
* ```
|
|
4450
|
+
*/
|
|
4451
|
+
clear() {
|
|
4452
|
+
this.backends.clear();
|
|
4453
|
+
}
|
|
4454
|
+
/**
|
|
4455
|
+
* Get number of registered backends
|
|
4456
|
+
*
|
|
4457
|
+
* @returns Number of registered backends
|
|
4458
|
+
*
|
|
4459
|
+
* @example
|
|
4460
|
+
* ```typescript
|
|
4461
|
+
* const count = registry.size()
|
|
4462
|
+
* ```
|
|
4463
|
+
*/
|
|
4464
|
+
size() {
|
|
4465
|
+
return this.backends.size;
|
|
4466
|
+
}
|
|
4467
|
+
};
|
|
4468
|
+
|
|
4469
|
+
// src/settlement/router.ts
|
|
4470
|
+
var SmartRouter = class {
|
|
4471
|
+
constructor(registry) {
|
|
4472
|
+
this.registry = registry;
|
|
4473
|
+
}
|
|
4474
|
+
/**
|
|
4475
|
+
* Find best routes for a swap
|
|
4476
|
+
*
|
|
4477
|
+
* Queries all compatible backends in parallel and returns sorted routes.
|
|
4478
|
+
*
|
|
4479
|
+
* @param params - Route finding parameters
|
|
4480
|
+
* @returns Sorted routes (best first)
|
|
4481
|
+
* @throws {ValidationError} If no backends support the route
|
|
4482
|
+
*/
|
|
4483
|
+
async findBestRoute(params) {
|
|
4484
|
+
const {
|
|
4485
|
+
from,
|
|
4486
|
+
to,
|
|
4487
|
+
amount,
|
|
4488
|
+
privacyLevel,
|
|
4489
|
+
preferSpeed = false,
|
|
4490
|
+
preferLowFees = true,
|
|
4491
|
+
recipientMetaAddress,
|
|
4492
|
+
senderAddress,
|
|
4493
|
+
slippageTolerance,
|
|
4494
|
+
deadline
|
|
4495
|
+
} = params;
|
|
4496
|
+
if (amount <= 0n) {
|
|
4497
|
+
throw new ValidationError("Amount must be greater than zero");
|
|
4498
|
+
}
|
|
4499
|
+
const allBackends = this.registry.list().map((name) => this.registry.get(name));
|
|
4500
|
+
const compatibleBackends = allBackends.filter((backend) => {
|
|
4501
|
+
const { supportedSourceChains, supportedDestinationChains, supportedPrivacyLevels } = backend.capabilities;
|
|
4502
|
+
const supportsRoute = supportedSourceChains.includes(from.chain) && supportedDestinationChains.includes(to.chain);
|
|
4503
|
+
const supportsPrivacy = supportedPrivacyLevels.includes(privacyLevel);
|
|
4504
|
+
return supportsRoute && supportsPrivacy;
|
|
4505
|
+
});
|
|
4506
|
+
if (compatibleBackends.length === 0) {
|
|
4507
|
+
throw new ValidationError(
|
|
4508
|
+
`No backend supports route from ${from.chain} to ${to.chain} with privacy level ${privacyLevel}`
|
|
4509
|
+
);
|
|
4510
|
+
}
|
|
4511
|
+
const quoteParams = {
|
|
4512
|
+
fromChain: from.chain,
|
|
4513
|
+
toChain: to.chain,
|
|
4514
|
+
fromToken: from.token,
|
|
4515
|
+
toToken: to.token,
|
|
4516
|
+
amount,
|
|
4517
|
+
privacyLevel,
|
|
4518
|
+
recipientMetaAddress,
|
|
4519
|
+
senderAddress,
|
|
4520
|
+
slippageTolerance,
|
|
4521
|
+
deadline
|
|
4522
|
+
};
|
|
4523
|
+
const quotePromises = compatibleBackends.map(async (backend) => {
|
|
4524
|
+
try {
|
|
4525
|
+
const quote = await backend.getQuote(quoteParams);
|
|
4526
|
+
return {
|
|
4527
|
+
backend: backend.name,
|
|
4528
|
+
quote,
|
|
4529
|
+
backendInstance: backend,
|
|
4530
|
+
success: true
|
|
4531
|
+
};
|
|
4532
|
+
} catch (error) {
|
|
4533
|
+
return {
|
|
4534
|
+
backend: backend.name,
|
|
4535
|
+
error: error instanceof Error ? error.message : "Unknown error",
|
|
4536
|
+
success: false
|
|
4537
|
+
};
|
|
4538
|
+
}
|
|
4539
|
+
});
|
|
4540
|
+
const results = await Promise.all(quotePromises);
|
|
4541
|
+
const successfulRoutes = results.filter((r) => r.success).map((r) => ({
|
|
4542
|
+
backend: r.backend,
|
|
4543
|
+
quote: r.quote,
|
|
4544
|
+
backendInstance: r.backendInstance,
|
|
4545
|
+
score: 0
|
|
4546
|
+
// Will be calculated below
|
|
4547
|
+
}));
|
|
4548
|
+
if (successfulRoutes.length === 0) {
|
|
4549
|
+
const errors = results.filter((r) => !r.success).map((r) => `${r.backend}: ${r.error}`).join(", ");
|
|
4550
|
+
throw new NetworkError(
|
|
4551
|
+
`All backends failed to provide quotes: ${errors}`
|
|
4552
|
+
);
|
|
4553
|
+
}
|
|
4554
|
+
this.rankRoutes(successfulRoutes, { preferSpeed, preferLowFees });
|
|
4555
|
+
successfulRoutes.sort((a, b) => b.score - a.score);
|
|
4556
|
+
return successfulRoutes;
|
|
4557
|
+
}
|
|
4558
|
+
/**
|
|
4559
|
+
* Compare quotes from multiple routes side-by-side
|
|
4560
|
+
*
|
|
4561
|
+
* @param routes - Routes to compare (from findBestRoute)
|
|
4562
|
+
* @returns Comparison with best routes by different criteria
|
|
4563
|
+
*/
|
|
4564
|
+
compareQuotes(routes) {
|
|
4565
|
+
if (routes.length === 0) {
|
|
4566
|
+
return {
|
|
4567
|
+
routes: [],
|
|
4568
|
+
bestByCost: null,
|
|
4569
|
+
bestBySpeed: null,
|
|
4570
|
+
bestByPrivacy: null,
|
|
4571
|
+
metadata: {
|
|
4572
|
+
totalQueried: 0,
|
|
4573
|
+
failures: [],
|
|
4574
|
+
queriedAt: Date.now()
|
|
4575
|
+
}
|
|
4576
|
+
};
|
|
4577
|
+
}
|
|
4578
|
+
const bestByCost = [...routes].sort((a, b) => {
|
|
4579
|
+
const costA = this.calculateTotalCost(a.quote);
|
|
4580
|
+
const costB = this.calculateTotalCost(b.quote);
|
|
4581
|
+
return costA - costB;
|
|
4582
|
+
})[0];
|
|
4583
|
+
const bestBySpeed = [...routes].sort((a, b) => {
|
|
4584
|
+
const timeA = a.quote.estimatedTime ?? Infinity;
|
|
4585
|
+
const timeB = b.quote.estimatedTime ?? Infinity;
|
|
4586
|
+
return timeA - timeB;
|
|
4587
|
+
})[0];
|
|
4588
|
+
const bestByPrivacy = [...routes].find((route) => {
|
|
4589
|
+
const { supportedPrivacyLevels } = route.backendInstance.capabilities;
|
|
4590
|
+
return supportedPrivacyLevels.includes("shielded") || supportedPrivacyLevels.includes("compliant");
|
|
4591
|
+
}) || routes[0];
|
|
4592
|
+
return {
|
|
4593
|
+
routes,
|
|
4594
|
+
bestByCost,
|
|
4595
|
+
bestBySpeed,
|
|
4596
|
+
bestByPrivacy,
|
|
4597
|
+
metadata: {
|
|
4598
|
+
totalQueried: routes.length,
|
|
4599
|
+
failures: [],
|
|
4600
|
+
// Could track from findBestRoute
|
|
4601
|
+
queriedAt: Date.now()
|
|
4602
|
+
}
|
|
4603
|
+
};
|
|
4604
|
+
}
|
|
4605
|
+
/**
|
|
4606
|
+
* Rank routes by score
|
|
4607
|
+
*
|
|
4608
|
+
* Scoring algorithm:
|
|
4609
|
+
* - Base score: 100
|
|
4610
|
+
* - Cost: Lower fees = higher score (up to +50)
|
|
4611
|
+
* - Speed: Faster execution = higher score (up to +30)
|
|
4612
|
+
* - Privacy: Better privacy support = higher score (up to +20)
|
|
4613
|
+
*
|
|
4614
|
+
* @private
|
|
4615
|
+
*/
|
|
4616
|
+
rankRoutes(routes, preferences) {
|
|
4617
|
+
const { preferSpeed, preferLowFees } = preferences;
|
|
4618
|
+
const costs = routes.map((r) => this.calculateTotalCost(r.quote));
|
|
4619
|
+
const times = routes.map((r) => r.quote.estimatedTime ?? Infinity);
|
|
4620
|
+
const minCost = Math.min(...costs);
|
|
4621
|
+
const maxCost = Math.max(...costs);
|
|
4622
|
+
const minTime = Math.min(...times.filter((t) => t !== Infinity));
|
|
4623
|
+
const maxTime = Math.max(...times.filter((t) => t !== Infinity));
|
|
4624
|
+
routes.forEach((route, index) => {
|
|
4625
|
+
let score = 100;
|
|
4626
|
+
if (maxCost > minCost) {
|
|
4627
|
+
const costNormalized = 1 - (costs[index] - minCost) / (maxCost - minCost);
|
|
4628
|
+
const costWeight = preferLowFees ? 50 : 30;
|
|
4629
|
+
score += costNormalized * costWeight;
|
|
4630
|
+
}
|
|
4631
|
+
const time = times[index];
|
|
4632
|
+
if (time !== Infinity && maxTime > minTime) {
|
|
4633
|
+
const speedNormalized = 1 - (time - minTime) / (maxTime - minTime);
|
|
4634
|
+
const speedWeight = preferSpeed ? 50 : 30;
|
|
4635
|
+
score += speedNormalized * speedWeight;
|
|
4636
|
+
}
|
|
4637
|
+
const { supportedPrivacyLevels } = route.backendInstance.capabilities;
|
|
4638
|
+
if (supportedPrivacyLevels.includes("shielded")) {
|
|
4639
|
+
score += 20;
|
|
4640
|
+
} else if (supportedPrivacyLevels.includes("compliant")) {
|
|
4641
|
+
score += 10;
|
|
4642
|
+
}
|
|
4643
|
+
route.score = score;
|
|
4644
|
+
});
|
|
4645
|
+
}
|
|
4646
|
+
/**
|
|
4647
|
+
* Calculate total cost from quote
|
|
4648
|
+
*
|
|
4649
|
+
* Returns total fee in USD if available, otherwise estimates from fees
|
|
4650
|
+
*
|
|
4651
|
+
* @private
|
|
4652
|
+
*/
|
|
4653
|
+
calculateTotalCost(quote) {
|
|
4654
|
+
if (quote.fees.totalFeeUSD) {
|
|
4655
|
+
return parseFloat(quote.fees.totalFeeUSD);
|
|
4656
|
+
}
|
|
4657
|
+
const networkFee = parseFloat(quote.fees.networkFee) || 0;
|
|
4658
|
+
const protocolFee = parseFloat(quote.fees.protocolFee) || 0;
|
|
4659
|
+
return networkFee + protocolFee;
|
|
4660
|
+
}
|
|
4661
|
+
};
|
|
4662
|
+
function createSmartRouter(registry) {
|
|
4663
|
+
return new SmartRouter(registry);
|
|
4664
|
+
}
|
|
4665
|
+
|
|
4666
|
+
// src/settlement/backends/near-intents.ts
|
|
4667
|
+
var import_types8 = require("@sip-protocol/types");
|
|
4668
|
+
function mapOneClickStatus(status) {
|
|
4669
|
+
switch (status) {
|
|
4670
|
+
case import_types8.OneClickSwapStatus.PENDING_DEPOSIT:
|
|
4671
|
+
return "pending_deposit" /* PENDING_DEPOSIT */;
|
|
4672
|
+
case import_types8.OneClickSwapStatus.PROCESSING:
|
|
4673
|
+
return "in_progress" /* IN_PROGRESS */;
|
|
4674
|
+
case import_types8.OneClickSwapStatus.SUCCESS:
|
|
4675
|
+
return "success" /* SUCCESS */;
|
|
4676
|
+
case import_types8.OneClickSwapStatus.FAILED:
|
|
4677
|
+
return "failed" /* FAILED */;
|
|
4678
|
+
case import_types8.OneClickSwapStatus.INCOMPLETE_DEPOSIT:
|
|
4679
|
+
return "failed" /* FAILED */;
|
|
4680
|
+
case import_types8.OneClickSwapStatus.REFUNDED:
|
|
4681
|
+
return "refunded" /* REFUNDED */;
|
|
4682
|
+
default:
|
|
4683
|
+
return "pending_deposit" /* PENDING_DEPOSIT */;
|
|
4684
|
+
}
|
|
4685
|
+
}
|
|
4686
|
+
var NEARIntentsBackend = class {
|
|
4687
|
+
name = "near-intents";
|
|
4688
|
+
capabilities;
|
|
4689
|
+
adapter;
|
|
4690
|
+
quoteCache;
|
|
4691
|
+
constructor(config = {}) {
|
|
4692
|
+
this.adapter = new NEARIntentsAdapter(config);
|
|
4693
|
+
this.quoteCache = /* @__PURE__ */ new Map();
|
|
4694
|
+
this.capabilities = {
|
|
4695
|
+
supportedSourceChains: [
|
|
4696
|
+
"near",
|
|
4697
|
+
"ethereum",
|
|
4698
|
+
"solana",
|
|
4699
|
+
"polygon",
|
|
4700
|
+
"arbitrum",
|
|
4701
|
+
"optimism",
|
|
4702
|
+
"base",
|
|
4703
|
+
"bitcoin",
|
|
4704
|
+
"zcash"
|
|
4705
|
+
],
|
|
4706
|
+
supportedDestinationChains: [
|
|
4707
|
+
"near",
|
|
4708
|
+
"ethereum",
|
|
4709
|
+
"solana",
|
|
4710
|
+
"polygon",
|
|
4711
|
+
"arbitrum",
|
|
4712
|
+
"optimism",
|
|
4713
|
+
"base",
|
|
4714
|
+
"bitcoin",
|
|
4715
|
+
"zcash"
|
|
4716
|
+
],
|
|
4717
|
+
supportedPrivacyLevels: [
|
|
4718
|
+
import_types8.PrivacyLevel.TRANSPARENT,
|
|
4719
|
+
import_types8.PrivacyLevel.SHIELDED,
|
|
4720
|
+
import_types8.PrivacyLevel.COMPLIANT
|
|
4721
|
+
],
|
|
4722
|
+
supportsCancellation: false,
|
|
4723
|
+
supportsRefunds: true,
|
|
4724
|
+
averageExecutionTime: 300,
|
|
4725
|
+
// 5 minutes
|
|
4726
|
+
features: ["stealth-addresses", "cross-chain", "near-intents"]
|
|
4727
|
+
};
|
|
4728
|
+
}
|
|
4729
|
+
/**
|
|
4730
|
+
* Get quote for a cross-chain swap
|
|
4731
|
+
*/
|
|
4732
|
+
async getQuote(params) {
|
|
4733
|
+
this.validateQuoteParams(params);
|
|
4734
|
+
const swapRequest = {
|
|
4735
|
+
requestId: this.generateRequestId(),
|
|
4736
|
+
privacyLevel: params.privacyLevel,
|
|
4737
|
+
inputAsset: {
|
|
4738
|
+
chain: params.fromChain,
|
|
4739
|
+
symbol: params.fromToken,
|
|
4740
|
+
decimals: 0
|
|
4741
|
+
// Will be inferred by adapter
|
|
4742
|
+
},
|
|
4743
|
+
outputAsset: {
|
|
4744
|
+
chain: params.toChain,
|
|
4745
|
+
symbol: params.toToken,
|
|
4746
|
+
decimals: 0
|
|
4747
|
+
// Will be inferred by adapter
|
|
4748
|
+
},
|
|
4749
|
+
inputAmount: params.amount,
|
|
4750
|
+
minOutputAmount: params.slippageTolerance ? params.amount - params.amount * BigInt(params.slippageTolerance) / BigInt(1e4) : void 0
|
|
4751
|
+
};
|
|
4752
|
+
const prepared = await this.adapter.prepareSwap(
|
|
4753
|
+
swapRequest,
|
|
4754
|
+
params.recipientMetaAddress,
|
|
4755
|
+
params.senderAddress
|
|
4756
|
+
);
|
|
4757
|
+
const oneClickQuote = await this.adapter.getQuote(prepared);
|
|
4758
|
+
this.quoteCache.set(oneClickQuote.quoteId, params);
|
|
4759
|
+
const quote = {
|
|
4760
|
+
quoteId: oneClickQuote.quoteId,
|
|
4761
|
+
amountIn: oneClickQuote.amountIn,
|
|
4762
|
+
amountOut: oneClickQuote.amountOut,
|
|
4763
|
+
minAmountOut: oneClickQuote.amountOut,
|
|
4764
|
+
// 1Click doesn't provide separate minAmount
|
|
4765
|
+
fees: {
|
|
4766
|
+
networkFee: "0",
|
|
4767
|
+
// 1Click doesn't provide separate fee breakdown
|
|
4768
|
+
protocolFee: "0",
|
|
4769
|
+
totalFeeUSD: oneClickQuote.amountOutUsd
|
|
4770
|
+
},
|
|
4771
|
+
depositAddress: oneClickQuote.depositAddress,
|
|
4772
|
+
recipientAddress: prepared.stealthAddress?.address ?? params.senderAddress ?? "",
|
|
4773
|
+
refundAddress: params.senderAddress,
|
|
4774
|
+
expiresAt: new Date(oneClickQuote.deadline).getTime() / 1e3,
|
|
4775
|
+
estimatedTime: oneClickQuote.timeEstimate,
|
|
4776
|
+
metadata: {
|
|
4777
|
+
prepared,
|
|
4778
|
+
oneClickQuote,
|
|
4779
|
+
stealthAddress: prepared.stealthAddress,
|
|
4780
|
+
ephemeralPublicKey: prepared.stealthAddress?.ephemeralPublicKey,
|
|
4781
|
+
curve: prepared.curve
|
|
4782
|
+
}
|
|
4783
|
+
};
|
|
4784
|
+
return quote;
|
|
4785
|
+
}
|
|
4786
|
+
/**
|
|
4787
|
+
* Execute swap using a quote
|
|
4788
|
+
*/
|
|
4789
|
+
async executeSwap(params) {
|
|
4790
|
+
if (!params.quoteId) {
|
|
4791
|
+
throw new ValidationError("quoteId is required", "quoteId");
|
|
4792
|
+
}
|
|
4793
|
+
const quoteParams = this.quoteCache.get(params.quoteId);
|
|
4794
|
+
if (!quoteParams) {
|
|
4795
|
+
throw new ValidationError(
|
|
4796
|
+
"Quote not found. Please call getQuote() before executeSwap()",
|
|
4797
|
+
"quoteId"
|
|
4798
|
+
);
|
|
4799
|
+
}
|
|
4800
|
+
const swapRequest = {
|
|
4801
|
+
requestId: this.generateRequestId(),
|
|
4802
|
+
privacyLevel: quoteParams.privacyLevel,
|
|
4803
|
+
inputAsset: {
|
|
4804
|
+
chain: quoteParams.fromChain,
|
|
4805
|
+
symbol: quoteParams.fromToken,
|
|
4806
|
+
decimals: 0
|
|
4807
|
+
},
|
|
4808
|
+
outputAsset: {
|
|
4809
|
+
chain: quoteParams.toChain,
|
|
4810
|
+
symbol: quoteParams.toToken,
|
|
4811
|
+
decimals: 0
|
|
4812
|
+
},
|
|
4813
|
+
inputAmount: quoteParams.amount
|
|
4814
|
+
};
|
|
4815
|
+
const adapterResult = await this.adapter.initiateSwap(
|
|
4816
|
+
swapRequest,
|
|
4817
|
+
quoteParams.recipientMetaAddress,
|
|
4818
|
+
quoteParams.senderAddress
|
|
4819
|
+
);
|
|
4820
|
+
if (params.depositTxHash) {
|
|
4821
|
+
await this.adapter.notifyDeposit(
|
|
4822
|
+
adapterResult.depositAddress,
|
|
4823
|
+
params.depositTxHash,
|
|
4824
|
+
params.nearAccount
|
|
4825
|
+
);
|
|
4826
|
+
}
|
|
4827
|
+
const result = {
|
|
4828
|
+
swapId: adapterResult.depositAddress,
|
|
4829
|
+
// Use deposit address as swap ID
|
|
4830
|
+
status: mapOneClickStatus(adapterResult.status),
|
|
4831
|
+
quoteId: params.quoteId,
|
|
4832
|
+
depositAddress: adapterResult.depositAddress,
|
|
4833
|
+
depositTxHash: params.depositTxHash,
|
|
4834
|
+
settlementTxHash: adapterResult.settlementTxHash,
|
|
4835
|
+
actualAmountOut: adapterResult.amountOut,
|
|
4836
|
+
metadata: {
|
|
4837
|
+
adapterResult,
|
|
4838
|
+
stealthRecipient: adapterResult.stealthRecipient,
|
|
4839
|
+
ephemeralPublicKey: adapterResult.ephemeralPublicKey
|
|
4840
|
+
}
|
|
4841
|
+
};
|
|
4842
|
+
return result;
|
|
4843
|
+
}
|
|
4844
|
+
/**
|
|
4845
|
+
* Get current swap status
|
|
4846
|
+
*/
|
|
4847
|
+
async getStatus(swapId) {
|
|
4848
|
+
const oneClickStatus = await this.adapter.getStatus(swapId);
|
|
4849
|
+
const status = {
|
|
4850
|
+
swapId,
|
|
4851
|
+
status: mapOneClickStatus(oneClickStatus.status),
|
|
4852
|
+
quoteId: "",
|
|
4853
|
+
// 1Click status doesn't include quoteId
|
|
4854
|
+
depositAddress: swapId,
|
|
4855
|
+
amountIn: oneClickStatus.amountIn ?? "0",
|
|
4856
|
+
amountOut: oneClickStatus.amountOut ?? "0",
|
|
4857
|
+
depositTxHash: oneClickStatus.depositTxHash,
|
|
4858
|
+
settlementTxHash: oneClickStatus.settlementTxHash,
|
|
4859
|
+
errorMessage: oneClickStatus.error,
|
|
4860
|
+
updatedAt: Date.now() / 1e3,
|
|
4861
|
+
// 1Click doesn't provide updatedAt
|
|
4862
|
+
metadata: {
|
|
4863
|
+
oneClickStatus
|
|
4864
|
+
}
|
|
4865
|
+
};
|
|
4866
|
+
return status;
|
|
4867
|
+
}
|
|
4868
|
+
/**
|
|
4869
|
+
* Wait for swap completion (optional)
|
|
4870
|
+
*/
|
|
4871
|
+
async waitForCompletion(swapId, options) {
|
|
4872
|
+
await this.adapter.waitForCompletion(swapId, {
|
|
4873
|
+
interval: options?.interval,
|
|
4874
|
+
timeout: options?.timeout,
|
|
4875
|
+
onStatus: options?.onStatusChange ? (oneClickStatus) => {
|
|
4876
|
+
const status = {
|
|
4877
|
+
swapId,
|
|
4878
|
+
status: mapOneClickStatus(oneClickStatus.status),
|
|
4879
|
+
quoteId: "",
|
|
4880
|
+
depositAddress: swapId,
|
|
4881
|
+
amountIn: oneClickStatus.amountIn ?? "0",
|
|
4882
|
+
amountOut: oneClickStatus.amountOut ?? "0",
|
|
4883
|
+
depositTxHash: oneClickStatus.depositTxHash,
|
|
4884
|
+
settlementTxHash: oneClickStatus.settlementTxHash,
|
|
4885
|
+
errorMessage: oneClickStatus.error,
|
|
4886
|
+
updatedAt: Date.now() / 1e3,
|
|
4887
|
+
metadata: { oneClickStatus }
|
|
4888
|
+
};
|
|
4889
|
+
options.onStatusChange?.(status);
|
|
4890
|
+
} : void 0
|
|
4891
|
+
});
|
|
4892
|
+
return this.getStatus(swapId);
|
|
4893
|
+
}
|
|
4894
|
+
/**
|
|
4895
|
+
* Get dry quote (preview without creating deposit address)
|
|
4896
|
+
*/
|
|
4897
|
+
async getDryQuote(params) {
|
|
4898
|
+
this.validateQuoteParams(params);
|
|
4899
|
+
const swapRequest = {
|
|
4900
|
+
requestId: this.generateRequestId(),
|
|
4901
|
+
privacyLevel: params.privacyLevel,
|
|
4902
|
+
inputAsset: {
|
|
4903
|
+
chain: params.fromChain,
|
|
4904
|
+
symbol: params.fromToken,
|
|
4905
|
+
decimals: 0
|
|
4906
|
+
},
|
|
4907
|
+
outputAsset: {
|
|
4908
|
+
chain: params.toChain,
|
|
4909
|
+
symbol: params.toToken,
|
|
4910
|
+
decimals: 0
|
|
4911
|
+
},
|
|
4912
|
+
inputAmount: params.amount
|
|
4913
|
+
};
|
|
4914
|
+
const prepared = await this.adapter.prepareSwap(
|
|
4915
|
+
swapRequest,
|
|
4916
|
+
params.recipientMetaAddress,
|
|
4917
|
+
params.senderAddress
|
|
4918
|
+
);
|
|
4919
|
+
const oneClickQuote = await this.adapter.getDryQuote(prepared);
|
|
4920
|
+
const quote = {
|
|
4921
|
+
quoteId: oneClickQuote.quoteId,
|
|
4922
|
+
amountIn: oneClickQuote.amountIn,
|
|
4923
|
+
amountOut: oneClickQuote.amountOut,
|
|
4924
|
+
minAmountOut: oneClickQuote.amountOut,
|
|
4925
|
+
fees: {
|
|
4926
|
+
networkFee: "0",
|
|
4927
|
+
protocolFee: "0",
|
|
4928
|
+
totalFeeUSD: oneClickQuote.amountOutUsd
|
|
4929
|
+
},
|
|
4930
|
+
depositAddress: oneClickQuote.depositAddress,
|
|
4931
|
+
recipientAddress: prepared.stealthAddress?.address ?? params.senderAddress ?? "",
|
|
4932
|
+
refundAddress: params.senderAddress,
|
|
4933
|
+
expiresAt: new Date(oneClickQuote.deadline).getTime() / 1e3,
|
|
4934
|
+
estimatedTime: oneClickQuote.timeEstimate,
|
|
4935
|
+
metadata: {
|
|
4936
|
+
prepared,
|
|
4937
|
+
oneClickQuote,
|
|
4938
|
+
stealthAddress: prepared.stealthAddress,
|
|
4939
|
+
ephemeralPublicKey: prepared.stealthAddress?.ephemeralPublicKey,
|
|
4940
|
+
curve: prepared.curve,
|
|
4941
|
+
isDryQuote: true
|
|
4942
|
+
}
|
|
4943
|
+
};
|
|
4944
|
+
return quote;
|
|
4945
|
+
}
|
|
4946
|
+
/**
|
|
4947
|
+
* Notify backend of deposit transaction
|
|
4948
|
+
*/
|
|
4949
|
+
async notifyDeposit(swapId, txHash, metadata) {
|
|
4950
|
+
await this.adapter.notifyDeposit(
|
|
4951
|
+
swapId,
|
|
4952
|
+
// swapId is deposit address
|
|
4953
|
+
txHash,
|
|
4954
|
+
metadata?.nearAccount
|
|
4955
|
+
);
|
|
4956
|
+
}
|
|
4957
|
+
// ─── Private Methods ──────────────────────────────────────────────────────────
|
|
4958
|
+
validateQuoteParams(params) {
|
|
4959
|
+
if (!params.fromChain) {
|
|
4960
|
+
throw new ValidationError("fromChain is required", "fromChain");
|
|
4961
|
+
}
|
|
4962
|
+
if (!params.toChain) {
|
|
4963
|
+
throw new ValidationError("toChain is required", "toChain");
|
|
4964
|
+
}
|
|
4965
|
+
if (!params.fromToken) {
|
|
4966
|
+
throw new ValidationError("fromToken is required", "fromToken");
|
|
4967
|
+
}
|
|
4968
|
+
if (!params.toToken) {
|
|
4969
|
+
throw new ValidationError("toToken is required", "toToken");
|
|
4970
|
+
}
|
|
4971
|
+
if (!params.amount || params.amount <= BigInt(0)) {
|
|
4972
|
+
throw new ValidationError("amount must be greater than 0", "amount");
|
|
4973
|
+
}
|
|
4974
|
+
if (!params.privacyLevel) {
|
|
4975
|
+
throw new ValidationError("privacyLevel is required", "privacyLevel");
|
|
4976
|
+
}
|
|
4977
|
+
if (params.privacyLevel !== import_types8.PrivacyLevel.TRANSPARENT && !params.recipientMetaAddress) {
|
|
4978
|
+
throw new ValidationError(
|
|
4979
|
+
"recipientMetaAddress is required for shielded/compliant privacy modes",
|
|
4980
|
+
"recipientMetaAddress"
|
|
4981
|
+
);
|
|
4982
|
+
}
|
|
4983
|
+
if (params.privacyLevel === import_types8.PrivacyLevel.TRANSPARENT && !params.senderAddress) {
|
|
4984
|
+
throw new ValidationError(
|
|
4985
|
+
"senderAddress is required for transparent mode",
|
|
4986
|
+
"senderAddress"
|
|
4987
|
+
);
|
|
4988
|
+
}
|
|
4989
|
+
if (!this.capabilities.supportedSourceChains.includes(params.fromChain)) {
|
|
4990
|
+
throw new ValidationError(
|
|
4991
|
+
`Source chain ${params.fromChain} is not supported`,
|
|
4992
|
+
"fromChain",
|
|
4993
|
+
{ supportedChains: this.capabilities.supportedSourceChains }
|
|
4994
|
+
);
|
|
4995
|
+
}
|
|
4996
|
+
if (!this.capabilities.supportedDestinationChains.includes(params.toChain)) {
|
|
4997
|
+
throw new ValidationError(
|
|
4998
|
+
`Destination chain ${params.toChain} is not supported`,
|
|
4999
|
+
"toChain",
|
|
5000
|
+
{ supportedChains: this.capabilities.supportedDestinationChains }
|
|
5001
|
+
);
|
|
5002
|
+
}
|
|
5003
|
+
}
|
|
5004
|
+
generateRequestId() {
|
|
5005
|
+
return `req_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;
|
|
5006
|
+
}
|
|
5007
|
+
};
|
|
5008
|
+
function createNEARIntentsBackend(config) {
|
|
5009
|
+
return new NEARIntentsBackend(config);
|
|
5010
|
+
}
|
|
5011
|
+
|
|
5012
|
+
// src/settlement/backends/zcash-native.ts
|
|
5013
|
+
var import_types9 = require("@sip-protocol/types");
|
|
5014
|
+
var ZcashNativeBackend = class {
|
|
5015
|
+
name = "zcash-native";
|
|
5016
|
+
capabilities;
|
|
5017
|
+
swapService;
|
|
5018
|
+
config;
|
|
5019
|
+
quotes = /* @__PURE__ */ new Map();
|
|
5020
|
+
swaps = /* @__PURE__ */ new Map();
|
|
5021
|
+
constructor(config) {
|
|
5022
|
+
this.swapService = config.swapService;
|
|
5023
|
+
this.config = {
|
|
5024
|
+
quoteValiditySeconds: config.quoteValiditySeconds ?? 300,
|
|
5025
|
+
networkFeeZatoshis: config.networkFeeZatoshis ?? 1e4
|
|
5026
|
+
};
|
|
5027
|
+
this.capabilities = {
|
|
5028
|
+
supportedSourceChains: ["zcash"],
|
|
5029
|
+
supportedDestinationChains: ["zcash"],
|
|
5030
|
+
supportedPrivacyLevels: [
|
|
5031
|
+
import_types9.PrivacyLevel.TRANSPARENT,
|
|
5032
|
+
import_types9.PrivacyLevel.SHIELDED,
|
|
5033
|
+
import_types9.PrivacyLevel.COMPLIANT
|
|
5034
|
+
],
|
|
5035
|
+
supportsCancellation: false,
|
|
5036
|
+
supportsRefunds: false,
|
|
5037
|
+
averageExecutionTime: 75,
|
|
5038
|
+
// ~75 seconds for Zcash block confirmation
|
|
5039
|
+
features: [
|
|
5040
|
+
"native-zcash",
|
|
5041
|
+
"shielded-addresses",
|
|
5042
|
+
"transparent-addresses",
|
|
5043
|
+
"instant-quotes"
|
|
5044
|
+
]
|
|
5045
|
+
};
|
|
5046
|
+
}
|
|
5047
|
+
// ─── Quote Methods ─────────────────────────────────────────────────────────
|
|
5048
|
+
/**
|
|
5049
|
+
* Get a quote for ZEC → ZEC transfer
|
|
5050
|
+
*/
|
|
5051
|
+
async getQuote(params) {
|
|
5052
|
+
this.validateQuoteParams(params);
|
|
5053
|
+
const { amount, recipientMetaAddress, senderAddress, privacyLevel } = params;
|
|
5054
|
+
const quoteId = this.generateQuoteId();
|
|
5055
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
5056
|
+
const expiresAt = now + this.config.quoteValiditySeconds;
|
|
5057
|
+
const networkFee = BigInt(this.config.networkFeeZatoshis);
|
|
5058
|
+
const protocolFee = BigInt(0);
|
|
5059
|
+
const totalFee = networkFee;
|
|
5060
|
+
const amountOut = amount - totalFee;
|
|
5061
|
+
if (amountOut <= BigInt(0)) {
|
|
5062
|
+
throw new ValidationError(
|
|
5063
|
+
"Amount too small to cover network fees",
|
|
5064
|
+
"amount",
|
|
5065
|
+
{ amount: amount.toString(), networkFee: networkFee.toString() },
|
|
5066
|
+
"SIP_2004" /* INVALID_AMOUNT */
|
|
5067
|
+
);
|
|
5068
|
+
}
|
|
5069
|
+
const minAmountOut = amountOut * BigInt(99) / BigInt(100);
|
|
5070
|
+
let depositAddress;
|
|
5071
|
+
let recipientAddress;
|
|
5072
|
+
if (privacyLevel === import_types9.PrivacyLevel.SHIELDED || privacyLevel === import_types9.PrivacyLevel.COMPLIANT) {
|
|
5073
|
+
if (typeof recipientMetaAddress === "string") {
|
|
5074
|
+
recipientAddress = recipientMetaAddress;
|
|
5075
|
+
} else if (recipientMetaAddress) {
|
|
5076
|
+
recipientAddress = `zs1${this.randomHex(72)}`;
|
|
5077
|
+
} else {
|
|
5078
|
+
throw new ValidationError(
|
|
5079
|
+
"Recipient address required for shielded transfers",
|
|
5080
|
+
"recipientMetaAddress",
|
|
5081
|
+
void 0,
|
|
5082
|
+
"SIP_2000" /* VALIDATION_FAILED */
|
|
5083
|
+
);
|
|
5084
|
+
}
|
|
5085
|
+
depositAddress = `zs1${this.randomHex(72)}`;
|
|
5086
|
+
} else {
|
|
5087
|
+
if (senderAddress) {
|
|
5088
|
+
depositAddress = senderAddress;
|
|
5089
|
+
} else {
|
|
5090
|
+
depositAddress = `t1${this.randomBase58(33)}`;
|
|
5091
|
+
}
|
|
5092
|
+
if (typeof recipientMetaAddress === "string") {
|
|
5093
|
+
recipientAddress = recipientMetaAddress;
|
|
5094
|
+
} else {
|
|
5095
|
+
throw new ValidationError(
|
|
5096
|
+
"Recipient address required",
|
|
5097
|
+
"recipientMetaAddress",
|
|
5098
|
+
void 0,
|
|
5099
|
+
"SIP_2000" /* VALIDATION_FAILED */
|
|
5100
|
+
);
|
|
5101
|
+
}
|
|
5102
|
+
}
|
|
5103
|
+
const quote = {
|
|
5104
|
+
quoteId,
|
|
5105
|
+
amountIn: amount.toString(),
|
|
5106
|
+
amountOut: amountOut.toString(),
|
|
5107
|
+
minAmountOut: minAmountOut.toString(),
|
|
5108
|
+
fees: {
|
|
5109
|
+
networkFee: networkFee.toString(),
|
|
5110
|
+
protocolFee: protocolFee.toString()
|
|
5111
|
+
},
|
|
5112
|
+
depositAddress,
|
|
5113
|
+
recipientAddress,
|
|
5114
|
+
expiresAt,
|
|
5115
|
+
estimatedTime: this.capabilities.averageExecutionTime,
|
|
5116
|
+
metadata: {
|
|
5117
|
+
backend: this.name,
|
|
5118
|
+
privacyLevel,
|
|
5119
|
+
zcashNetwork: "mainnet"
|
|
5120
|
+
}
|
|
5121
|
+
};
|
|
5122
|
+
this.quotes.set(quoteId, quote);
|
|
5123
|
+
return quote;
|
|
5124
|
+
}
|
|
5125
|
+
/**
|
|
5126
|
+
* Get a dry quote (preview without creating deposit address)
|
|
5127
|
+
*/
|
|
5128
|
+
async getDryQuote(params) {
|
|
5129
|
+
return this.getQuote(params);
|
|
5130
|
+
}
|
|
5131
|
+
// ─── Swap Execution ────────────────────────────────────────────────────────
|
|
5132
|
+
/**
|
|
5133
|
+
* Execute a ZEC → ZEC swap/transfer
|
|
5134
|
+
*/
|
|
5135
|
+
async executeSwap(params) {
|
|
5136
|
+
const { quoteId, depositTxHash } = params;
|
|
5137
|
+
const quote = this.quotes.get(quoteId);
|
|
5138
|
+
if (!quote) {
|
|
5139
|
+
throw new ValidationError(
|
|
5140
|
+
"Quote not found or expired",
|
|
5141
|
+
"quoteId",
|
|
5142
|
+
{ quoteId },
|
|
5143
|
+
"SIP_2000" /* VALIDATION_FAILED */
|
|
5144
|
+
);
|
|
5145
|
+
}
|
|
5146
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
5147
|
+
if (now > quote.expiresAt) {
|
|
5148
|
+
throw new ValidationError(
|
|
5149
|
+
"Quote has expired",
|
|
5150
|
+
"quoteId",
|
|
5151
|
+
{ quoteId, expiresAt: quote.expiresAt, now },
|
|
5152
|
+
"SIP_2000" /* VALIDATION_FAILED */
|
|
5153
|
+
);
|
|
5154
|
+
}
|
|
5155
|
+
const swapId = this.generateSwapId();
|
|
5156
|
+
const result = {
|
|
5157
|
+
swapId,
|
|
5158
|
+
status: depositTxHash ? "deposit_confirmed" /* DEPOSIT_CONFIRMED */ : "pending_deposit" /* PENDING_DEPOSIT */,
|
|
5159
|
+
quoteId,
|
|
5160
|
+
depositAddress: quote.depositAddress,
|
|
5161
|
+
depositTxHash,
|
|
5162
|
+
metadata: {
|
|
5163
|
+
backend: this.name,
|
|
5164
|
+
recipientAddress: quote.recipientAddress
|
|
5165
|
+
}
|
|
5166
|
+
};
|
|
5167
|
+
this.swaps.set(swapId, result);
|
|
5168
|
+
if (depositTxHash) {
|
|
5169
|
+
this.simulateSwapExecution(swapId, quote);
|
|
5170
|
+
}
|
|
5171
|
+
return result;
|
|
4170
5172
|
}
|
|
5173
|
+
// ─── Status Methods ────────────────────────────────────────────────────────
|
|
4171
5174
|
/**
|
|
4172
|
-
*
|
|
4173
|
-
*
|
|
4174
|
-
* In production, this would:
|
|
4175
|
-
* 1. Lock collateral
|
|
4176
|
-
* 2. Execute the swap on destination chain
|
|
4177
|
-
* 3. Generate fulfillment proof
|
|
4178
|
-
* 4. Release collateral after verification
|
|
4179
|
-
*
|
|
4180
|
-
* Privacy preserved:
|
|
4181
|
-
* - Funds go to stealth address (unlinkable)
|
|
4182
|
-
* - Solver never learns recipient's real identity
|
|
5175
|
+
* Get swap status
|
|
4183
5176
|
*/
|
|
4184
|
-
async
|
|
4185
|
-
const
|
|
4186
|
-
|
|
4187
|
-
|
|
4188
|
-
|
|
4189
|
-
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
|
|
4193
|
-
status.error = "Simulated failure for testing";
|
|
4194
|
-
return {
|
|
4195
|
-
intentId: intent.intentId,
|
|
4196
|
-
status: import_types7.IntentStatus.FAILED,
|
|
4197
|
-
fulfilledAt: Math.floor(Date.now() / 1e3),
|
|
4198
|
-
error: status.error
|
|
4199
|
-
};
|
|
5177
|
+
async getStatus(swapId) {
|
|
5178
|
+
const swap = this.swaps.get(swapId);
|
|
5179
|
+
if (!swap) {
|
|
5180
|
+
throw new ValidationError(
|
|
5181
|
+
"Swap not found",
|
|
5182
|
+
"swapId",
|
|
5183
|
+
{ swapId },
|
|
5184
|
+
"SIP_2000" /* VALIDATION_FAILED */
|
|
5185
|
+
);
|
|
4200
5186
|
}
|
|
4201
|
-
const
|
|
4202
|
-
|
|
4203
|
-
|
|
4204
|
-
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
|
|
4209
|
-
|
|
4210
|
-
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
4217
|
-
|
|
5187
|
+
const quote = this.quotes.get(swap.quoteId);
|
|
5188
|
+
if (!quote) {
|
|
5189
|
+
throw new ValidationError(
|
|
5190
|
+
"Quote not found for swap",
|
|
5191
|
+
"quoteId",
|
|
5192
|
+
{ quoteId: swap.quoteId },
|
|
5193
|
+
"SIP_2000" /* VALIDATION_FAILED */
|
|
5194
|
+
);
|
|
5195
|
+
}
|
|
5196
|
+
const status = {
|
|
5197
|
+
swapId: swap.swapId,
|
|
5198
|
+
status: swap.status,
|
|
5199
|
+
quoteId: swap.quoteId,
|
|
5200
|
+
depositAddress: swap.depositAddress,
|
|
5201
|
+
amountIn: quote.amountIn,
|
|
5202
|
+
amountOut: quote.amountOut,
|
|
5203
|
+
depositTxHash: swap.depositTxHash,
|
|
5204
|
+
settlementTxHash: swap.settlementTxHash,
|
|
5205
|
+
actualAmountOut: swap.actualAmountOut,
|
|
5206
|
+
errorMessage: swap.errorMessage,
|
|
5207
|
+
updatedAt: Math.floor(Date.now() / 1e3),
|
|
5208
|
+
metadata: swap.metadata
|
|
4218
5209
|
};
|
|
5210
|
+
return status;
|
|
4219
5211
|
}
|
|
4220
5212
|
/**
|
|
4221
|
-
*
|
|
5213
|
+
* Wait for swap completion
|
|
4222
5214
|
*/
|
|
4223
|
-
async
|
|
4224
|
-
const
|
|
4225
|
-
|
|
4226
|
-
|
|
5215
|
+
async waitForCompletion(swapId, options) {
|
|
5216
|
+
const interval = options?.interval ?? 5e3;
|
|
5217
|
+
const timeout = options?.timeout ?? 6e5;
|
|
5218
|
+
const startTime = Date.now();
|
|
5219
|
+
while (Date.now() - startTime < timeout) {
|
|
5220
|
+
const status2 = await this.getStatus(swapId);
|
|
5221
|
+
if (options?.onStatusChange) {
|
|
5222
|
+
options.onStatusChange(status2);
|
|
5223
|
+
}
|
|
5224
|
+
if (status2.status === "success" /* SUCCESS */) {
|
|
5225
|
+
return status2;
|
|
5226
|
+
}
|
|
5227
|
+
if (status2.status === "failed" /* FAILED */ || status2.status === "cancelled" /* CANCELLED */ || status2.status === "refunded" /* REFUNDED */) {
|
|
5228
|
+
return status2;
|
|
5229
|
+
}
|
|
5230
|
+
await this.delay(interval);
|
|
4227
5231
|
}
|
|
4228
|
-
status
|
|
4229
|
-
return
|
|
5232
|
+
const status = await this.getStatus(swapId);
|
|
5233
|
+
return status;
|
|
4230
5234
|
}
|
|
4231
5235
|
/**
|
|
4232
|
-
*
|
|
5236
|
+
* Notify backend of deposit
|
|
4233
5237
|
*/
|
|
4234
|
-
async
|
|
4235
|
-
|
|
5238
|
+
async notifyDeposit(swapId, txHash, metadata) {
|
|
5239
|
+
const swap = this.swaps.get(swapId);
|
|
5240
|
+
if (!swap) {
|
|
5241
|
+
throw new ValidationError(
|
|
5242
|
+
"Swap not found",
|
|
5243
|
+
"swapId",
|
|
5244
|
+
{ swapId },
|
|
5245
|
+
"SIP_2000" /* VALIDATION_FAILED */
|
|
5246
|
+
);
|
|
5247
|
+
}
|
|
5248
|
+
swap.depositTxHash = txHash;
|
|
5249
|
+
swap.status = "deposit_confirmed" /* DEPOSIT_CONFIRMED */;
|
|
5250
|
+
if (metadata) {
|
|
5251
|
+
swap.metadata = { ...swap.metadata, ...metadata };
|
|
5252
|
+
}
|
|
5253
|
+
this.swaps.set(swapId, swap);
|
|
5254
|
+
const quote = this.quotes.get(swap.quoteId);
|
|
5255
|
+
if (quote) {
|
|
5256
|
+
this.simulateSwapExecution(swapId, quote);
|
|
5257
|
+
}
|
|
4236
5258
|
}
|
|
4237
|
-
|
|
4238
|
-
|
|
4239
|
-
|
|
4240
|
-
|
|
4241
|
-
|
|
5259
|
+
// ─── Private Helpers ───────────────────────────────────────────────────────
|
|
5260
|
+
validateQuoteParams(params) {
|
|
5261
|
+
if (params.fromChain !== "zcash") {
|
|
5262
|
+
throw new ValidationError(
|
|
5263
|
+
"Source chain must be zcash",
|
|
5264
|
+
"fromChain",
|
|
5265
|
+
{ received: params.fromChain, expected: "zcash" },
|
|
5266
|
+
"SIP_2000" /* VALIDATION_FAILED */
|
|
5267
|
+
);
|
|
5268
|
+
}
|
|
5269
|
+
if (params.toChain !== "zcash") {
|
|
5270
|
+
throw new ValidationError(
|
|
5271
|
+
"Destination chain must be zcash",
|
|
5272
|
+
"toChain",
|
|
5273
|
+
{ received: params.toChain, expected: "zcash" },
|
|
5274
|
+
"SIP_2000" /* VALIDATION_FAILED */
|
|
5275
|
+
);
|
|
5276
|
+
}
|
|
5277
|
+
if (params.fromToken !== "ZEC") {
|
|
5278
|
+
throw new ValidationError(
|
|
5279
|
+
"Source token must be ZEC",
|
|
5280
|
+
"fromToken",
|
|
5281
|
+
{ received: params.fromToken, expected: "ZEC" },
|
|
5282
|
+
"SIP_2000" /* VALIDATION_FAILED */
|
|
5283
|
+
);
|
|
5284
|
+
}
|
|
5285
|
+
if (params.toToken !== "ZEC") {
|
|
5286
|
+
throw new ValidationError(
|
|
5287
|
+
"Destination token must be ZEC",
|
|
5288
|
+
"toToken",
|
|
5289
|
+
{ received: params.toToken, expected: "ZEC" },
|
|
5290
|
+
"SIP_2000" /* VALIDATION_FAILED */
|
|
5291
|
+
);
|
|
5292
|
+
}
|
|
5293
|
+
if (!params.amount || params.amount <= BigInt(0)) {
|
|
5294
|
+
throw new ValidationError(
|
|
5295
|
+
"Amount must be positive",
|
|
5296
|
+
"amount",
|
|
5297
|
+
{ received: params.amount },
|
|
5298
|
+
"SIP_2004" /* INVALID_AMOUNT */
|
|
5299
|
+
);
|
|
5300
|
+
}
|
|
5301
|
+
if (!this.capabilities.supportedPrivacyLevels.includes(params.privacyLevel)) {
|
|
5302
|
+
throw new ValidationError(
|
|
5303
|
+
"Unsupported privacy level",
|
|
5304
|
+
"privacyLevel",
|
|
5305
|
+
{ received: params.privacyLevel, supported: this.capabilities.supportedPrivacyLevels },
|
|
5306
|
+
"SIP_2000" /* VALIDATION_FAILED */
|
|
5307
|
+
);
|
|
5308
|
+
}
|
|
5309
|
+
}
|
|
5310
|
+
simulateSwapExecution(swapId, quote) {
|
|
5311
|
+
setTimeout(() => {
|
|
5312
|
+
const swap = this.swaps.get(swapId);
|
|
5313
|
+
if (!swap) return;
|
|
5314
|
+
swap.status = "in_progress" /* IN_PROGRESS */;
|
|
5315
|
+
this.swaps.set(swapId, swap);
|
|
5316
|
+
setTimeout(() => {
|
|
5317
|
+
const finalSwap = this.swaps.get(swapId);
|
|
5318
|
+
if (!finalSwap) return;
|
|
5319
|
+
finalSwap.status = "success" /* SUCCESS */;
|
|
5320
|
+
finalSwap.settlementTxHash = this.randomHex(64);
|
|
5321
|
+
finalSwap.actualAmountOut = quote.amountOut;
|
|
5322
|
+
this.swaps.set(swapId, finalSwap);
|
|
5323
|
+
}, 2e3);
|
|
5324
|
+
}, 1e3);
|
|
5325
|
+
}
|
|
5326
|
+
generateQuoteId() {
|
|
5327
|
+
return `zec_native_quote_${Date.now()}_${this.randomHex(8)}`;
|
|
5328
|
+
}
|
|
5329
|
+
generateSwapId() {
|
|
5330
|
+
return `zec_native_swap_${Date.now()}_${this.randomHex(8)}`;
|
|
5331
|
+
}
|
|
5332
|
+
randomHex(length) {
|
|
5333
|
+
const chars = "0123456789abcdef";
|
|
5334
|
+
let result = "";
|
|
5335
|
+
for (let i = 0; i < length; i++) {
|
|
5336
|
+
result += chars[Math.floor(Math.random() * chars.length)];
|
|
5337
|
+
}
|
|
5338
|
+
return result;
|
|
5339
|
+
}
|
|
5340
|
+
randomBase58(length) {
|
|
5341
|
+
const chars = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
5342
|
+
let result = "";
|
|
5343
|
+
for (let i = 0; i < length; i++) {
|
|
5344
|
+
result += chars[Math.floor(Math.random() * chars.length)];
|
|
5345
|
+
}
|
|
5346
|
+
return result;
|
|
4242
5347
|
}
|
|
4243
5348
|
delay(ms) {
|
|
4244
5349
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
4245
5350
|
}
|
|
4246
5351
|
};
|
|
4247
|
-
function
|
|
4248
|
-
return new
|
|
5352
|
+
function createZcashNativeBackend(config) {
|
|
5353
|
+
return new ZcashNativeBackend(config);
|
|
4249
5354
|
}
|
|
4250
5355
|
|
|
4251
|
-
// src/
|
|
4252
|
-
var
|
|
5356
|
+
// src/settlement/backends/direct-chain.ts
|
|
5357
|
+
var import_types10 = require("@sip-protocol/types");
|
|
5358
|
+
var import_utils11 = require("@noble/hashes/utils");
|
|
5359
|
+
var DEFAULT_GAS_FEES = {
|
|
5360
|
+
ethereum: 21000n * 50n * 1000000000n,
|
|
5361
|
+
// 21k gas * 50 gwei = 0.00105 ETH
|
|
5362
|
+
solana: 5000n,
|
|
5363
|
+
// 5000 lamports = 0.000005 SOL
|
|
5364
|
+
near: 300000000000000000000n,
|
|
5365
|
+
// 0.3 NEAR in yoctoNEAR
|
|
5366
|
+
zcash: 10000n,
|
|
5367
|
+
// 0.0001 ZEC in zatoshi
|
|
5368
|
+
polygon: 21000n * 30n * 1000000000n,
|
|
5369
|
+
// 21k gas * 30 gwei POL
|
|
5370
|
+
arbitrum: 2100000000n,
|
|
5371
|
+
// 21k gas * 0.1 gwei ETH = 2100 gwei = 2.1e9 wei
|
|
5372
|
+
optimism: 21000000n,
|
|
5373
|
+
// 21k gas * 0.001 gwei ETH = 21 gwei = 21e6 wei
|
|
5374
|
+
base: 2100000000n,
|
|
5375
|
+
// 21k gas * 0.1 gwei ETH = 2100 gwei = 2.1e9 wei
|
|
5376
|
+
bitcoin: 10000n
|
|
5377
|
+
// 10000 sats = 0.0001 BTC (estimate for 1 input, 2 outputs)
|
|
5378
|
+
};
|
|
4253
5379
|
|
|
4254
5380
|
// src/zcash/rpc-client.ts
|
|
4255
|
-
var
|
|
5381
|
+
var import_types11 = require("@sip-protocol/types");
|
|
4256
5382
|
var DEFAULT_CONFIG = {
|
|
4257
5383
|
host: "127.0.0.1",
|
|
4258
5384
|
port: 8232,
|
|
@@ -4272,19 +5398,19 @@ var ZcashRPCError = class extends Error {
|
|
|
4272
5398
|
* Check if error is due to insufficient funds
|
|
4273
5399
|
*/
|
|
4274
5400
|
isInsufficientFunds() {
|
|
4275
|
-
return this.code ===
|
|
5401
|
+
return this.code === import_types11.ZcashErrorCode.WALLET_INSUFFICIENT_FUNDS;
|
|
4276
5402
|
}
|
|
4277
5403
|
/**
|
|
4278
5404
|
* Check if error is due to invalid address
|
|
4279
5405
|
*/
|
|
4280
5406
|
isInvalidAddress() {
|
|
4281
|
-
return this.code ===
|
|
5407
|
+
return this.code === import_types11.ZcashErrorCode.INVALID_ADDRESS_OR_KEY;
|
|
4282
5408
|
}
|
|
4283
5409
|
/**
|
|
4284
5410
|
* Check if error is due to wallet being locked
|
|
4285
5411
|
*/
|
|
4286
5412
|
isWalletLocked() {
|
|
4287
|
-
return this.code ===
|
|
5413
|
+
return this.code === import_types11.ZcashErrorCode.WALLET_UNLOCK_NEEDED;
|
|
4288
5414
|
}
|
|
4289
5415
|
};
|
|
4290
5416
|
var ZcashRPCClient = class {
|
|
@@ -4671,7 +5797,7 @@ function createZcashClient(config) {
|
|
|
4671
5797
|
}
|
|
4672
5798
|
|
|
4673
5799
|
// src/zcash/shielded-service.ts
|
|
4674
|
-
var
|
|
5800
|
+
var import_types12 = require("@sip-protocol/types");
|
|
4675
5801
|
var ZcashShieldedService = class _ZcashShieldedService {
|
|
4676
5802
|
client;
|
|
4677
5803
|
config;
|
|
@@ -4857,7 +5983,7 @@ var ZcashShieldedService = class _ZcashShieldedService {
|
|
|
4857
5983
|
* Higher-level method that handles privacy level mapping.
|
|
4858
5984
|
*/
|
|
4859
5985
|
async sendWithPrivacy(to, amount, privacyLevel, memo) {
|
|
4860
|
-
if (privacyLevel ===
|
|
5986
|
+
if (privacyLevel === import_types12.PrivacyLevel.TRANSPARENT) {
|
|
4861
5987
|
throw new ValidationError(
|
|
4862
5988
|
"Transparent mode not supported for Zcash shielded service. Use standard RPC client.",
|
|
4863
5989
|
"privacyLevel",
|
|
@@ -4951,7 +6077,7 @@ var ZcashShieldedService = class _ZcashShieldedService {
|
|
|
4951
6077
|
const viewingKey = await this.exportViewingKey();
|
|
4952
6078
|
return {
|
|
4953
6079
|
viewingKey,
|
|
4954
|
-
privacyLevel:
|
|
6080
|
+
privacyLevel: import_types12.PrivacyLevel.COMPLIANT,
|
|
4955
6081
|
disclaimer: "This viewing key provides read-only access to transaction history. It cannot be used to spend funds. Share only with authorized auditors."
|
|
4956
6082
|
};
|
|
4957
6083
|
}
|
|
@@ -5037,11 +6163,11 @@ var ZcashShieldedService = class _ZcashShieldedService {
|
|
|
5037
6163
|
*/
|
|
5038
6164
|
mapPrivacyLevelToPolicy(level) {
|
|
5039
6165
|
switch (level) {
|
|
5040
|
-
case
|
|
6166
|
+
case import_types12.PrivacyLevel.TRANSPARENT:
|
|
5041
6167
|
return "NoPrivacy";
|
|
5042
|
-
case
|
|
6168
|
+
case import_types12.PrivacyLevel.SHIELDED:
|
|
5043
6169
|
return "FullPrivacy";
|
|
5044
|
-
case
|
|
6170
|
+
case import_types12.PrivacyLevel.COMPLIANT:
|
|
5045
6171
|
return "FullPrivacy";
|
|
5046
6172
|
default:
|
|
5047
6173
|
return "FullPrivacy";
|
|
@@ -5094,7 +6220,7 @@ function createZcashShieldedService(config) {
|
|
|
5094
6220
|
}
|
|
5095
6221
|
|
|
5096
6222
|
// src/zcash/swap-service.ts
|
|
5097
|
-
var
|
|
6223
|
+
var import_types13 = require("@sip-protocol/types");
|
|
5098
6224
|
var MOCK_PRICES = {
|
|
5099
6225
|
ETH: 2500,
|
|
5100
6226
|
SOL: 120,
|
|
@@ -5122,6 +6248,12 @@ var ZcashSwapService = class {
|
|
|
5122
6248
|
quotes = /* @__PURE__ */ new Map();
|
|
5123
6249
|
swaps = /* @__PURE__ */ new Map();
|
|
5124
6250
|
constructor(config) {
|
|
6251
|
+
if (config.mode === "production" && !config.bridgeProvider) {
|
|
6252
|
+
throw new IntentError(
|
|
6253
|
+
"Bridge provider required for production mode",
|
|
6254
|
+
"SIP_5004" /* INTENT_INVALID_STATE */
|
|
6255
|
+
);
|
|
6256
|
+
}
|
|
5125
6257
|
this.config = {
|
|
5126
6258
|
mode: config.mode,
|
|
5127
6259
|
defaultSlippage: config.defaultSlippage ?? 100,
|
|
@@ -5201,7 +6333,7 @@ var ZcashSwapService = class {
|
|
|
5201
6333
|
validUntil,
|
|
5202
6334
|
depositAddress: this.generateMockDepositAddress(sourceChain),
|
|
5203
6335
|
estimatedTime: this.getEstimatedTime(sourceChain),
|
|
5204
|
-
privacyLevel:
|
|
6336
|
+
privacyLevel: import_types13.PrivacyLevel.SHIELDED
|
|
5205
6337
|
};
|
|
5206
6338
|
this.quotes.set(quoteId, quote);
|
|
5207
6339
|
return quote;
|
|
@@ -5244,7 +6376,7 @@ var ZcashSwapService = class {
|
|
|
5244
6376
|
depositAddress: "",
|
|
5245
6377
|
// Will be set by bridge
|
|
5246
6378
|
estimatedTime: this.getEstimatedTime(params.sourceChain),
|
|
5247
|
-
privacyLevel:
|
|
6379
|
+
privacyLevel: import_types13.PrivacyLevel.SHIELDED
|
|
5248
6380
|
};
|
|
5249
6381
|
this.quotes.set(quote.quoteId, quote);
|
|
5250
6382
|
return quote;
|
|
@@ -5524,15 +6656,15 @@ function createZcashSwapService(config) {
|
|
|
5524
6656
|
}
|
|
5525
6657
|
|
|
5526
6658
|
// src/zcash/index.ts
|
|
5527
|
-
var
|
|
6659
|
+
var import_types14 = require("@sip-protocol/types");
|
|
5528
6660
|
|
|
5529
6661
|
// src/index.ts
|
|
5530
|
-
var
|
|
6662
|
+
var import_types42 = require("@sip-protocol/types");
|
|
5531
6663
|
|
|
5532
6664
|
// src/payment/payment.ts
|
|
5533
|
-
var
|
|
6665
|
+
var import_types15 = require("@sip-protocol/types");
|
|
5534
6666
|
var import_sha2569 = require("@noble/hashes/sha256");
|
|
5535
|
-
var
|
|
6667
|
+
var import_utils12 = require("@noble/hashes/utils");
|
|
5536
6668
|
var import_chacha2 = require("@noble/ciphers/chacha.js");
|
|
5537
6669
|
var import_hkdf2 = require("@noble/hashes/hkdf");
|
|
5538
6670
|
|
|
@@ -5717,7 +6849,7 @@ var PaymentBuilder = class {
|
|
|
5717
6849
|
_amount;
|
|
5718
6850
|
_recipientMetaAddress;
|
|
5719
6851
|
_recipientAddress;
|
|
5720
|
-
_privacy =
|
|
6852
|
+
_privacy = import_types15.PrivacyLevel.SHIELDED;
|
|
5721
6853
|
_viewingKey;
|
|
5722
6854
|
_sourceChain;
|
|
5723
6855
|
_destinationChain;
|
|
@@ -6000,7 +7132,7 @@ async function createShieldedPayment(params, options) {
|
|
|
6000
7132
|
} else {
|
|
6001
7133
|
resolvedToken = token;
|
|
6002
7134
|
}
|
|
6003
|
-
if (privacy !==
|
|
7135
|
+
if (privacy !== import_types15.PrivacyLevel.TRANSPARENT && !recipientMetaAddress) {
|
|
6004
7136
|
throw new ValidationError(
|
|
6005
7137
|
"recipientMetaAddress is required for shielded/compliant privacy modes",
|
|
6006
7138
|
"recipientMetaAddress",
|
|
@@ -6008,7 +7140,7 @@ async function createShieldedPayment(params, options) {
|
|
|
6008
7140
|
"SIP_2008" /* MISSING_REQUIRED */
|
|
6009
7141
|
);
|
|
6010
7142
|
}
|
|
6011
|
-
if (privacy ===
|
|
7143
|
+
if (privacy === import_types15.PrivacyLevel.TRANSPARENT && !recipientAddress) {
|
|
6012
7144
|
throw new ValidationError(
|
|
6013
7145
|
"recipientAddress is required for transparent mode",
|
|
6014
7146
|
"recipientAddress",
|
|
@@ -6016,7 +7148,7 @@ async function createShieldedPayment(params, options) {
|
|
|
6016
7148
|
"SIP_2008" /* MISSING_REQUIRED */
|
|
6017
7149
|
);
|
|
6018
7150
|
}
|
|
6019
|
-
if (privacy ===
|
|
7151
|
+
if (privacy === import_types15.PrivacyLevel.COMPLIANT && !viewingKey) {
|
|
6020
7152
|
throw new ValidationError(
|
|
6021
7153
|
"viewingKey is required for compliant mode",
|
|
6022
7154
|
"viewingKey",
|
|
@@ -6028,8 +7160,8 @@ async function createShieldedPayment(params, options) {
|
|
|
6028
7160
|
let viewingKeyHash;
|
|
6029
7161
|
if (viewingKey) {
|
|
6030
7162
|
const keyHex = viewingKey.startsWith("0x") ? viewingKey.slice(2) : viewingKey;
|
|
6031
|
-
const keyBytes = (0,
|
|
6032
|
-
viewingKeyHash = `0x${(0,
|
|
7163
|
+
const keyBytes = (0, import_utils12.hexToBytes)(keyHex);
|
|
7164
|
+
viewingKeyHash = `0x${(0, import_utils12.bytesToHex)((0, import_sha2569.sha256)(keyBytes))}`;
|
|
6033
7165
|
}
|
|
6034
7166
|
const privacyConfig = getPrivacyConfig(
|
|
6035
7167
|
privacy,
|
|
@@ -6038,7 +7170,7 @@ async function createShieldedPayment(params, options) {
|
|
|
6038
7170
|
const now = Math.floor(Date.now() / 1e3);
|
|
6039
7171
|
const payment = {
|
|
6040
7172
|
paymentId,
|
|
6041
|
-
version:
|
|
7173
|
+
version: import_types15.SIP_VERSION,
|
|
6042
7174
|
privacyLevel: privacy,
|
|
6043
7175
|
createdAt: now,
|
|
6044
7176
|
expiry: now + ttl,
|
|
@@ -6049,7 +7181,7 @@ async function createShieldedPayment(params, options) {
|
|
|
6049
7181
|
purpose,
|
|
6050
7182
|
viewingKeyHash
|
|
6051
7183
|
};
|
|
6052
|
-
if (privacy !==
|
|
7184
|
+
if (privacy !== import_types15.PrivacyLevel.TRANSPARENT && recipientMetaAddress) {
|
|
6053
7185
|
const metaAddress = decodeStealthMetaAddress(recipientMetaAddress);
|
|
6054
7186
|
const { stealthAddress } = generateStealthAddress(metaAddress);
|
|
6055
7187
|
payment.recipientStealth = stealthAddress;
|
|
@@ -6066,10 +7198,10 @@ async function createShieldedPayment(params, options) {
|
|
|
6066
7198
|
payment.recipientAddress = recipientAddress;
|
|
6067
7199
|
payment.memo = memo;
|
|
6068
7200
|
}
|
|
6069
|
-
if (privacy !==
|
|
7201
|
+
if (privacy !== import_types15.PrivacyLevel.TRANSPARENT && proofProvider?.isReady) {
|
|
6070
7202
|
const hexToUint8 = (hex) => {
|
|
6071
7203
|
const cleanHex = hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
6072
|
-
return (0,
|
|
7204
|
+
return (0, import_utils12.hexToBytes)(cleanHex);
|
|
6073
7205
|
};
|
|
6074
7206
|
const fundingResult = await proofProvider.generateFundingProof({
|
|
6075
7207
|
balance: amount,
|
|
@@ -6096,17 +7228,17 @@ async function createShieldedPayment(params, options) {
|
|
|
6096
7228
|
}
|
|
6097
7229
|
function encryptMemo(memo, viewingKey) {
|
|
6098
7230
|
const keyHex = viewingKey.startsWith("0x") ? viewingKey.slice(2) : viewingKey;
|
|
6099
|
-
const keyBytes = (0,
|
|
7231
|
+
const keyBytes = (0, import_utils12.hexToBytes)(keyHex);
|
|
6100
7232
|
const encKey = (0, import_hkdf2.hkdf)(import_sha2569.sha256, keyBytes, new Uint8Array(0), new Uint8Array(0), 32);
|
|
6101
7233
|
try {
|
|
6102
|
-
const nonce = (0,
|
|
7234
|
+
const nonce = (0, import_utils12.randomBytes)(24);
|
|
6103
7235
|
const cipher = (0, import_chacha2.xchacha20poly1305)(encKey, nonce);
|
|
6104
7236
|
const plaintext = new TextEncoder().encode(memo);
|
|
6105
7237
|
const ciphertext = cipher.encrypt(plaintext);
|
|
6106
7238
|
const result = new Uint8Array(nonce.length + ciphertext.length);
|
|
6107
7239
|
result.set(nonce);
|
|
6108
7240
|
result.set(ciphertext, nonce.length);
|
|
6109
|
-
return `0x${(0,
|
|
7241
|
+
return `0x${(0, import_utils12.bytesToHex)(result)}`;
|
|
6110
7242
|
} finally {
|
|
6111
7243
|
secureWipe(keyBytes);
|
|
6112
7244
|
secureWipe(encKey);
|
|
@@ -6114,11 +7246,11 @@ function encryptMemo(memo, viewingKey) {
|
|
|
6114
7246
|
}
|
|
6115
7247
|
function decryptMemo(encryptedMemo, viewingKey) {
|
|
6116
7248
|
const keyHex = viewingKey.startsWith("0x") ? viewingKey.slice(2) : viewingKey;
|
|
6117
|
-
const keyBytes = (0,
|
|
7249
|
+
const keyBytes = (0, import_utils12.hexToBytes)(keyHex);
|
|
6118
7250
|
const encKey = (0, import_hkdf2.hkdf)(import_sha2569.sha256, keyBytes, new Uint8Array(0), new Uint8Array(0), 32);
|
|
6119
7251
|
try {
|
|
6120
7252
|
const dataHex = encryptedMemo.startsWith("0x") ? encryptedMemo.slice(2) : encryptedMemo;
|
|
6121
|
-
const data = (0,
|
|
7253
|
+
const data = (0, import_utils12.hexToBytes)(dataHex);
|
|
6122
7254
|
const nonce = data.slice(0, 24);
|
|
6123
7255
|
const ciphertext = data.slice(24);
|
|
6124
7256
|
const cipher = (0, import_chacha2.xchacha20poly1305)(encKey, nonce);
|
|
@@ -6132,7 +7264,7 @@ function decryptMemo(encryptedMemo, viewingKey) {
|
|
|
6132
7264
|
function trackPayment(payment) {
|
|
6133
7265
|
return {
|
|
6134
7266
|
...payment,
|
|
6135
|
-
status:
|
|
7267
|
+
status: import_types15.PaymentStatus.DRAFT
|
|
6136
7268
|
};
|
|
6137
7269
|
}
|
|
6138
7270
|
function isPaymentExpired(payment) {
|
|
@@ -6165,10 +7297,10 @@ function getPaymentSummary(payment) {
|
|
|
6165
7297
|
}
|
|
6166
7298
|
|
|
6167
7299
|
// src/treasury/treasury.ts
|
|
6168
|
-
var
|
|
7300
|
+
var import_types16 = require("@sip-protocol/types");
|
|
6169
7301
|
var import_secp256k13 = require("@noble/curves/secp256k1");
|
|
6170
7302
|
var import_sha25610 = require("@noble/hashes/sha256");
|
|
6171
|
-
var
|
|
7303
|
+
var import_utils13 = require("@noble/hashes/utils");
|
|
6172
7304
|
var DEFAULT_PROPOSAL_TTL = 7 * 24 * 60 * 60;
|
|
6173
7305
|
var Treasury = class _Treasury {
|
|
6174
7306
|
config;
|
|
@@ -6198,7 +7330,7 @@ var Treasury = class _Treasury {
|
|
|
6198
7330
|
...m,
|
|
6199
7331
|
addedAt: now
|
|
6200
7332
|
})),
|
|
6201
|
-
defaultPrivacy: params.defaultPrivacy ??
|
|
7333
|
+
defaultPrivacy: params.defaultPrivacy ?? import_types16.PrivacyLevel.SHIELDED,
|
|
6202
7334
|
masterViewingKey,
|
|
6203
7335
|
dailyLimit: params.dailyLimit,
|
|
6204
7336
|
transactionLimit: params.transactionLimit,
|
|
@@ -6277,7 +7409,7 @@ var Treasury = class _Treasury {
|
|
|
6277
7409
|
proposalId,
|
|
6278
7410
|
treasuryId: this.config.treasuryId,
|
|
6279
7411
|
type: "payment",
|
|
6280
|
-
status:
|
|
7412
|
+
status: import_types16.ProposalStatus.PENDING,
|
|
6281
7413
|
proposer: "",
|
|
6282
7414
|
// Should be set by caller
|
|
6283
7415
|
title: params.title,
|
|
@@ -6310,7 +7442,7 @@ var Treasury = class _Treasury {
|
|
|
6310
7442
|
proposalId,
|
|
6311
7443
|
treasuryId: this.config.treasuryId,
|
|
6312
7444
|
type: "batch_payment",
|
|
6313
|
-
status:
|
|
7445
|
+
status: import_types16.ProposalStatus.PENDING,
|
|
6314
7446
|
proposer: "",
|
|
6315
7447
|
title: params.title,
|
|
6316
7448
|
description: params.description,
|
|
@@ -6344,7 +7476,7 @@ var Treasury = class _Treasury {
|
|
|
6344
7476
|
* Get pending proposals
|
|
6345
7477
|
*/
|
|
6346
7478
|
getPendingProposals() {
|
|
6347
|
-
return this.getAllProposals().filter((p) => p.status ===
|
|
7479
|
+
return this.getAllProposals().filter((p) => p.status === import_types16.ProposalStatus.PENDING);
|
|
6348
7480
|
}
|
|
6349
7481
|
/**
|
|
6350
7482
|
* Sign a proposal
|
|
@@ -6375,7 +7507,7 @@ var Treasury = class _Treasury {
|
|
|
6375
7507
|
"SIP_2001" /* INVALID_INPUT */
|
|
6376
7508
|
);
|
|
6377
7509
|
}
|
|
6378
|
-
if (proposal.status !==
|
|
7510
|
+
if (proposal.status !== import_types16.ProposalStatus.PENDING) {
|
|
6379
7511
|
throw new ValidationError(
|
|
6380
7512
|
`proposal is not pending: ${proposal.status}`,
|
|
6381
7513
|
"proposalId",
|
|
@@ -6385,7 +7517,7 @@ var Treasury = class _Treasury {
|
|
|
6385
7517
|
}
|
|
6386
7518
|
const now = Math.floor(Date.now() / 1e3);
|
|
6387
7519
|
if (now > proposal.expiresAt) {
|
|
6388
|
-
proposal.status =
|
|
7520
|
+
proposal.status = import_types16.ProposalStatus.EXPIRED;
|
|
6389
7521
|
throw new ValidationError(
|
|
6390
7522
|
"proposal has expired",
|
|
6391
7523
|
"proposalId",
|
|
@@ -6417,9 +7549,9 @@ var Treasury = class _Treasury {
|
|
|
6417
7549
|
const approvals = proposal.signatures.filter((s) => s.approved).length;
|
|
6418
7550
|
const rejections = proposal.signatures.filter((s) => !s.approved).length;
|
|
6419
7551
|
if (approvals >= proposal.requiredSignatures) {
|
|
6420
|
-
proposal.status =
|
|
7552
|
+
proposal.status = import_types16.ProposalStatus.APPROVED;
|
|
6421
7553
|
} else if (rejections > this.config.totalSigners - proposal.requiredSignatures) {
|
|
6422
|
-
proposal.status =
|
|
7554
|
+
proposal.status = import_types16.ProposalStatus.REJECTED;
|
|
6423
7555
|
}
|
|
6424
7556
|
return proposal;
|
|
6425
7557
|
}
|
|
@@ -6436,7 +7568,7 @@ var Treasury = class _Treasury {
|
|
|
6436
7568
|
"SIP_2001" /* INVALID_INPUT */
|
|
6437
7569
|
);
|
|
6438
7570
|
}
|
|
6439
|
-
if (proposal.status !==
|
|
7571
|
+
if (proposal.status !== import_types16.ProposalStatus.APPROVED) {
|
|
6440
7572
|
throw new ValidationError(
|
|
6441
7573
|
`proposal is not approved: ${proposal.status}`,
|
|
6442
7574
|
"proposalId",
|
|
@@ -6449,8 +7581,8 @@ var Treasury = class _Treasury {
|
|
|
6449
7581
|
const payment = await createShieldedPayment({
|
|
6450
7582
|
token: proposal.payment.token,
|
|
6451
7583
|
amount: proposal.payment.amount,
|
|
6452
|
-
recipientMetaAddress: proposal.payment.privacy !==
|
|
6453
|
-
recipientAddress: proposal.payment.privacy ===
|
|
7584
|
+
recipientMetaAddress: proposal.payment.privacy !== import_types16.PrivacyLevel.TRANSPARENT ? proposal.payment.recipient : void 0,
|
|
7585
|
+
recipientAddress: proposal.payment.privacy === import_types16.PrivacyLevel.TRANSPARENT ? proposal.payment.recipient : void 0,
|
|
6454
7586
|
privacy: proposal.payment.privacy,
|
|
6455
7587
|
viewingKey: this.config.masterViewingKey?.key,
|
|
6456
7588
|
sourceChain: this.config.chain,
|
|
@@ -6463,8 +7595,8 @@ var Treasury = class _Treasury {
|
|
|
6463
7595
|
const payment = await createShieldedPayment({
|
|
6464
7596
|
token: proposal.batchPayment.token,
|
|
6465
7597
|
amount: recipient.amount,
|
|
6466
|
-
recipientMetaAddress: proposal.batchPayment.privacy !==
|
|
6467
|
-
recipientAddress: proposal.batchPayment.privacy ===
|
|
7598
|
+
recipientMetaAddress: proposal.batchPayment.privacy !== import_types16.PrivacyLevel.TRANSPARENT ? recipient.address : void 0,
|
|
7599
|
+
recipientAddress: proposal.batchPayment.privacy === import_types16.PrivacyLevel.TRANSPARENT ? recipient.address : void 0,
|
|
6468
7600
|
privacy: proposal.batchPayment.privacy,
|
|
6469
7601
|
viewingKey: this.config.masterViewingKey?.key,
|
|
6470
7602
|
sourceChain: this.config.chain,
|
|
@@ -6474,7 +7606,7 @@ var Treasury = class _Treasury {
|
|
|
6474
7606
|
payments.push(payment);
|
|
6475
7607
|
}
|
|
6476
7608
|
}
|
|
6477
|
-
proposal.status =
|
|
7609
|
+
proposal.status = import_types16.ProposalStatus.EXECUTED;
|
|
6478
7610
|
proposal.executedAt = Math.floor(Date.now() / 1e3);
|
|
6479
7611
|
proposal.resultPayments = payments;
|
|
6480
7612
|
return payments;
|
|
@@ -6503,7 +7635,7 @@ var Treasury = class _Treasury {
|
|
|
6503
7635
|
"SIP_2001" /* INVALID_INPUT */
|
|
6504
7636
|
);
|
|
6505
7637
|
}
|
|
6506
|
-
if (proposal.status !==
|
|
7638
|
+
if (proposal.status !== import_types16.ProposalStatus.PENDING) {
|
|
6507
7639
|
throw new ValidationError(
|
|
6508
7640
|
`proposal is not pending: ${proposal.status}`,
|
|
6509
7641
|
"proposalId",
|
|
@@ -6511,7 +7643,7 @@ var Treasury = class _Treasury {
|
|
|
6511
7643
|
"SIP_2001" /* INVALID_INPUT */
|
|
6512
7644
|
);
|
|
6513
7645
|
}
|
|
6514
|
-
proposal.status =
|
|
7646
|
+
proposal.status = import_types16.ProposalStatus.CANCELLED;
|
|
6515
7647
|
return proposal;
|
|
6516
7648
|
}
|
|
6517
7649
|
// ─── Auditor Access ──────────────────────────────────────────────────────────
|
|
@@ -6608,7 +7740,7 @@ var Treasury = class _Treasury {
|
|
|
6608
7740
|
getCommittedAmount(token) {
|
|
6609
7741
|
let committed = 0n;
|
|
6610
7742
|
for (const proposal of this.proposals.values()) {
|
|
6611
|
-
if (proposal.status !==
|
|
7743
|
+
if (proposal.status !== import_types16.ProposalStatus.PENDING) continue;
|
|
6612
7744
|
if (proposal.type === "payment" && proposal.payment) {
|
|
6613
7745
|
if (proposal.payment.token.symbol === token.symbol && proposal.payment.token.chain === token.chain) {
|
|
6614
7746
|
committed += proposal.payment.amount;
|
|
@@ -6659,12 +7791,12 @@ var Treasury = class _Treasury {
|
|
|
6659
7791
|
}
|
|
6660
7792
|
};
|
|
6661
7793
|
function generateTreasuryId() {
|
|
6662
|
-
const bytes = (0,
|
|
6663
|
-
return `treasury_${(0,
|
|
7794
|
+
const bytes = (0, import_utils13.randomBytes)(16);
|
|
7795
|
+
return `treasury_${(0, import_utils13.bytesToHex)(bytes)}`;
|
|
6664
7796
|
}
|
|
6665
7797
|
function generateProposalId() {
|
|
6666
|
-
const bytes = (0,
|
|
6667
|
-
return `prop_${(0,
|
|
7798
|
+
const bytes = (0, import_utils13.randomBytes)(16);
|
|
7799
|
+
return `prop_${(0, import_utils13.bytesToHex)(bytes)}`;
|
|
6668
7800
|
}
|
|
6669
7801
|
function computeProposalHash(proposal) {
|
|
6670
7802
|
const data = JSON.stringify({
|
|
@@ -6680,7 +7812,7 @@ function computeProposalHash(proposal) {
|
|
|
6680
7812
|
}
|
|
6681
7813
|
function signMessage(messageHash, privateKey) {
|
|
6682
7814
|
const keyHex = privateKey.startsWith("0x") ? privateKey.slice(2) : privateKey;
|
|
6683
|
-
const keyBytes = (0,
|
|
7815
|
+
const keyBytes = (0, import_utils13.hexToBytes)(keyHex);
|
|
6684
7816
|
try {
|
|
6685
7817
|
const signature = import_secp256k13.secp256k1.sign(messageHash, keyBytes);
|
|
6686
7818
|
return `0x${signature.toCompactHex()}`;
|
|
@@ -6692,8 +7824,8 @@ function verifySignature(messageHash, signature, publicKey) {
|
|
|
6692
7824
|
const sigHex = signature.startsWith("0x") ? signature.slice(2) : signature;
|
|
6693
7825
|
const pubKeyHex = publicKey.startsWith("0x") ? publicKey.slice(2) : publicKey;
|
|
6694
7826
|
try {
|
|
6695
|
-
const sigBytes = (0,
|
|
6696
|
-
const pubKeyBytes = (0,
|
|
7827
|
+
const sigBytes = (0, import_utils13.hexToBytes)(sigHex);
|
|
7828
|
+
const pubKeyBytes = (0, import_utils13.hexToBytes)(pubKeyHex);
|
|
6697
7829
|
return import_secp256k13.secp256k1.verify(sigBytes, messageHash, pubKeyBytes);
|
|
6698
7830
|
} catch {
|
|
6699
7831
|
return false;
|
|
@@ -6851,8 +7983,8 @@ function validateBatchProposalParams(params, config) {
|
|
|
6851
7983
|
}
|
|
6852
7984
|
|
|
6853
7985
|
// src/compliance/compliance-manager.ts
|
|
6854
|
-
var
|
|
6855
|
-
var
|
|
7986
|
+
var import_types17 = require("@sip-protocol/types");
|
|
7987
|
+
var import_utils14 = require("@noble/hashes/utils");
|
|
6856
7988
|
var DEFAULTS2 = {
|
|
6857
7989
|
riskThreshold: 70,
|
|
6858
7990
|
highValueThreshold: 10000000000n,
|
|
@@ -7219,7 +8351,7 @@ var ComplianceManager = class _ComplianceManager {
|
|
|
7219
8351
|
title: params.title,
|
|
7220
8352
|
description: params.description,
|
|
7221
8353
|
format: params.format,
|
|
7222
|
-
status:
|
|
8354
|
+
status: import_types17.ReportStatus.GENERATING,
|
|
7223
8355
|
requestedBy,
|
|
7224
8356
|
requestedAt: now,
|
|
7225
8357
|
startDate: params.startDate,
|
|
@@ -7248,10 +8380,10 @@ var ComplianceManager = class _ComplianceManager {
|
|
|
7248
8380
|
} else if (params.format === "csv") {
|
|
7249
8381
|
report.content = this.generateCSV(transactions);
|
|
7250
8382
|
}
|
|
7251
|
-
report.status =
|
|
8383
|
+
report.status = import_types17.ReportStatus.COMPLETED;
|
|
7252
8384
|
report.generatedAt = Math.floor(Date.now() / 1e3);
|
|
7253
8385
|
} catch (error) {
|
|
7254
|
-
report.status =
|
|
8386
|
+
report.status = import_types17.ReportStatus.FAILED;
|
|
7255
8387
|
report.error = error instanceof Error ? error.message : "Unknown error";
|
|
7256
8388
|
}
|
|
7257
8389
|
this.addAuditLog(requestedBy, "report_generated", {
|
|
@@ -7526,7 +8658,7 @@ var ComplianceManager = class _ComplianceManager {
|
|
|
7526
8658
|
}
|
|
7527
8659
|
};
|
|
7528
8660
|
function generateId(prefix) {
|
|
7529
|
-
return `${prefix}_${(0,
|
|
8661
|
+
return `${prefix}_${(0, import_utils14.bytesToHex)((0, import_utils14.randomBytes)(12))}`;
|
|
7530
8662
|
}
|
|
7531
8663
|
function validateRegisterAuditorParams(params) {
|
|
7532
8664
|
if (!params.organization?.trim()) {
|
|
@@ -7614,10 +8746,10 @@ function validateReportParams(params) {
|
|
|
7614
8746
|
}
|
|
7615
8747
|
|
|
7616
8748
|
// src/wallet/errors.ts
|
|
7617
|
-
var
|
|
8749
|
+
var import_types18 = require("@sip-protocol/types");
|
|
7618
8750
|
var WalletError = class extends SIPError {
|
|
7619
8751
|
walletCode;
|
|
7620
|
-
constructor(message, walletCode =
|
|
8752
|
+
constructor(message, walletCode = import_types18.WalletErrorCode.UNKNOWN, options) {
|
|
7621
8753
|
super(message, "SIP_7000" /* WALLET_ERROR */, options);
|
|
7622
8754
|
this.walletCode = walletCode;
|
|
7623
8755
|
this.name = "WalletError";
|
|
@@ -7627,10 +8759,10 @@ var WalletError = class extends SIPError {
|
|
|
7627
8759
|
*/
|
|
7628
8760
|
isConnectionError() {
|
|
7629
8761
|
const codes = [
|
|
7630
|
-
|
|
7631
|
-
|
|
7632
|
-
|
|
7633
|
-
|
|
8762
|
+
import_types18.WalletErrorCode.NOT_INSTALLED,
|
|
8763
|
+
import_types18.WalletErrorCode.CONNECTION_REJECTED,
|
|
8764
|
+
import_types18.WalletErrorCode.CONNECTION_FAILED,
|
|
8765
|
+
import_types18.WalletErrorCode.NOT_CONNECTED
|
|
7634
8766
|
];
|
|
7635
8767
|
return codes.includes(this.walletCode);
|
|
7636
8768
|
}
|
|
@@ -7639,9 +8771,9 @@ var WalletError = class extends SIPError {
|
|
|
7639
8771
|
*/
|
|
7640
8772
|
isSigningError() {
|
|
7641
8773
|
const codes = [
|
|
7642
|
-
|
|
7643
|
-
|
|
7644
|
-
|
|
8774
|
+
import_types18.WalletErrorCode.SIGNING_REJECTED,
|
|
8775
|
+
import_types18.WalletErrorCode.SIGNING_FAILED,
|
|
8776
|
+
import_types18.WalletErrorCode.INVALID_MESSAGE
|
|
7645
8777
|
];
|
|
7646
8778
|
return codes.includes(this.walletCode);
|
|
7647
8779
|
}
|
|
@@ -7650,10 +8782,10 @@ var WalletError = class extends SIPError {
|
|
|
7650
8782
|
*/
|
|
7651
8783
|
isTransactionError() {
|
|
7652
8784
|
const codes = [
|
|
7653
|
-
|
|
7654
|
-
|
|
7655
|
-
|
|
7656
|
-
|
|
8785
|
+
import_types18.WalletErrorCode.INSUFFICIENT_FUNDS,
|
|
8786
|
+
import_types18.WalletErrorCode.TRANSACTION_REJECTED,
|
|
8787
|
+
import_types18.WalletErrorCode.TRANSACTION_FAILED,
|
|
8788
|
+
import_types18.WalletErrorCode.INVALID_TRANSACTION
|
|
7657
8789
|
];
|
|
7658
8790
|
return codes.includes(this.walletCode);
|
|
7659
8791
|
}
|
|
@@ -7662,9 +8794,9 @@ var WalletError = class extends SIPError {
|
|
|
7662
8794
|
*/
|
|
7663
8795
|
isPrivacyError() {
|
|
7664
8796
|
const codes = [
|
|
7665
|
-
|
|
7666
|
-
|
|
7667
|
-
|
|
8797
|
+
import_types18.WalletErrorCode.STEALTH_NOT_SUPPORTED,
|
|
8798
|
+
import_types18.WalletErrorCode.VIEWING_KEY_NOT_SUPPORTED,
|
|
8799
|
+
import_types18.WalletErrorCode.SHIELDED_NOT_SUPPORTED
|
|
7668
8800
|
];
|
|
7669
8801
|
return codes.includes(this.walletCode);
|
|
7670
8802
|
}
|
|
@@ -7673,10 +8805,10 @@ var WalletError = class extends SIPError {
|
|
|
7673
8805
|
*/
|
|
7674
8806
|
isUserRejection() {
|
|
7675
8807
|
const codes = [
|
|
7676
|
-
|
|
7677
|
-
|
|
7678
|
-
|
|
7679
|
-
|
|
8808
|
+
import_types18.WalletErrorCode.CONNECTION_REJECTED,
|
|
8809
|
+
import_types18.WalletErrorCode.SIGNING_REJECTED,
|
|
8810
|
+
import_types18.WalletErrorCode.TRANSACTION_REJECTED,
|
|
8811
|
+
import_types18.WalletErrorCode.CHAIN_SWITCH_REJECTED
|
|
7680
8812
|
];
|
|
7681
8813
|
return codes.includes(this.walletCode);
|
|
7682
8814
|
}
|
|
@@ -7684,15 +8816,15 @@ var WalletError = class extends SIPError {
|
|
|
7684
8816
|
function notConnectedError() {
|
|
7685
8817
|
return new WalletError(
|
|
7686
8818
|
"Wallet not connected. Call connect() first.",
|
|
7687
|
-
|
|
8819
|
+
import_types18.WalletErrorCode.NOT_CONNECTED
|
|
7688
8820
|
);
|
|
7689
8821
|
}
|
|
7690
|
-
function featureNotSupportedError(feature, code =
|
|
8822
|
+
function featureNotSupportedError(feature, code = import_types18.WalletErrorCode.UNKNOWN) {
|
|
7691
8823
|
return new WalletError(`${feature} is not supported by this wallet`, code);
|
|
7692
8824
|
}
|
|
7693
8825
|
|
|
7694
8826
|
// src/wallet/base-adapter.ts
|
|
7695
|
-
var
|
|
8827
|
+
var import_types19 = require("@sip-protocol/types");
|
|
7696
8828
|
var BaseWalletAdapter = class {
|
|
7697
8829
|
_address = "";
|
|
7698
8830
|
_publicKey = "";
|
|
@@ -7855,12 +8987,12 @@ var MockWalletAdapter = class extends BaseWalletAdapter {
|
|
|
7855
8987
|
this._connectionState = "connecting";
|
|
7856
8988
|
if (this.shouldFailConnect) {
|
|
7857
8989
|
this.setError(
|
|
7858
|
-
|
|
8990
|
+
import_types19.WalletErrorCode.CONNECTION_FAILED,
|
|
7859
8991
|
"Mock connection failure"
|
|
7860
8992
|
);
|
|
7861
8993
|
throw new WalletError(
|
|
7862
8994
|
"Mock connection failure",
|
|
7863
|
-
|
|
8995
|
+
import_types19.WalletErrorCode.CONNECTION_FAILED
|
|
7864
8996
|
);
|
|
7865
8997
|
}
|
|
7866
8998
|
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
@@ -7872,7 +9004,7 @@ var MockWalletAdapter = class extends BaseWalletAdapter {
|
|
|
7872
9004
|
async signMessage(message) {
|
|
7873
9005
|
this.requireConnected();
|
|
7874
9006
|
if (this.shouldFailSign) {
|
|
7875
|
-
throw new WalletError("Mock signing failure",
|
|
9007
|
+
throw new WalletError("Mock signing failure", import_types19.WalletErrorCode.SIGNING_FAILED);
|
|
7876
9008
|
}
|
|
7877
9009
|
const mockSig = new Uint8Array(64);
|
|
7878
9010
|
for (let i = 0; i < 64; i++) {
|
|
@@ -7887,7 +9019,7 @@ var MockWalletAdapter = class extends BaseWalletAdapter {
|
|
|
7887
9019
|
async signTransaction(tx) {
|
|
7888
9020
|
this.requireConnected();
|
|
7889
9021
|
if (this.shouldFailSign) {
|
|
7890
|
-
throw new WalletError("Mock signing failure",
|
|
9022
|
+
throw new WalletError("Mock signing failure", import_types19.WalletErrorCode.SIGNING_FAILED);
|
|
7891
9023
|
}
|
|
7892
9024
|
const signature = await this.signMessage(
|
|
7893
9025
|
new TextEncoder().encode(JSON.stringify(tx.data))
|
|
@@ -8069,7 +9201,7 @@ function isPrivateWalletAdapter(adapter) {
|
|
|
8069
9201
|
}
|
|
8070
9202
|
|
|
8071
9203
|
// src/wallet/solana/adapter.ts
|
|
8072
|
-
var
|
|
9204
|
+
var import_types20 = require("@sip-protocol/types");
|
|
8073
9205
|
|
|
8074
9206
|
// src/wallet/solana/types.ts
|
|
8075
9207
|
function getSolanaProvider(wallet = "phantom") {
|
|
@@ -8190,19 +9322,19 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
|
|
|
8190
9322
|
}
|
|
8191
9323
|
if (!this.provider) {
|
|
8192
9324
|
this.setError(
|
|
8193
|
-
|
|
9325
|
+
import_types20.WalletErrorCode.NOT_INSTALLED,
|
|
8194
9326
|
`${this.walletName} wallet is not installed`
|
|
8195
9327
|
);
|
|
8196
9328
|
throw new WalletError(
|
|
8197
9329
|
`${this.walletName} wallet is not installed`,
|
|
8198
|
-
|
|
9330
|
+
import_types20.WalletErrorCode.NOT_INSTALLED
|
|
8199
9331
|
);
|
|
8200
9332
|
}
|
|
8201
9333
|
const { publicKey } = await this.provider.connect();
|
|
8202
9334
|
if (!publicKey) {
|
|
8203
9335
|
throw new WalletError(
|
|
8204
9336
|
"No public key returned from wallet",
|
|
8205
|
-
|
|
9337
|
+
import_types20.WalletErrorCode.CONNECTION_FAILED
|
|
8206
9338
|
);
|
|
8207
9339
|
}
|
|
8208
9340
|
this.setupEventHandlers();
|
|
@@ -8212,11 +9344,11 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
|
|
|
8212
9344
|
} catch (error) {
|
|
8213
9345
|
const message = error instanceof Error ? error.message : "Connection failed";
|
|
8214
9346
|
if (message.includes("User rejected") || message.includes("rejected")) {
|
|
8215
|
-
this.setError(
|
|
8216
|
-
throw new WalletError(message,
|
|
9347
|
+
this.setError(import_types20.WalletErrorCode.CONNECTION_REJECTED, message);
|
|
9348
|
+
throw new WalletError(message, import_types20.WalletErrorCode.CONNECTION_REJECTED);
|
|
8217
9349
|
}
|
|
8218
|
-
this.setError(
|
|
8219
|
-
throw error instanceof WalletError ? error : new WalletError(message,
|
|
9350
|
+
this.setError(import_types20.WalletErrorCode.CONNECTION_FAILED, message);
|
|
9351
|
+
throw error instanceof WalletError ? error : new WalletError(message, import_types20.WalletErrorCode.CONNECTION_FAILED, { cause: error });
|
|
8220
9352
|
}
|
|
8221
9353
|
}
|
|
8222
9354
|
/**
|
|
@@ -8239,7 +9371,7 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
|
|
|
8239
9371
|
async signMessage(message) {
|
|
8240
9372
|
this.requireConnected();
|
|
8241
9373
|
if (!this.provider) {
|
|
8242
|
-
throw new WalletError("Provider not available",
|
|
9374
|
+
throw new WalletError("Provider not available", import_types20.WalletErrorCode.NOT_CONNECTED);
|
|
8243
9375
|
}
|
|
8244
9376
|
try {
|
|
8245
9377
|
const { signature } = await this.provider.signMessage(message);
|
|
@@ -8250,9 +9382,9 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
|
|
|
8250
9382
|
} catch (error) {
|
|
8251
9383
|
const message2 = error instanceof Error ? error.message : "Signing failed";
|
|
8252
9384
|
if (message2.includes("User rejected") || message2.includes("rejected")) {
|
|
8253
|
-
throw new WalletError(message2,
|
|
9385
|
+
throw new WalletError(message2, import_types20.WalletErrorCode.SIGNING_REJECTED);
|
|
8254
9386
|
}
|
|
8255
|
-
throw new WalletError(message2,
|
|
9387
|
+
throw new WalletError(message2, import_types20.WalletErrorCode.SIGNING_FAILED, {
|
|
8256
9388
|
cause: error
|
|
8257
9389
|
});
|
|
8258
9390
|
}
|
|
@@ -8265,7 +9397,7 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
|
|
|
8265
9397
|
async signTransaction(tx) {
|
|
8266
9398
|
this.requireConnected();
|
|
8267
9399
|
if (!this.provider) {
|
|
8268
|
-
throw new WalletError("Provider not available",
|
|
9400
|
+
throw new WalletError("Provider not available", import_types20.WalletErrorCode.NOT_CONNECTED);
|
|
8269
9401
|
}
|
|
8270
9402
|
try {
|
|
8271
9403
|
const solTx = tx.data;
|
|
@@ -8284,9 +9416,9 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
|
|
|
8284
9416
|
} catch (error) {
|
|
8285
9417
|
const message = error instanceof Error ? error.message : "Signing failed";
|
|
8286
9418
|
if (message.includes("User rejected") || message.includes("rejected")) {
|
|
8287
|
-
throw new WalletError(message,
|
|
9419
|
+
throw new WalletError(message, import_types20.WalletErrorCode.SIGNING_REJECTED);
|
|
8288
9420
|
}
|
|
8289
|
-
throw new WalletError(message,
|
|
9421
|
+
throw new WalletError(message, import_types20.WalletErrorCode.SIGNING_FAILED, {
|
|
8290
9422
|
cause: error
|
|
8291
9423
|
});
|
|
8292
9424
|
}
|
|
@@ -8297,7 +9429,7 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
|
|
|
8297
9429
|
async signAndSendTransaction(tx) {
|
|
8298
9430
|
this.requireConnected();
|
|
8299
9431
|
if (!this.provider) {
|
|
8300
|
-
throw new WalletError("Provider not available",
|
|
9432
|
+
throw new WalletError("Provider not available", import_types20.WalletErrorCode.NOT_CONNECTED);
|
|
8301
9433
|
}
|
|
8302
9434
|
try {
|
|
8303
9435
|
const solTx = tx.data;
|
|
@@ -8312,12 +9444,12 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
|
|
|
8312
9444
|
} catch (error) {
|
|
8313
9445
|
const message = error instanceof Error ? error.message : "Transaction failed";
|
|
8314
9446
|
if (message.includes("User rejected") || message.includes("rejected")) {
|
|
8315
|
-
throw new WalletError(message,
|
|
9447
|
+
throw new WalletError(message, import_types20.WalletErrorCode.TRANSACTION_REJECTED);
|
|
8316
9448
|
}
|
|
8317
9449
|
if (message.includes("insufficient") || message.includes("Insufficient")) {
|
|
8318
|
-
throw new WalletError(message,
|
|
9450
|
+
throw new WalletError(message, import_types20.WalletErrorCode.INSUFFICIENT_FUNDS);
|
|
8319
9451
|
}
|
|
8320
|
-
throw new WalletError(message,
|
|
9452
|
+
throw new WalletError(message, import_types20.WalletErrorCode.TRANSACTION_FAILED, {
|
|
8321
9453
|
cause: error
|
|
8322
9454
|
});
|
|
8323
9455
|
}
|
|
@@ -8330,16 +9462,16 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
|
|
|
8330
9462
|
async signAllTransactions(transactions) {
|
|
8331
9463
|
this.requireConnected();
|
|
8332
9464
|
if (!this.provider) {
|
|
8333
|
-
throw new WalletError("Provider not available",
|
|
9465
|
+
throw new WalletError("Provider not available", import_types20.WalletErrorCode.NOT_CONNECTED);
|
|
8334
9466
|
}
|
|
8335
9467
|
try {
|
|
8336
9468
|
return await this.provider.signAllTransactions(transactions);
|
|
8337
9469
|
} catch (error) {
|
|
8338
9470
|
const message = error instanceof Error ? error.message : "Signing failed";
|
|
8339
9471
|
if (message.includes("User rejected") || message.includes("rejected")) {
|
|
8340
|
-
throw new WalletError(message,
|
|
9472
|
+
throw new WalletError(message, import_types20.WalletErrorCode.SIGNING_REJECTED);
|
|
8341
9473
|
}
|
|
8342
|
-
throw new WalletError(message,
|
|
9474
|
+
throw new WalletError(message, import_types20.WalletErrorCode.SIGNING_FAILED, {
|
|
8343
9475
|
cause: error
|
|
8344
9476
|
});
|
|
8345
9477
|
}
|
|
@@ -8360,7 +9492,7 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
|
|
|
8360
9492
|
} catch (error) {
|
|
8361
9493
|
throw new WalletError(
|
|
8362
9494
|
"Failed to get balance",
|
|
8363
|
-
|
|
9495
|
+
import_types20.WalletErrorCode.UNKNOWN,
|
|
8364
9496
|
{ cause: error }
|
|
8365
9497
|
);
|
|
8366
9498
|
}
|
|
@@ -8373,7 +9505,7 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
|
|
|
8373
9505
|
if (asset.chain !== "solana") {
|
|
8374
9506
|
throw new WalletError(
|
|
8375
9507
|
`Asset chain ${asset.chain} not supported by Solana adapter`,
|
|
8376
|
-
|
|
9508
|
+
import_types20.WalletErrorCode.UNSUPPORTED_CHAIN
|
|
8377
9509
|
);
|
|
8378
9510
|
}
|
|
8379
9511
|
if (!asset.address) {
|
|
@@ -8491,7 +9623,7 @@ function createSolanaAdapter(config = {}) {
|
|
|
8491
9623
|
}
|
|
8492
9624
|
|
|
8493
9625
|
// src/wallet/solana/mock.ts
|
|
8494
|
-
var
|
|
9626
|
+
var import_types22 = require("@sip-protocol/types");
|
|
8495
9627
|
var MockPublicKey = class {
|
|
8496
9628
|
base58;
|
|
8497
9629
|
bytes;
|
|
@@ -8557,8 +9689,8 @@ var MockSolanaAdapter = class extends BaseWalletAdapter {
|
|
|
8557
9689
|
this._connectionState = "connecting";
|
|
8558
9690
|
await this.simulateLatency();
|
|
8559
9691
|
if (this.shouldFailConnect) {
|
|
8560
|
-
this.setError(
|
|
8561
|
-
throw new WalletError("Mock connection failure",
|
|
9692
|
+
this.setError(import_types22.WalletErrorCode.CONNECTION_FAILED, "Mock connection failure");
|
|
9693
|
+
throw new WalletError("Mock connection failure", import_types22.WalletErrorCode.CONNECTION_FAILED);
|
|
8562
9694
|
}
|
|
8563
9695
|
const hexPubKey = "0x" + Buffer.from(this.mockPublicKey.toBytes()).toString("hex");
|
|
8564
9696
|
this.setConnected(this.mockAddress, hexPubKey);
|
|
@@ -8577,7 +9709,7 @@ var MockSolanaAdapter = class extends BaseWalletAdapter {
|
|
|
8577
9709
|
this.requireConnected();
|
|
8578
9710
|
await this.simulateLatency();
|
|
8579
9711
|
if (this.shouldFailSign) {
|
|
8580
|
-
throw new WalletError("Mock signing failure",
|
|
9712
|
+
throw new WalletError("Mock signing failure", import_types22.WalletErrorCode.SIGNING_REJECTED);
|
|
8581
9713
|
}
|
|
8582
9714
|
const mockSig = new Uint8Array(64);
|
|
8583
9715
|
for (let i = 0; i < 64; i++) {
|
|
@@ -8595,7 +9727,7 @@ var MockSolanaAdapter = class extends BaseWalletAdapter {
|
|
|
8595
9727
|
this.requireConnected();
|
|
8596
9728
|
await this.simulateLatency();
|
|
8597
9729
|
if (this.shouldFailSign) {
|
|
8598
|
-
throw new WalletError("Mock signing failure",
|
|
9730
|
+
throw new WalletError("Mock signing failure", import_types22.WalletErrorCode.SIGNING_REJECTED);
|
|
8599
9731
|
}
|
|
8600
9732
|
const solTx = tx.data;
|
|
8601
9733
|
this.signedTransactions.push(solTx);
|
|
@@ -8615,10 +9747,10 @@ var MockSolanaAdapter = class extends BaseWalletAdapter {
|
|
|
8615
9747
|
this.requireConnected();
|
|
8616
9748
|
await this.simulateLatency();
|
|
8617
9749
|
if (this.shouldFailSign) {
|
|
8618
|
-
throw new WalletError("Mock signing failure",
|
|
9750
|
+
throw new WalletError("Mock signing failure", import_types22.WalletErrorCode.SIGNING_REJECTED);
|
|
8619
9751
|
}
|
|
8620
9752
|
if (this.shouldFailTransaction) {
|
|
8621
|
-
throw new WalletError("Mock transaction failure",
|
|
9753
|
+
throw new WalletError("Mock transaction failure", import_types22.WalletErrorCode.TRANSACTION_FAILED);
|
|
8622
9754
|
}
|
|
8623
9755
|
const txSig = `mock_tx_${Date.now()}_${Math.random().toString(36).slice(2)}`;
|
|
8624
9756
|
this.sentTransactions.push(txSig);
|
|
@@ -8638,7 +9770,7 @@ var MockSolanaAdapter = class extends BaseWalletAdapter {
|
|
|
8638
9770
|
this.requireConnected();
|
|
8639
9771
|
await this.simulateLatency();
|
|
8640
9772
|
if (this.shouldFailSign) {
|
|
8641
|
-
throw new WalletError("Mock signing failure",
|
|
9773
|
+
throw new WalletError("Mock signing failure", import_types22.WalletErrorCode.SIGNING_REJECTED);
|
|
8642
9774
|
}
|
|
8643
9775
|
this.signedTransactions.push(...transactions);
|
|
8644
9776
|
return transactions.map((tx) => {
|
|
@@ -8665,7 +9797,7 @@ var MockSolanaAdapter = class extends BaseWalletAdapter {
|
|
|
8665
9797
|
if (asset.chain !== "solana") {
|
|
8666
9798
|
throw new WalletError(
|
|
8667
9799
|
`Asset chain ${asset.chain} not supported by Solana adapter`,
|
|
8668
|
-
|
|
9800
|
+
import_types22.WalletErrorCode.UNSUPPORTED_CHAIN
|
|
8669
9801
|
);
|
|
8670
9802
|
}
|
|
8671
9803
|
if (!asset.address) {
|
|
@@ -8834,7 +9966,7 @@ function createMockSolanaAdapter(config = {}) {
|
|
|
8834
9966
|
}
|
|
8835
9967
|
|
|
8836
9968
|
// src/wallet/ethereum/adapter.ts
|
|
8837
|
-
var
|
|
9969
|
+
var import_types24 = require("@sip-protocol/types");
|
|
8838
9970
|
|
|
8839
9971
|
// src/wallet/ethereum/types.ts
|
|
8840
9972
|
var EthereumChainId = {
|
|
@@ -8976,7 +10108,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
8976
10108
|
this._connectionState = "error";
|
|
8977
10109
|
throw new WalletError(
|
|
8978
10110
|
`${this.walletType} wallet not found. Please install the extension.`,
|
|
8979
|
-
|
|
10111
|
+
import_types24.WalletErrorCode.NOT_INSTALLED
|
|
8980
10112
|
);
|
|
8981
10113
|
}
|
|
8982
10114
|
const accounts = await this.provider.request({
|
|
@@ -8986,7 +10118,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
8986
10118
|
this._connectionState = "error";
|
|
8987
10119
|
throw new WalletError(
|
|
8988
10120
|
"No accounts returned from wallet",
|
|
8989
|
-
|
|
10121
|
+
import_types24.WalletErrorCode.CONNECTION_REJECTED
|
|
8990
10122
|
);
|
|
8991
10123
|
}
|
|
8992
10124
|
const address = normalizeAddress(accounts[0]);
|
|
@@ -9006,12 +10138,12 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9006
10138
|
if (rpcError.code === 4001) {
|
|
9007
10139
|
throw new WalletError(
|
|
9008
10140
|
"User rejected connection request",
|
|
9009
|
-
|
|
10141
|
+
import_types24.WalletErrorCode.CONNECTION_REJECTED
|
|
9010
10142
|
);
|
|
9011
10143
|
}
|
|
9012
10144
|
throw new WalletError(
|
|
9013
10145
|
`Failed to connect: ${rpcError.message || String(error)}`,
|
|
9014
|
-
|
|
10146
|
+
import_types24.WalletErrorCode.CONNECTION_FAILED
|
|
9015
10147
|
);
|
|
9016
10148
|
}
|
|
9017
10149
|
}
|
|
@@ -9031,7 +10163,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9031
10163
|
if (!this.provider) {
|
|
9032
10164
|
throw new WalletError(
|
|
9033
10165
|
"Provider not available",
|
|
9034
|
-
|
|
10166
|
+
import_types24.WalletErrorCode.NOT_CONNECTED
|
|
9035
10167
|
);
|
|
9036
10168
|
}
|
|
9037
10169
|
try {
|
|
@@ -9049,12 +10181,12 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9049
10181
|
if (rpcError.code === 4001) {
|
|
9050
10182
|
throw new WalletError(
|
|
9051
10183
|
"User rejected signing request",
|
|
9052
|
-
|
|
10184
|
+
import_types24.WalletErrorCode.SIGNING_REJECTED
|
|
9053
10185
|
);
|
|
9054
10186
|
}
|
|
9055
10187
|
throw new WalletError(
|
|
9056
10188
|
`Failed to sign message: ${rpcError.message || String(error)}`,
|
|
9057
|
-
|
|
10189
|
+
import_types24.WalletErrorCode.SIGNING_FAILED
|
|
9058
10190
|
);
|
|
9059
10191
|
}
|
|
9060
10192
|
}
|
|
@@ -9066,7 +10198,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9066
10198
|
if (!this.provider) {
|
|
9067
10199
|
throw new WalletError(
|
|
9068
10200
|
"Provider not available",
|
|
9069
|
-
|
|
10201
|
+
import_types24.WalletErrorCode.NOT_CONNECTED
|
|
9070
10202
|
);
|
|
9071
10203
|
}
|
|
9072
10204
|
try {
|
|
@@ -9083,12 +10215,12 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9083
10215
|
if (rpcError.code === 4001) {
|
|
9084
10216
|
throw new WalletError(
|
|
9085
10217
|
"User rejected signing request",
|
|
9086
|
-
|
|
10218
|
+
import_types24.WalletErrorCode.SIGNING_REJECTED
|
|
9087
10219
|
);
|
|
9088
10220
|
}
|
|
9089
10221
|
throw new WalletError(
|
|
9090
10222
|
`Failed to sign typed data: ${rpcError.message || String(error)}`,
|
|
9091
|
-
|
|
10223
|
+
import_types24.WalletErrorCode.SIGNING_FAILED
|
|
9092
10224
|
);
|
|
9093
10225
|
}
|
|
9094
10226
|
}
|
|
@@ -9100,7 +10232,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9100
10232
|
if (!this.provider) {
|
|
9101
10233
|
throw new WalletError(
|
|
9102
10234
|
"Provider not available",
|
|
9103
|
-
|
|
10235
|
+
import_types24.WalletErrorCode.NOT_CONNECTED
|
|
9104
10236
|
);
|
|
9105
10237
|
}
|
|
9106
10238
|
try {
|
|
@@ -9128,7 +10260,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9128
10260
|
if (rpcError.code === 4001) {
|
|
9129
10261
|
throw new WalletError(
|
|
9130
10262
|
"User rejected transaction signing",
|
|
9131
|
-
|
|
10263
|
+
import_types24.WalletErrorCode.SIGNING_REJECTED
|
|
9132
10264
|
);
|
|
9133
10265
|
}
|
|
9134
10266
|
if (rpcError.code === -32601 || rpcError.message?.includes("not supported")) {
|
|
@@ -9146,7 +10278,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9146
10278
|
}
|
|
9147
10279
|
throw new WalletError(
|
|
9148
10280
|
`Failed to sign transaction: ${rpcError.message || String(error)}`,
|
|
9149
|
-
|
|
10281
|
+
import_types24.WalletErrorCode.TRANSACTION_FAILED
|
|
9150
10282
|
);
|
|
9151
10283
|
}
|
|
9152
10284
|
}
|
|
@@ -9158,7 +10290,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9158
10290
|
if (!this.provider) {
|
|
9159
10291
|
throw new WalletError(
|
|
9160
10292
|
"Provider not available",
|
|
9161
|
-
|
|
10293
|
+
import_types24.WalletErrorCode.NOT_CONNECTED
|
|
9162
10294
|
);
|
|
9163
10295
|
}
|
|
9164
10296
|
try {
|
|
@@ -9180,12 +10312,12 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9180
10312
|
if (rpcError.code === 4001) {
|
|
9181
10313
|
throw new WalletError(
|
|
9182
10314
|
"User rejected transaction",
|
|
9183
|
-
|
|
10315
|
+
import_types24.WalletErrorCode.TRANSACTION_REJECTED
|
|
9184
10316
|
);
|
|
9185
10317
|
}
|
|
9186
10318
|
throw new WalletError(
|
|
9187
10319
|
`Failed to send transaction: ${rpcError.message || String(error)}`,
|
|
9188
|
-
|
|
10320
|
+
import_types24.WalletErrorCode.TRANSACTION_FAILED
|
|
9189
10321
|
);
|
|
9190
10322
|
}
|
|
9191
10323
|
}
|
|
@@ -9220,7 +10352,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9220
10352
|
} catch (error) {
|
|
9221
10353
|
throw new WalletError(
|
|
9222
10354
|
`Failed to fetch balance: ${String(error)}`,
|
|
9223
|
-
|
|
10355
|
+
import_types24.WalletErrorCode.UNKNOWN
|
|
9224
10356
|
);
|
|
9225
10357
|
}
|
|
9226
10358
|
}
|
|
@@ -9232,7 +10364,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9232
10364
|
if (asset.chain !== "ethereum") {
|
|
9233
10365
|
throw new WalletError(
|
|
9234
10366
|
`Asset chain ${asset.chain} not supported by Ethereum adapter`,
|
|
9235
|
-
|
|
10367
|
+
import_types24.WalletErrorCode.UNSUPPORTED_CHAIN
|
|
9236
10368
|
);
|
|
9237
10369
|
}
|
|
9238
10370
|
if (!asset.address) {
|
|
@@ -9257,7 +10389,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9257
10389
|
} catch (error) {
|
|
9258
10390
|
throw new WalletError(
|
|
9259
10391
|
`Failed to fetch token balance: ${String(error)}`,
|
|
9260
|
-
|
|
10392
|
+
import_types24.WalletErrorCode.UNKNOWN
|
|
9261
10393
|
);
|
|
9262
10394
|
}
|
|
9263
10395
|
}
|
|
@@ -9269,7 +10401,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9269
10401
|
if (!this.provider) {
|
|
9270
10402
|
throw new WalletError(
|
|
9271
10403
|
"Provider not available",
|
|
9272
|
-
|
|
10404
|
+
import_types24.WalletErrorCode.NOT_CONNECTED
|
|
9273
10405
|
);
|
|
9274
10406
|
}
|
|
9275
10407
|
try {
|
|
@@ -9284,18 +10416,18 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9284
10416
|
if (rpcError.code === 4001) {
|
|
9285
10417
|
throw new WalletError(
|
|
9286
10418
|
"User rejected chain switch",
|
|
9287
|
-
|
|
10419
|
+
import_types24.WalletErrorCode.CHAIN_SWITCH_REJECTED
|
|
9288
10420
|
);
|
|
9289
10421
|
}
|
|
9290
10422
|
if (rpcError.code === 4902) {
|
|
9291
10423
|
throw new WalletError(
|
|
9292
10424
|
`Chain ${chainId} not added to wallet`,
|
|
9293
|
-
|
|
10425
|
+
import_types24.WalletErrorCode.UNSUPPORTED_CHAIN
|
|
9294
10426
|
);
|
|
9295
10427
|
}
|
|
9296
10428
|
throw new WalletError(
|
|
9297
10429
|
`Failed to switch chain: ${rpcError.message || String(error)}`,
|
|
9298
|
-
|
|
10430
|
+
import_types24.WalletErrorCode.CHAIN_SWITCH_FAILED
|
|
9299
10431
|
);
|
|
9300
10432
|
}
|
|
9301
10433
|
}
|
|
@@ -9331,7 +10463,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9331
10463
|
}
|
|
9332
10464
|
throw new WalletError(
|
|
9333
10465
|
`Transaction ${txHash} not confirmed after ${maxAttempts * 5} seconds`,
|
|
9334
|
-
|
|
10466
|
+
import_types24.WalletErrorCode.TRANSACTION_FAILED
|
|
9335
10467
|
);
|
|
9336
10468
|
}
|
|
9337
10469
|
/**
|
|
@@ -9405,7 +10537,7 @@ function createEthereumAdapter(config) {
|
|
|
9405
10537
|
}
|
|
9406
10538
|
|
|
9407
10539
|
// src/wallet/ethereum/mock.ts
|
|
9408
|
-
var
|
|
10540
|
+
var import_types26 = require("@sip-protocol/types");
|
|
9409
10541
|
var MockEthereumAdapter = class extends BaseWalletAdapter {
|
|
9410
10542
|
chain = "ethereum";
|
|
9411
10543
|
name = "mock-ethereum";
|
|
@@ -9446,7 +10578,7 @@ var MockEthereumAdapter = class extends BaseWalletAdapter {
|
|
|
9446
10578
|
this._connectionState = "error";
|
|
9447
10579
|
throw new WalletError(
|
|
9448
10580
|
"Mock connection rejected",
|
|
9449
|
-
|
|
10581
|
+
import_types26.WalletErrorCode.CONNECTION_REJECTED
|
|
9450
10582
|
);
|
|
9451
10583
|
}
|
|
9452
10584
|
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
@@ -9458,7 +10590,7 @@ var MockEthereumAdapter = class extends BaseWalletAdapter {
|
|
|
9458
10590
|
this._connectionState = "error";
|
|
9459
10591
|
throw new WalletError(
|
|
9460
10592
|
`Mock connection failed: ${String(error)}`,
|
|
9461
|
-
|
|
10593
|
+
import_types26.WalletErrorCode.CONNECTION_FAILED
|
|
9462
10594
|
);
|
|
9463
10595
|
}
|
|
9464
10596
|
}
|
|
@@ -9476,7 +10608,7 @@ var MockEthereumAdapter = class extends BaseWalletAdapter {
|
|
|
9476
10608
|
if (this._shouldFailSign) {
|
|
9477
10609
|
throw new WalletError(
|
|
9478
10610
|
"Mock signing rejected",
|
|
9479
|
-
|
|
10611
|
+
import_types26.WalletErrorCode.SIGNING_REJECTED
|
|
9480
10612
|
);
|
|
9481
10613
|
}
|
|
9482
10614
|
const msgHex = Buffer.from(message).toString("hex");
|
|
@@ -9494,7 +10626,7 @@ var MockEthereumAdapter = class extends BaseWalletAdapter {
|
|
|
9494
10626
|
if (this._shouldFailSign) {
|
|
9495
10627
|
throw new WalletError(
|
|
9496
10628
|
"Mock signing rejected",
|
|
9497
|
-
|
|
10629
|
+
import_types26.WalletErrorCode.SIGNING_REJECTED
|
|
9498
10630
|
);
|
|
9499
10631
|
}
|
|
9500
10632
|
const mockSig = `0x${"1".repeat(130)}`;
|
|
@@ -9511,7 +10643,7 @@ var MockEthereumAdapter = class extends BaseWalletAdapter {
|
|
|
9511
10643
|
if (this._shouldFailSign) {
|
|
9512
10644
|
throw new WalletError(
|
|
9513
10645
|
"Mock signing rejected",
|
|
9514
|
-
|
|
10646
|
+
import_types26.WalletErrorCode.SIGNING_REJECTED
|
|
9515
10647
|
);
|
|
9516
10648
|
}
|
|
9517
10649
|
this._signedTransactions.push(tx);
|
|
@@ -9536,7 +10668,7 @@ var MockEthereumAdapter = class extends BaseWalletAdapter {
|
|
|
9536
10668
|
if (this._shouldFailTransaction) {
|
|
9537
10669
|
throw new WalletError(
|
|
9538
10670
|
"Mock transaction failed",
|
|
9539
|
-
|
|
10671
|
+
import_types26.WalletErrorCode.TRANSACTION_FAILED
|
|
9540
10672
|
);
|
|
9541
10673
|
}
|
|
9542
10674
|
this._signedTransactions.push(tx);
|
|
@@ -9566,7 +10698,7 @@ var MockEthereumAdapter = class extends BaseWalletAdapter {
|
|
|
9566
10698
|
if (asset.chain !== "ethereum") {
|
|
9567
10699
|
throw new WalletError(
|
|
9568
10700
|
`Asset chain ${asset.chain} not supported by Ethereum adapter`,
|
|
9569
|
-
|
|
10701
|
+
import_types26.WalletErrorCode.UNSUPPORTED_CHAIN
|
|
9570
10702
|
);
|
|
9571
10703
|
}
|
|
9572
10704
|
if (!asset.address) {
|
|
@@ -9845,7 +10977,7 @@ function getAvailableTransports() {
|
|
|
9845
10977
|
}
|
|
9846
10978
|
|
|
9847
10979
|
// src/wallet/hardware/ledger.ts
|
|
9848
|
-
var
|
|
10980
|
+
var import_types29 = require("@sip-protocol/types");
|
|
9849
10981
|
var LedgerWalletAdapter = class extends BaseWalletAdapter {
|
|
9850
10982
|
chain;
|
|
9851
10983
|
name = "ledger";
|
|
@@ -9998,7 +11130,7 @@ var LedgerWalletAdapter = class extends BaseWalletAdapter {
|
|
|
9998
11130
|
async getBalance() {
|
|
9999
11131
|
throw new WalletError(
|
|
10000
11132
|
"Hardware wallets do not track balances. Use an RPC provider.",
|
|
10001
|
-
|
|
11133
|
+
import_types29.WalletErrorCode.UNSUPPORTED_OPERATION
|
|
10002
11134
|
);
|
|
10003
11135
|
}
|
|
10004
11136
|
/**
|
|
@@ -10009,7 +11141,7 @@ var LedgerWalletAdapter = class extends BaseWalletAdapter {
|
|
|
10009
11141
|
async getTokenBalance(_asset) {
|
|
10010
11142
|
throw new WalletError(
|
|
10011
11143
|
"Hardware wallets do not track balances. Use an RPC provider.",
|
|
10012
|
-
|
|
11144
|
+
import_types29.WalletErrorCode.UNSUPPORTED_OPERATION
|
|
10013
11145
|
);
|
|
10014
11146
|
}
|
|
10015
11147
|
// ─── Account Management ─────────────────────────────────────────────────────
|
|
@@ -10297,7 +11429,7 @@ function createLedgerAdapter(config) {
|
|
|
10297
11429
|
}
|
|
10298
11430
|
|
|
10299
11431
|
// src/wallet/hardware/trezor.ts
|
|
10300
|
-
var
|
|
11432
|
+
var import_types31 = require("@sip-protocol/types");
|
|
10301
11433
|
var TrezorWalletAdapter = class extends BaseWalletAdapter {
|
|
10302
11434
|
chain;
|
|
10303
11435
|
name = "trezor";
|
|
@@ -10443,7 +11575,7 @@ var TrezorWalletAdapter = class extends BaseWalletAdapter {
|
|
|
10443
11575
|
async getBalance() {
|
|
10444
11576
|
throw new WalletError(
|
|
10445
11577
|
"Hardware wallets do not track balances. Use an RPC provider.",
|
|
10446
|
-
|
|
11578
|
+
import_types31.WalletErrorCode.UNSUPPORTED_OPERATION
|
|
10447
11579
|
);
|
|
10448
11580
|
}
|
|
10449
11581
|
/**
|
|
@@ -10454,7 +11586,7 @@ var TrezorWalletAdapter = class extends BaseWalletAdapter {
|
|
|
10454
11586
|
async getTokenBalance(_asset) {
|
|
10455
11587
|
throw new WalletError(
|
|
10456
11588
|
"Hardware wallets do not track balances. Use an RPC provider.",
|
|
10457
|
-
|
|
11589
|
+
import_types31.WalletErrorCode.UNSUPPORTED_OPERATION
|
|
10458
11590
|
);
|
|
10459
11591
|
}
|
|
10460
11592
|
// ─── Account Management ─────────────────────────────────────────────────────
|
|
@@ -10735,8 +11867,8 @@ function createTrezorAdapter(config) {
|
|
|
10735
11867
|
}
|
|
10736
11868
|
|
|
10737
11869
|
// src/wallet/hardware/mock.ts
|
|
10738
|
-
var
|
|
10739
|
-
var
|
|
11870
|
+
var import_types33 = require("@sip-protocol/types");
|
|
11871
|
+
var import_utils15 = require("@noble/hashes/utils");
|
|
10740
11872
|
var MockLedgerAdapter = class extends BaseWalletAdapter {
|
|
10741
11873
|
chain;
|
|
10742
11874
|
name = "mock-ledger";
|
|
@@ -10883,7 +12015,7 @@ var MockLedgerAdapter = class extends BaseWalletAdapter {
|
|
|
10883
12015
|
async getBalance() {
|
|
10884
12016
|
throw new WalletError(
|
|
10885
12017
|
"Hardware wallets do not track balances",
|
|
10886
|
-
|
|
12018
|
+
import_types33.WalletErrorCode.UNSUPPORTED_OPERATION
|
|
10887
12019
|
);
|
|
10888
12020
|
}
|
|
10889
12021
|
/**
|
|
@@ -10892,7 +12024,7 @@ var MockLedgerAdapter = class extends BaseWalletAdapter {
|
|
|
10892
12024
|
async getTokenBalance(_asset) {
|
|
10893
12025
|
throw new WalletError(
|
|
10894
12026
|
"Hardware wallets do not track balances",
|
|
10895
|
-
|
|
12027
|
+
import_types33.WalletErrorCode.UNSUPPORTED_OPERATION
|
|
10896
12028
|
);
|
|
10897
12029
|
}
|
|
10898
12030
|
/**
|
|
@@ -10981,15 +12113,15 @@ var MockLedgerAdapter = class extends BaseWalletAdapter {
|
|
|
10981
12113
|
}
|
|
10982
12114
|
}
|
|
10983
12115
|
generateMockAddress(index) {
|
|
10984
|
-
const bytes = (0,
|
|
12116
|
+
const bytes = (0, import_utils15.randomBytes)(20);
|
|
10985
12117
|
bytes[0] = index;
|
|
10986
|
-
return `0x${(0,
|
|
12118
|
+
return `0x${(0, import_utils15.bytesToHex)(bytes)}`;
|
|
10987
12119
|
}
|
|
10988
12120
|
generateMockPublicKey(index) {
|
|
10989
|
-
const bytes = (0,
|
|
12121
|
+
const bytes = (0, import_utils15.randomBytes)(33);
|
|
10990
12122
|
bytes[0] = 2;
|
|
10991
12123
|
bytes[1] = index;
|
|
10992
|
-
return `0x${(0,
|
|
12124
|
+
return `0x${(0, import_utils15.bytesToHex)(bytes)}`;
|
|
10993
12125
|
}
|
|
10994
12126
|
generateMockSignature(data) {
|
|
10995
12127
|
const sig = new Uint8Array(65);
|
|
@@ -10998,7 +12130,7 @@ var MockLedgerAdapter = class extends BaseWalletAdapter {
|
|
|
10998
12130
|
sig[32 + i] = (data[i % data.length] ?? 0) ^ i * 11;
|
|
10999
12131
|
}
|
|
11000
12132
|
sig[64] = 27;
|
|
11001
|
-
return `0x${(0,
|
|
12133
|
+
return `0x${(0, import_utils15.bytesToHex)(sig)}`;
|
|
11002
12134
|
}
|
|
11003
12135
|
delay(ms) {
|
|
11004
12136
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
@@ -11122,13 +12254,13 @@ var MockTrezorAdapter = class extends BaseWalletAdapter {
|
|
|
11122
12254
|
async getBalance() {
|
|
11123
12255
|
throw new WalletError(
|
|
11124
12256
|
"Hardware wallets do not track balances",
|
|
11125
|
-
|
|
12257
|
+
import_types33.WalletErrorCode.UNSUPPORTED_OPERATION
|
|
11126
12258
|
);
|
|
11127
12259
|
}
|
|
11128
12260
|
async getTokenBalance(_asset) {
|
|
11129
12261
|
throw new WalletError(
|
|
11130
12262
|
"Hardware wallets do not track balances",
|
|
11131
|
-
|
|
12263
|
+
import_types33.WalletErrorCode.UNSUPPORTED_OPERATION
|
|
11132
12264
|
);
|
|
11133
12265
|
}
|
|
11134
12266
|
async getAccounts(startIndex = 0, count = 5) {
|
|
@@ -11187,15 +12319,15 @@ var MockTrezorAdapter = class extends BaseWalletAdapter {
|
|
|
11187
12319
|
}
|
|
11188
12320
|
}
|
|
11189
12321
|
generateMockAddress(index) {
|
|
11190
|
-
const bytes = (0,
|
|
12322
|
+
const bytes = (0, import_utils15.randomBytes)(20);
|
|
11191
12323
|
bytes[0] = index + 100;
|
|
11192
|
-
return `0x${(0,
|
|
12324
|
+
return `0x${(0, import_utils15.bytesToHex)(bytes)}`;
|
|
11193
12325
|
}
|
|
11194
12326
|
generateMockPublicKey(index) {
|
|
11195
|
-
const bytes = (0,
|
|
12327
|
+
const bytes = (0, import_utils15.randomBytes)(33);
|
|
11196
12328
|
bytes[0] = 3;
|
|
11197
12329
|
bytes[1] = index + 100;
|
|
11198
|
-
return `0x${(0,
|
|
12330
|
+
return `0x${(0, import_utils15.bytesToHex)(bytes)}`;
|
|
11199
12331
|
}
|
|
11200
12332
|
generateMockSignature(data) {
|
|
11201
12333
|
const sig = new Uint8Array(65);
|
|
@@ -11204,7 +12336,7 @@ var MockTrezorAdapter = class extends BaseWalletAdapter {
|
|
|
11204
12336
|
sig[32 + i] = (data[i % data.length] ?? 0) ^ i * 17;
|
|
11205
12337
|
}
|
|
11206
12338
|
sig[64] = 28;
|
|
11207
|
-
return `0x${(0,
|
|
12339
|
+
return `0x${(0, import_utils15.bytesToHex)(sig)}`;
|
|
11208
12340
|
}
|
|
11209
12341
|
delay(ms) {
|
|
11210
12342
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
@@ -11218,7 +12350,7 @@ function createMockTrezorAdapter(config) {
|
|
|
11218
12350
|
}
|
|
11219
12351
|
|
|
11220
12352
|
// src/wallet/index.ts
|
|
11221
|
-
var
|
|
12353
|
+
var import_types36 = require("@sip-protocol/types");
|
|
11222
12354
|
|
|
11223
12355
|
// src/proofs/browser.ts
|
|
11224
12356
|
var import_noir_js = require("@noir-lang/noir_js");
|
|
@@ -12989,6 +14121,211 @@ function createWorkerBlobURL() {
|
|
|
12989
14121
|
}
|
|
12990
14122
|
}
|
|
12991
14123
|
|
|
14124
|
+
// Generate validity proof
|
|
14125
|
+
async function generateValidityProof(id, params) {
|
|
14126
|
+
if (!isReady) {
|
|
14127
|
+
sendError(id, new Error('Worker not initialized'));
|
|
14128
|
+
return;
|
|
14129
|
+
}
|
|
14130
|
+
|
|
14131
|
+
try {
|
|
14132
|
+
sendProgress(id, 'witness', 20, 'Preparing validity witness...');
|
|
14133
|
+
|
|
14134
|
+
// Import noble crypto for hashing
|
|
14135
|
+
const { sha256 } = await import('@noble/hashes/sha256');
|
|
14136
|
+
|
|
14137
|
+
// Convert inputs to field elements
|
|
14138
|
+
const intentHashField = hexToField(params.intentHash);
|
|
14139
|
+
const senderAddressField = hexToField(params.senderAddress);
|
|
14140
|
+
const senderBlindingField = bytesToField(params.senderBlinding);
|
|
14141
|
+
const senderSecretField = bytesToField(params.senderSecret);
|
|
14142
|
+
const nonceField = bytesToField(params.nonce);
|
|
14143
|
+
|
|
14144
|
+
// Compute sender commitment
|
|
14145
|
+
const addressBytes = hexToBytes(senderAddressField);
|
|
14146
|
+
const blindingBytes = hexToBytes(senderBlindingField.padStart(64, '0'));
|
|
14147
|
+
const commitmentPreimage = new Uint8Array([...addressBytes, ...blindingBytes]);
|
|
14148
|
+
const commitmentHash = sha256(commitmentPreimage);
|
|
14149
|
+
const commitmentX = bytesToHex(commitmentHash.slice(0, 16)).padStart(64, '0');
|
|
14150
|
+
const commitmentY = bytesToHex(commitmentHash.slice(16, 32)).padStart(64, '0');
|
|
14151
|
+
|
|
14152
|
+
// Compute nullifier
|
|
14153
|
+
const secretBytes = hexToBytes(senderSecretField.padStart(64, '0'));
|
|
14154
|
+
const intentBytes = hexToBytes(intentHashField);
|
|
14155
|
+
const nonceBytes = hexToBytes(nonceField.padStart(64, '0'));
|
|
14156
|
+
const nullifierPreimage = new Uint8Array([...secretBytes, ...intentBytes, ...nonceBytes]);
|
|
14157
|
+
const nullifierHash = sha256(nullifierPreimage);
|
|
14158
|
+
const nullifier = bytesToHex(nullifierHash);
|
|
14159
|
+
|
|
14160
|
+
const signature = Array.from(params.authorizationSignature);
|
|
14161
|
+
const messageHash = fieldToBytes32(intentHashField);
|
|
14162
|
+
|
|
14163
|
+
// Get public key coordinates
|
|
14164
|
+
let pubKeyX, pubKeyY;
|
|
14165
|
+
if (params.senderPublicKey) {
|
|
14166
|
+
pubKeyX = Array.from(params.senderPublicKey.x);
|
|
14167
|
+
pubKeyY = Array.from(params.senderPublicKey.y);
|
|
14168
|
+
} else {
|
|
14169
|
+
// Derive from secret
|
|
14170
|
+
const { secp256k1 } = await import('@noble/curves/secp256k1');
|
|
14171
|
+
const uncompressedPubKey = secp256k1.getPublicKey(params.senderSecret, false);
|
|
14172
|
+
pubKeyX = Array.from(uncompressedPubKey.slice(1, 33));
|
|
14173
|
+
pubKeyY = Array.from(uncompressedPubKey.slice(33, 65));
|
|
14174
|
+
}
|
|
14175
|
+
|
|
14176
|
+
const witnessInputs = {
|
|
14177
|
+
intent_hash: intentHashField,
|
|
14178
|
+
sender_commitment_x: commitmentX,
|
|
14179
|
+
sender_commitment_y: commitmentY,
|
|
14180
|
+
nullifier: nullifier,
|
|
14181
|
+
timestamp: params.timestamp.toString(),
|
|
14182
|
+
expiry: params.expiry.toString(),
|
|
14183
|
+
sender_address: senderAddressField,
|
|
14184
|
+
sender_blinding: senderBlindingField,
|
|
14185
|
+
sender_secret: senderSecretField,
|
|
14186
|
+
pub_key_x: pubKeyX,
|
|
14187
|
+
pub_key_y: pubKeyY,
|
|
14188
|
+
signature: signature,
|
|
14189
|
+
message_hash: messageHash,
|
|
14190
|
+
nonce: nonceField,
|
|
14191
|
+
};
|
|
14192
|
+
|
|
14193
|
+
sendProgress(id, 'witness', 40, 'Executing validity circuit...');
|
|
14194
|
+
const { witness } = await validityNoir.execute(witnessInputs);
|
|
14195
|
+
|
|
14196
|
+
sendProgress(id, 'proving', 60, 'Generating validity proof...');
|
|
14197
|
+
const proofData = await validityBackend.generateProof(witness);
|
|
14198
|
+
|
|
14199
|
+
sendProgress(id, 'complete', 100, 'Validity proof generated');
|
|
14200
|
+
|
|
14201
|
+
const publicInputs = [
|
|
14202
|
+
'0x' + intentHashField,
|
|
14203
|
+
'0x' + commitmentX,
|
|
14204
|
+
'0x' + commitmentY,
|
|
14205
|
+
'0x' + nullifier,
|
|
14206
|
+
'0x' + params.timestamp.toString(16).padStart(16, '0'),
|
|
14207
|
+
'0x' + params.expiry.toString(16).padStart(16, '0'),
|
|
14208
|
+
];
|
|
14209
|
+
|
|
14210
|
+
const proof = {
|
|
14211
|
+
type: 'validity',
|
|
14212
|
+
proof: '0x' + bytesToHex(proofData.proof),
|
|
14213
|
+
publicInputs,
|
|
14214
|
+
};
|
|
14215
|
+
|
|
14216
|
+
sendSuccess(id, { proof, publicInputs });
|
|
14217
|
+
} catch (error) {
|
|
14218
|
+
sendError(id, error);
|
|
14219
|
+
}
|
|
14220
|
+
}
|
|
14221
|
+
|
|
14222
|
+
// Generate fulfillment proof
|
|
14223
|
+
async function generateFulfillmentProof(id, params) {
|
|
14224
|
+
if (!isReady) {
|
|
14225
|
+
sendError(id, new Error('Worker not initialized'));
|
|
14226
|
+
return;
|
|
14227
|
+
}
|
|
14228
|
+
|
|
14229
|
+
try {
|
|
14230
|
+
sendProgress(id, 'witness', 20, 'Preparing fulfillment witness...');
|
|
14231
|
+
|
|
14232
|
+
// Import noble crypto for hashing
|
|
14233
|
+
const { sha256 } = await import('@noble/hashes/sha256');
|
|
14234
|
+
|
|
14235
|
+
const intentHashField = hexToField(params.intentHash);
|
|
14236
|
+
const recipientStealthField = hexToField(params.recipientStealth);
|
|
14237
|
+
|
|
14238
|
+
// Compute output commitment
|
|
14239
|
+
const amountBytes = bigintToBytes(params.outputAmount, 8);
|
|
14240
|
+
const blindingBytes = params.outputBlinding.slice(0, 32);
|
|
14241
|
+
const outputPreimage = new Uint8Array([...amountBytes, ...blindingBytes]);
|
|
14242
|
+
const outputHash = sha256(outputPreimage);
|
|
14243
|
+
const commitmentX = bytesToHex(outputHash.slice(0, 16)).padStart(64, '0');
|
|
14244
|
+
const commitmentY = bytesToHex(outputHash.slice(16, 32)).padStart(64, '0');
|
|
14245
|
+
|
|
14246
|
+
const solverSecretField = bytesToField(params.solverSecret);
|
|
14247
|
+
|
|
14248
|
+
// Compute solver ID
|
|
14249
|
+
const solverSecretBytes = hexToBytes(solverSecretField.padStart(64, '0'));
|
|
14250
|
+
const solverIdHash = sha256(solverSecretBytes);
|
|
14251
|
+
const solverId = bytesToHex(solverIdHash);
|
|
14252
|
+
|
|
14253
|
+
const outputBlindingField = bytesToField(params.outputBlinding);
|
|
14254
|
+
|
|
14255
|
+
const attestation = params.oracleAttestation;
|
|
14256
|
+
const attestationRecipientField = hexToField(attestation.recipient);
|
|
14257
|
+
const attestationTxHashField = hexToField(attestation.txHash);
|
|
14258
|
+
const oracleSignature = Array.from(attestation.signature);
|
|
14259
|
+
|
|
14260
|
+
// Compute oracle message hash
|
|
14261
|
+
const recipientBytes = hexToBytes(attestationRecipientField);
|
|
14262
|
+
const attestationAmountBytes = bigintToBytes(attestation.amount, 8);
|
|
14263
|
+
const txHashBytes = hexToBytes(attestationTxHashField);
|
|
14264
|
+
const blockBytes = bigintToBytes(attestation.blockNumber, 8);
|
|
14265
|
+
const oraclePreimage = new Uint8Array([
|
|
14266
|
+
...recipientBytes,
|
|
14267
|
+
...attestationAmountBytes,
|
|
14268
|
+
...txHashBytes,
|
|
14269
|
+
...blockBytes,
|
|
14270
|
+
]);
|
|
14271
|
+
const oracleMessageHash = Array.from(sha256(oraclePreimage));
|
|
14272
|
+
|
|
14273
|
+
const oraclePubKeyX = config.oraclePublicKey?.x ?? new Array(32).fill(0);
|
|
14274
|
+
const oraclePubKeyY = config.oraclePublicKey?.y ?? new Array(32).fill(0);
|
|
14275
|
+
|
|
14276
|
+
const witnessInputs = {
|
|
14277
|
+
intent_hash: intentHashField,
|
|
14278
|
+
output_commitment_x: commitmentX,
|
|
14279
|
+
output_commitment_y: commitmentY,
|
|
14280
|
+
recipient_stealth: recipientStealthField,
|
|
14281
|
+
min_output_amount: params.minOutputAmount.toString(),
|
|
14282
|
+
solver_id: solverId,
|
|
14283
|
+
fulfillment_time: params.fulfillmentTime.toString(),
|
|
14284
|
+
expiry: params.expiry.toString(),
|
|
14285
|
+
output_amount: params.outputAmount.toString(),
|
|
14286
|
+
output_blinding: outputBlindingField,
|
|
14287
|
+
solver_secret: solverSecretField,
|
|
14288
|
+
attestation_recipient: attestationRecipientField,
|
|
14289
|
+
attestation_amount: attestation.amount.toString(),
|
|
14290
|
+
attestation_tx_hash: attestationTxHashField,
|
|
14291
|
+
attestation_block: attestation.blockNumber.toString(),
|
|
14292
|
+
oracle_signature: oracleSignature,
|
|
14293
|
+
oracle_message_hash: oracleMessageHash,
|
|
14294
|
+
oracle_pub_key_x: oraclePubKeyX,
|
|
14295
|
+
oracle_pub_key_y: oraclePubKeyY,
|
|
14296
|
+
};
|
|
14297
|
+
|
|
14298
|
+
sendProgress(id, 'witness', 40, 'Executing fulfillment circuit...');
|
|
14299
|
+
const { witness } = await fulfillmentNoir.execute(witnessInputs);
|
|
14300
|
+
|
|
14301
|
+
sendProgress(id, 'proving', 60, 'Generating fulfillment proof...');
|
|
14302
|
+
const proofData = await fulfillmentBackend.generateProof(witness);
|
|
14303
|
+
|
|
14304
|
+
sendProgress(id, 'complete', 100, 'Fulfillment proof generated');
|
|
14305
|
+
|
|
14306
|
+
const publicInputs = [
|
|
14307
|
+
'0x' + intentHashField,
|
|
14308
|
+
'0x' + commitmentX,
|
|
14309
|
+
'0x' + commitmentY,
|
|
14310
|
+
'0x' + recipientStealthField,
|
|
14311
|
+
'0x' + params.minOutputAmount.toString(16).padStart(16, '0'),
|
|
14312
|
+
'0x' + solverId,
|
|
14313
|
+
'0x' + params.fulfillmentTime.toString(16).padStart(16, '0'),
|
|
14314
|
+
'0x' + params.expiry.toString(16).padStart(16, '0'),
|
|
14315
|
+
];
|
|
14316
|
+
|
|
14317
|
+
const proof = {
|
|
14318
|
+
type: 'fulfillment',
|
|
14319
|
+
proof: '0x' + bytesToHex(proofData.proof),
|
|
14320
|
+
publicInputs,
|
|
14321
|
+
};
|
|
14322
|
+
|
|
14323
|
+
sendSuccess(id, { proof, publicInputs });
|
|
14324
|
+
} catch (error) {
|
|
14325
|
+
sendError(id, error);
|
|
14326
|
+
}
|
|
14327
|
+
}
|
|
14328
|
+
|
|
12992
14329
|
// Helper functions
|
|
12993
14330
|
function bytesToField(bytes) {
|
|
12994
14331
|
let result = 0n;
|
|
@@ -13016,6 +14353,39 @@ function createWorkerBlobURL() {
|
|
|
13016
14353
|
return Array.from(bytes).map(b => b.toString(16).padStart(2, '0')).join('');
|
|
13017
14354
|
}
|
|
13018
14355
|
|
|
14356
|
+
function hexToBytes(hex) {
|
|
14357
|
+
const h = hex.startsWith('0x') ? hex.slice(2) : hex;
|
|
14358
|
+
const bytes = new Uint8Array(h.length / 2);
|
|
14359
|
+
for (let i = 0; i < h.length; i += 2) {
|
|
14360
|
+
bytes[i / 2] = parseInt(h.slice(i, i + 2), 16);
|
|
14361
|
+
}
|
|
14362
|
+
return bytes;
|
|
14363
|
+
}
|
|
14364
|
+
|
|
14365
|
+
function hexToField(hex) {
|
|
14366
|
+
const h = hex.startsWith('0x') ? hex.slice(2) : hex;
|
|
14367
|
+
return h.padStart(64, '0');
|
|
14368
|
+
}
|
|
14369
|
+
|
|
14370
|
+
function fieldToBytes32(field) {
|
|
14371
|
+
const hex = field.padStart(64, '0');
|
|
14372
|
+
const bytes = [];
|
|
14373
|
+
for (let i = 0; i < 32; i++) {
|
|
14374
|
+
bytes.push(parseInt(hex.slice(i * 2, i * 2 + 2), 16));
|
|
14375
|
+
}
|
|
14376
|
+
return bytes;
|
|
14377
|
+
}
|
|
14378
|
+
|
|
14379
|
+
function bigintToBytes(value, length) {
|
|
14380
|
+
const bytes = new Uint8Array(length);
|
|
14381
|
+
let v = value;
|
|
14382
|
+
for (let i = length - 1; i >= 0; i--) {
|
|
14383
|
+
bytes[i] = Number(v & 0xffn);
|
|
14384
|
+
v = v >> 8n;
|
|
14385
|
+
}
|
|
14386
|
+
return bytes;
|
|
14387
|
+
}
|
|
14388
|
+
|
|
13019
14389
|
// Message handler
|
|
13020
14390
|
self.onmessage = async function(event) {
|
|
13021
14391
|
const { id, type, params, config: initConfig } = event.data;
|
|
@@ -13028,12 +14398,10 @@ function createWorkerBlobURL() {
|
|
|
13028
14398
|
await generateFundingProof(id, params);
|
|
13029
14399
|
break;
|
|
13030
14400
|
case 'generateValidityProof':
|
|
13031
|
-
|
|
13032
|
-
sendError(id, new Error('Validity proof not yet implemented in worker'));
|
|
14401
|
+
await generateValidityProof(id, params);
|
|
13033
14402
|
break;
|
|
13034
14403
|
case 'generateFulfillmentProof':
|
|
13035
|
-
|
|
13036
|
-
sendError(id, new Error('Fulfillment proof not yet implemented in worker'));
|
|
14404
|
+
await generateFulfillmentProof(id, params);
|
|
13037
14405
|
break;
|
|
13038
14406
|
case 'destroy':
|
|
13039
14407
|
// Cleanup
|
|
@@ -13193,6 +14561,7 @@ var ProofWorker = class _ProofWorker {
|
|
|
13193
14561
|
MockWalletAdapter,
|
|
13194
14562
|
NATIVE_TOKENS,
|
|
13195
14563
|
NEARIntentsAdapter,
|
|
14564
|
+
NEARIntentsBackend,
|
|
13196
14565
|
NetworkError,
|
|
13197
14566
|
ORACLE_DOMAIN,
|
|
13198
14567
|
OneClickClient,
|
|
@@ -13215,13 +14584,18 @@ var ProofWorker = class _ProofWorker {
|
|
|
13215
14584
|
STABLECOIN_ADDRESSES,
|
|
13216
14585
|
STABLECOIN_DECIMALS,
|
|
13217
14586
|
STABLECOIN_INFO,
|
|
14587
|
+
SettlementRegistry,
|
|
14588
|
+
SettlementRegistryError,
|
|
14589
|
+
SmartRouter,
|
|
13218
14590
|
SolanaWalletAdapter,
|
|
14591
|
+
SwapStatus,
|
|
13219
14592
|
Treasury,
|
|
13220
14593
|
TrezorWalletAdapter,
|
|
13221
14594
|
ValidationError,
|
|
13222
14595
|
WalletError,
|
|
13223
14596
|
WalletErrorCode,
|
|
13224
14597
|
ZcashErrorCode,
|
|
14598
|
+
ZcashNativeBackend,
|
|
13225
14599
|
ZcashRPCClient,
|
|
13226
14600
|
ZcashRPCError,
|
|
13227
14601
|
ZcashShieldedService,
|
|
@@ -13251,16 +14625,19 @@ var ProofWorker = class _ProofWorker {
|
|
|
13251
14625
|
createMockSolver,
|
|
13252
14626
|
createMockTrezorAdapter,
|
|
13253
14627
|
createNEARIntentsAdapter,
|
|
14628
|
+
createNEARIntentsBackend,
|
|
13254
14629
|
createOracleRegistry,
|
|
13255
14630
|
createProductionSIP,
|
|
13256
14631
|
createSIP,
|
|
13257
14632
|
createShieldedIntent,
|
|
13258
14633
|
createShieldedPayment,
|
|
14634
|
+
createSmartRouter,
|
|
13259
14635
|
createSolanaAdapter,
|
|
13260
14636
|
createTrezorAdapter,
|
|
13261
14637
|
createWalletFactory,
|
|
13262
14638
|
createWorkerBlobURL,
|
|
13263
14639
|
createZcashClient,
|
|
14640
|
+
createZcashNativeBackend,
|
|
13264
14641
|
createZcashShieldedService,
|
|
13265
14642
|
createZcashSwapService,
|
|
13266
14643
|
decodeStealthMetaAddress,
|