@portal-hq/web 3.14.0-alpha.0 → 3.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commonjs/integrations/trading/lifi/index.js +22 -1
- package/lib/commonjs/integrations/yield/yieldxyz.highLevel.test.js +108 -0
- package/lib/commonjs/integrations/yield/yieldxyz.js +27 -3
- package/lib/commonjs/mpc/index.js +4 -3
- package/lib/esm/integrations/trading/lifi/index.js +22 -1
- package/lib/esm/integrations/yield/yieldxyz.highLevel.test.js +108 -0
- package/lib/esm/integrations/yield/yieldxyz.js +27 -3
- package/lib/esm/mpc/index.js +4 -3
- package/package.json +2 -3
- package/src/integrations/trading/lifi/index.ts +34 -1
- package/src/integrations/yield/yieldxyz.highLevel.test.ts +133 -0
- package/src/integrations/yield/yieldxyz.ts +27 -5
- package/src/mpc/index.ts +4 -2
- package/src/shared/types/yieldxyz.ts +7 -0
- package/src/shared/types/zero-x.ts +18 -2
|
@@ -280,6 +280,27 @@ class LiFi {
|
|
|
280
280
|
});
|
|
281
281
|
throw new LifiReportedError(msg);
|
|
282
282
|
}
|
|
283
|
+
let lifiTxHash = txHash;
|
|
284
|
+
if (network.startsWith('eip155:') && o.evmRequestFn) {
|
|
285
|
+
try {
|
|
286
|
+
const userOpReceipt = yield o.evmRequestFn('eth_getUserOperationReceipt', [txHash], network);
|
|
287
|
+
if (userOpReceipt &&
|
|
288
|
+
typeof userOpReceipt === 'object' &&
|
|
289
|
+
'receipt' in userOpReceipt &&
|
|
290
|
+
userOpReceipt.receipt &&
|
|
291
|
+
typeof userOpReceipt.receipt === 'object' &&
|
|
292
|
+
'transactionHash' in userOpReceipt.receipt) {
|
|
293
|
+
const bundleHash = userOpReceipt.receipt.transactionHash;
|
|
294
|
+
if (bundleHash && typeof bundleHash === 'string') {
|
|
295
|
+
lifiTxHash = bundleHash;
|
|
296
|
+
logger_1.sdkLogger.debug(`${LOG_PREFIX} Resolved AA bundle tx hash for LiFi: ${lifiTxHash}`);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
catch (error) {
|
|
301
|
+
logger_1.sdkLogger.debug(`${LOG_PREFIX} Could not resolve bundle hash (likely EOA tx), using original hash`);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
283
304
|
const bridgeTool = statusBridgeFromStepTool(populated.tool);
|
|
284
305
|
const crossLike = populated.type === 'cross' ||
|
|
285
306
|
populated.action.fromChainId !== populated.action.toChainId;
|
|
@@ -294,7 +315,7 @@ class LiFi {
|
|
|
294
315
|
});
|
|
295
316
|
const pollOpts = (_p = params.statusPoll) !== null && _p !== void 0 ? _p : {};
|
|
296
317
|
const terminal = yield this.pollStatus({
|
|
297
|
-
txHash,
|
|
318
|
+
txHash: lifiTxHash,
|
|
298
319
|
fromChain: params.fromChain,
|
|
299
320
|
toChain: params.toChain,
|
|
300
321
|
bridge: bridgeTool,
|
|
@@ -327,4 +327,112 @@ describe('YieldXyz high-level (deposit, withdraw, defaults)', () => {
|
|
|
327
327
|
expect(r.chain).toBe('eip155:1');
|
|
328
328
|
expect(r.token).toBe('ETH');
|
|
329
329
|
}));
|
|
330
|
+
it('status=SUCCESS when no waitForConfirmation configured', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
331
|
+
jest.spyOn(mpc, 'enterYieldXyzYield').mockResolvedValue(enterResponseWithTxs([
|
|
332
|
+
{
|
|
333
|
+
id: 'tx1',
|
|
334
|
+
network: 'eip155:1',
|
|
335
|
+
unsignedTransaction: { to: '0x1' },
|
|
336
|
+
},
|
|
337
|
+
]));
|
|
338
|
+
jest.spyOn(mpc, 'trackYieldXyzTransaction').mockResolvedValue({});
|
|
339
|
+
const r = yield yieldXyz.deposit({
|
|
340
|
+
yieldId: 'y',
|
|
341
|
+
amount: '1',
|
|
342
|
+
address: constants_1.mockAddress,
|
|
343
|
+
});
|
|
344
|
+
expect(r.status).toBe('SUCCESS');
|
|
345
|
+
}));
|
|
346
|
+
it('status=SUCCESS when all confirmations reach true', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
347
|
+
const y = new yieldxyz_1.default({
|
|
348
|
+
mpc,
|
|
349
|
+
waitForConfirmation: jest.fn().mockResolvedValue(true),
|
|
350
|
+
});
|
|
351
|
+
y.setSignAndSendTransaction(jest.fn().mockResolvedValue('0xh'));
|
|
352
|
+
jest.spyOn(mpc, 'enterYieldXyzYield').mockResolvedValue(enterResponseWithTxs([
|
|
353
|
+
{
|
|
354
|
+
id: 'tx1',
|
|
355
|
+
network: 'eip155:1',
|
|
356
|
+
unsignedTransaction: { to: '0x1' },
|
|
357
|
+
},
|
|
358
|
+
{
|
|
359
|
+
id: 'tx2',
|
|
360
|
+
network: 'eip155:1',
|
|
361
|
+
unsignedTransaction: { to: '0x2' },
|
|
362
|
+
},
|
|
363
|
+
]));
|
|
364
|
+
jest.spyOn(mpc, 'trackYieldXyzTransaction').mockResolvedValue({});
|
|
365
|
+
const r = yield y.deposit({ yieldId: 'y', amount: '1', address: constants_1.mockAddress });
|
|
366
|
+
expect(r.status).toBe('SUCCESS');
|
|
367
|
+
expect(r.hashes).toHaveLength(2);
|
|
368
|
+
}));
|
|
369
|
+
it('status=FAILED when first confirmation returns false', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
370
|
+
const y = new yieldxyz_1.default({
|
|
371
|
+
mpc,
|
|
372
|
+
waitForConfirmation: jest.fn().mockResolvedValue(false),
|
|
373
|
+
});
|
|
374
|
+
y.setSignAndSendTransaction(jest.fn().mockResolvedValue('0xh'));
|
|
375
|
+
jest.spyOn(mpc, 'enterYieldXyzYield').mockResolvedValue(enterResponseWithTxs([
|
|
376
|
+
{
|
|
377
|
+
id: 'tx1',
|
|
378
|
+
network: 'eip155:1',
|
|
379
|
+
unsignedTransaction: { to: '0x1' },
|
|
380
|
+
},
|
|
381
|
+
]));
|
|
382
|
+
jest.spyOn(mpc, 'trackYieldXyzTransaction').mockResolvedValue({});
|
|
383
|
+
const r = yield y.deposit({ yieldId: 'y', amount: '1', address: constants_1.mockAddress });
|
|
384
|
+
expect(r.status).toBe('FAILED');
|
|
385
|
+
expect(r.hashes).toEqual(['0xh']);
|
|
386
|
+
}));
|
|
387
|
+
it('status=PARTIAL_SUCCESS when first tx confirms but second fails', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
388
|
+
const waiter = jest
|
|
389
|
+
.fn()
|
|
390
|
+
.mockResolvedValueOnce(true)
|
|
391
|
+
.mockResolvedValueOnce(false);
|
|
392
|
+
const y = new yieldxyz_1.default({
|
|
393
|
+
mpc,
|
|
394
|
+
waitForConfirmation: waiter,
|
|
395
|
+
});
|
|
396
|
+
const signer = jest
|
|
397
|
+
.fn()
|
|
398
|
+
.mockResolvedValueOnce('0xh1')
|
|
399
|
+
.mockResolvedValueOnce('0xh2');
|
|
400
|
+
y.setSignAndSendTransaction(signer);
|
|
401
|
+
jest.spyOn(mpc, 'enterYieldXyzYield').mockResolvedValue(enterResponseWithTxs([
|
|
402
|
+
{
|
|
403
|
+
id: 'tx1',
|
|
404
|
+
network: 'eip155:1',
|
|
405
|
+
unsignedTransaction: { to: '0x1' },
|
|
406
|
+
},
|
|
407
|
+
{
|
|
408
|
+
id: 'tx2',
|
|
409
|
+
network: 'eip155:1',
|
|
410
|
+
unsignedTransaction: { to: '0x2' },
|
|
411
|
+
},
|
|
412
|
+
]));
|
|
413
|
+
jest.spyOn(mpc, 'trackYieldXyzTransaction').mockResolvedValue({});
|
|
414
|
+
const r = yield y.deposit({ yieldId: 'y', amount: '1', address: constants_1.mockAddress });
|
|
415
|
+
expect(r.status).toBe('PARTIAL_SUCCESS');
|
|
416
|
+
expect(r.hashes).toEqual(['0xh1', '0xh2']);
|
|
417
|
+
expect(signer).toHaveBeenCalledTimes(2);
|
|
418
|
+
expect(waiter).toHaveBeenCalledTimes(2);
|
|
419
|
+
}));
|
|
420
|
+
it('withdraw: status=FAILED when confirmation returns false', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
421
|
+
const y = new yieldxyz_1.default({
|
|
422
|
+
mpc,
|
|
423
|
+
waitForConfirmation: jest.fn().mockResolvedValue(false),
|
|
424
|
+
});
|
|
425
|
+
y.setSignAndSendTransaction(jest.fn().mockResolvedValue('0xh'));
|
|
426
|
+
jest.spyOn(mpc, 'exitYieldXyzYield').mockResolvedValue(exitResponseWithTxs([
|
|
427
|
+
{
|
|
428
|
+
id: 'tx1',
|
|
429
|
+
network: 'eip155:1',
|
|
430
|
+
unsignedTransaction: { to: '0x1' },
|
|
431
|
+
},
|
|
432
|
+
]));
|
|
433
|
+
jest.spyOn(mpc, 'trackYieldXyzTransaction').mockResolvedValue({});
|
|
434
|
+
const r = yield y.withdraw({ yieldId: 'y', amount: '1', address: constants_1.mockAddress });
|
|
435
|
+
expect(r.status).toBe('FAILED');
|
|
436
|
+
expect(r.hashes).toEqual(['0xh']);
|
|
437
|
+
}));
|
|
330
438
|
});
|
|
@@ -263,9 +263,10 @@ class YieldXyz {
|
|
|
263
263
|
const result = Object.assign(Object.assign({}, base), (resolvedChain !== undefined && resolvedToken !== undefined
|
|
264
264
|
? { chain: resolvedChain, token: resolvedToken }
|
|
265
265
|
: {}));
|
|
266
|
-
logger_1.sdkLogger.info(`${LOG_PREFIX} deposit:
|
|
266
|
+
logger_1.sdkLogger.info(`${LOG_PREFIX} deposit: complete`, {
|
|
267
267
|
hashes: result.hashes,
|
|
268
268
|
yieldId: result.yieldId,
|
|
269
|
+
status: result.status,
|
|
269
270
|
yieldOpportunityDetails: result.yieldOpportunityDetails,
|
|
270
271
|
});
|
|
271
272
|
return result;
|
|
@@ -310,9 +311,10 @@ class YieldXyz {
|
|
|
310
311
|
const result = Object.assign(Object.assign({}, base), (resolvedChain !== undefined && resolvedToken !== undefined
|
|
311
312
|
? { chain: resolvedChain, token: resolvedToken }
|
|
312
313
|
: {}));
|
|
313
|
-
logger_1.sdkLogger.info(`${LOG_PREFIX} withdraw:
|
|
314
|
+
logger_1.sdkLogger.info(`${LOG_PREFIX} withdraw: complete`, {
|
|
314
315
|
hashes: result.hashes,
|
|
315
316
|
yieldId: result.yieldId,
|
|
317
|
+
status: result.status,
|
|
316
318
|
yieldOpportunityDetails: result.yieldOpportunityDetails,
|
|
317
319
|
});
|
|
318
320
|
return result;
|
|
@@ -444,6 +446,7 @@ class YieldXyz {
|
|
|
444
446
|
const total = transactions.length;
|
|
445
447
|
const hashes = [];
|
|
446
448
|
let confirmationsReached = 0;
|
|
449
|
+
let confirmationsRequired = waitForConfirmation ? total : 0;
|
|
447
450
|
for (let index = 0; index < transactions.length; index++) {
|
|
448
451
|
const tx = transactions[index];
|
|
449
452
|
// Validate transaction exists (defensive check for sparse arrays)
|
|
@@ -615,15 +618,36 @@ class YieldXyz {
|
|
|
615
618
|
const rawResponse = (_d = response.data) === null || _d === void 0 ? void 0 : _d.rawResponse;
|
|
616
619
|
const yieldId = (_e = rawResponse === null || rawResponse === void 0 ? void 0 : rawResponse.yieldId) !== null && _e !== void 0 ? _e : '';
|
|
617
620
|
const yieldOpportunityDetails = this.buildYieldOpportunityDetails(response);
|
|
621
|
+
// Determine status based on confirmation semantics from docs:
|
|
622
|
+
// - If no confirmations required (no waitForConfirmation): SUCCESS
|
|
623
|
+
// - If all required confirmations reached: SUCCESS
|
|
624
|
+
// - If some confirmations reached but not all: PARTIAL_SUCCESS
|
|
625
|
+
// - If confirmations required but zero reached: FAILED
|
|
626
|
+
let status;
|
|
627
|
+
if (confirmationsRequired === 0) {
|
|
628
|
+
status = 'SUCCESS';
|
|
629
|
+
}
|
|
630
|
+
else if (confirmationsReached === confirmationsRequired) {
|
|
631
|
+
status = 'SUCCESS';
|
|
632
|
+
}
|
|
633
|
+
else if (confirmationsReached > 0) {
|
|
634
|
+
status = 'PARTIAL_SUCCESS';
|
|
635
|
+
}
|
|
636
|
+
else {
|
|
637
|
+
status = 'FAILED';
|
|
638
|
+
}
|
|
618
639
|
logger_1.sdkLogger.info(`${LOG_PREFIX} ${method}: executeAndTrack complete`, {
|
|
619
640
|
yieldId,
|
|
620
641
|
hashCount: hashes.length,
|
|
621
|
-
confirmationsReached
|
|
642
|
+
confirmationsReached,
|
|
643
|
+
confirmationsRequired,
|
|
644
|
+
status,
|
|
622
645
|
});
|
|
623
646
|
return {
|
|
624
647
|
hashes,
|
|
625
648
|
yieldId,
|
|
626
649
|
yieldOpportunityDetails,
|
|
650
|
+
status,
|
|
627
651
|
};
|
|
628
652
|
});
|
|
629
653
|
}
|
|
@@ -14,7 +14,7 @@ const errors_1 = require("./errors");
|
|
|
14
14
|
const logger_1 = require("../logger");
|
|
15
15
|
const index_1 = require("../index");
|
|
16
16
|
const trace_1 = require("../shared/trace");
|
|
17
|
-
const WEB_SDK_VERSION = '3.14.0
|
|
17
|
+
const WEB_SDK_VERSION = '3.14.0';
|
|
18
18
|
class Mpc {
|
|
19
19
|
get ready() {
|
|
20
20
|
return this._ready;
|
|
@@ -1011,10 +1011,11 @@ class Mpc {
|
|
|
1011
1011
|
});
|
|
1012
1012
|
}
|
|
1013
1013
|
rpcRequest(data, options) {
|
|
1014
|
-
var _a, _b;
|
|
1015
1014
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1016
1015
|
const { timeoutMs = 30000, traceId } = options !== null && options !== void 0 ? options : {};
|
|
1017
|
-
const requestId =
|
|
1016
|
+
const requestId = typeof crypto !== 'undefined' && crypto.randomUUID
|
|
1017
|
+
? crypto.randomUUID()
|
|
1018
|
+
: `${Date.now()}-${Math.random()}`;
|
|
1018
1019
|
const resolvedTraceId = traceId !== null && traceId !== void 0 ? traceId : (0, trace_1.generateTraceId)();
|
|
1019
1020
|
logger_1.sdkLogger.debug('[Portal] rpcRequest', {
|
|
1020
1021
|
requestId,
|
|
@@ -273,6 +273,27 @@ export default class LiFi {
|
|
|
273
273
|
});
|
|
274
274
|
throw new LifiReportedError(msg);
|
|
275
275
|
}
|
|
276
|
+
let lifiTxHash = txHash;
|
|
277
|
+
if (network.startsWith('eip155:') && o.evmRequestFn) {
|
|
278
|
+
try {
|
|
279
|
+
const userOpReceipt = yield o.evmRequestFn('eth_getUserOperationReceipt', [txHash], network);
|
|
280
|
+
if (userOpReceipt &&
|
|
281
|
+
typeof userOpReceipt === 'object' &&
|
|
282
|
+
'receipt' in userOpReceipt &&
|
|
283
|
+
userOpReceipt.receipt &&
|
|
284
|
+
typeof userOpReceipt.receipt === 'object' &&
|
|
285
|
+
'transactionHash' in userOpReceipt.receipt) {
|
|
286
|
+
const bundleHash = userOpReceipt.receipt.transactionHash;
|
|
287
|
+
if (bundleHash && typeof bundleHash === 'string') {
|
|
288
|
+
lifiTxHash = bundleHash;
|
|
289
|
+
sdkLogger.debug(`${LOG_PREFIX} Resolved AA bundle tx hash for LiFi: ${lifiTxHash}`);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
catch (error) {
|
|
294
|
+
sdkLogger.debug(`${LOG_PREFIX} Could not resolve bundle hash (likely EOA tx), using original hash`);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
276
297
|
const bridgeTool = statusBridgeFromStepTool(populated.tool);
|
|
277
298
|
const crossLike = populated.type === 'cross' ||
|
|
278
299
|
populated.action.fromChainId !== populated.action.toChainId;
|
|
@@ -287,7 +308,7 @@ export default class LiFi {
|
|
|
287
308
|
});
|
|
288
309
|
const pollOpts = (_p = params.statusPoll) !== null && _p !== void 0 ? _p : {};
|
|
289
310
|
const terminal = yield this.pollStatus({
|
|
290
|
-
txHash,
|
|
311
|
+
txHash: lifiTxHash,
|
|
291
312
|
fromChain: params.fromChain,
|
|
292
313
|
toChain: params.toChain,
|
|
293
314
|
bridge: bridgeTool,
|
|
@@ -322,4 +322,112 @@ describe('YieldXyz high-level (deposit, withdraw, defaults)', () => {
|
|
|
322
322
|
expect(r.chain).toBe('eip155:1');
|
|
323
323
|
expect(r.token).toBe('ETH');
|
|
324
324
|
}));
|
|
325
|
+
it('status=SUCCESS when no waitForConfirmation configured', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
326
|
+
jest.spyOn(mpc, 'enterYieldXyzYield').mockResolvedValue(enterResponseWithTxs([
|
|
327
|
+
{
|
|
328
|
+
id: 'tx1',
|
|
329
|
+
network: 'eip155:1',
|
|
330
|
+
unsignedTransaction: { to: '0x1' },
|
|
331
|
+
},
|
|
332
|
+
]));
|
|
333
|
+
jest.spyOn(mpc, 'trackYieldXyzTransaction').mockResolvedValue({});
|
|
334
|
+
const r = yield yieldXyz.deposit({
|
|
335
|
+
yieldId: 'y',
|
|
336
|
+
amount: '1',
|
|
337
|
+
address: mockAddress,
|
|
338
|
+
});
|
|
339
|
+
expect(r.status).toBe('SUCCESS');
|
|
340
|
+
}));
|
|
341
|
+
it('status=SUCCESS when all confirmations reach true', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
342
|
+
const y = new YieldXyz({
|
|
343
|
+
mpc,
|
|
344
|
+
waitForConfirmation: jest.fn().mockResolvedValue(true),
|
|
345
|
+
});
|
|
346
|
+
y.setSignAndSendTransaction(jest.fn().mockResolvedValue('0xh'));
|
|
347
|
+
jest.spyOn(mpc, 'enterYieldXyzYield').mockResolvedValue(enterResponseWithTxs([
|
|
348
|
+
{
|
|
349
|
+
id: 'tx1',
|
|
350
|
+
network: 'eip155:1',
|
|
351
|
+
unsignedTransaction: { to: '0x1' },
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
id: 'tx2',
|
|
355
|
+
network: 'eip155:1',
|
|
356
|
+
unsignedTransaction: { to: '0x2' },
|
|
357
|
+
},
|
|
358
|
+
]));
|
|
359
|
+
jest.spyOn(mpc, 'trackYieldXyzTransaction').mockResolvedValue({});
|
|
360
|
+
const r = yield y.deposit({ yieldId: 'y', amount: '1', address: mockAddress });
|
|
361
|
+
expect(r.status).toBe('SUCCESS');
|
|
362
|
+
expect(r.hashes).toHaveLength(2);
|
|
363
|
+
}));
|
|
364
|
+
it('status=FAILED when first confirmation returns false', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
365
|
+
const y = new YieldXyz({
|
|
366
|
+
mpc,
|
|
367
|
+
waitForConfirmation: jest.fn().mockResolvedValue(false),
|
|
368
|
+
});
|
|
369
|
+
y.setSignAndSendTransaction(jest.fn().mockResolvedValue('0xh'));
|
|
370
|
+
jest.spyOn(mpc, 'enterYieldXyzYield').mockResolvedValue(enterResponseWithTxs([
|
|
371
|
+
{
|
|
372
|
+
id: 'tx1',
|
|
373
|
+
network: 'eip155:1',
|
|
374
|
+
unsignedTransaction: { to: '0x1' },
|
|
375
|
+
},
|
|
376
|
+
]));
|
|
377
|
+
jest.spyOn(mpc, 'trackYieldXyzTransaction').mockResolvedValue({});
|
|
378
|
+
const r = yield y.deposit({ yieldId: 'y', amount: '1', address: mockAddress });
|
|
379
|
+
expect(r.status).toBe('FAILED');
|
|
380
|
+
expect(r.hashes).toEqual(['0xh']);
|
|
381
|
+
}));
|
|
382
|
+
it('status=PARTIAL_SUCCESS when first tx confirms but second fails', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
383
|
+
const waiter = jest
|
|
384
|
+
.fn()
|
|
385
|
+
.mockResolvedValueOnce(true)
|
|
386
|
+
.mockResolvedValueOnce(false);
|
|
387
|
+
const y = new YieldXyz({
|
|
388
|
+
mpc,
|
|
389
|
+
waitForConfirmation: waiter,
|
|
390
|
+
});
|
|
391
|
+
const signer = jest
|
|
392
|
+
.fn()
|
|
393
|
+
.mockResolvedValueOnce('0xh1')
|
|
394
|
+
.mockResolvedValueOnce('0xh2');
|
|
395
|
+
y.setSignAndSendTransaction(signer);
|
|
396
|
+
jest.spyOn(mpc, 'enterYieldXyzYield').mockResolvedValue(enterResponseWithTxs([
|
|
397
|
+
{
|
|
398
|
+
id: 'tx1',
|
|
399
|
+
network: 'eip155:1',
|
|
400
|
+
unsignedTransaction: { to: '0x1' },
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
id: 'tx2',
|
|
404
|
+
network: 'eip155:1',
|
|
405
|
+
unsignedTransaction: { to: '0x2' },
|
|
406
|
+
},
|
|
407
|
+
]));
|
|
408
|
+
jest.spyOn(mpc, 'trackYieldXyzTransaction').mockResolvedValue({});
|
|
409
|
+
const r = yield y.deposit({ yieldId: 'y', amount: '1', address: mockAddress });
|
|
410
|
+
expect(r.status).toBe('PARTIAL_SUCCESS');
|
|
411
|
+
expect(r.hashes).toEqual(['0xh1', '0xh2']);
|
|
412
|
+
expect(signer).toHaveBeenCalledTimes(2);
|
|
413
|
+
expect(waiter).toHaveBeenCalledTimes(2);
|
|
414
|
+
}));
|
|
415
|
+
it('withdraw: status=FAILED when confirmation returns false', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
416
|
+
const y = new YieldXyz({
|
|
417
|
+
mpc,
|
|
418
|
+
waitForConfirmation: jest.fn().mockResolvedValue(false),
|
|
419
|
+
});
|
|
420
|
+
y.setSignAndSendTransaction(jest.fn().mockResolvedValue('0xh'));
|
|
421
|
+
jest.spyOn(mpc, 'exitYieldXyzYield').mockResolvedValue(exitResponseWithTxs([
|
|
422
|
+
{
|
|
423
|
+
id: 'tx1',
|
|
424
|
+
network: 'eip155:1',
|
|
425
|
+
unsignedTransaction: { to: '0x1' },
|
|
426
|
+
},
|
|
427
|
+
]));
|
|
428
|
+
jest.spyOn(mpc, 'trackYieldXyzTransaction').mockResolvedValue({});
|
|
429
|
+
const r = yield y.withdraw({ yieldId: 'y', amount: '1', address: mockAddress });
|
|
430
|
+
expect(r.status).toBe('FAILED');
|
|
431
|
+
expect(r.hashes).toEqual(['0xh']);
|
|
432
|
+
}));
|
|
325
433
|
});
|
|
@@ -261,9 +261,10 @@ export default class YieldXyz {
|
|
|
261
261
|
const result = Object.assign(Object.assign({}, base), (resolvedChain !== undefined && resolvedToken !== undefined
|
|
262
262
|
? { chain: resolvedChain, token: resolvedToken }
|
|
263
263
|
: {}));
|
|
264
|
-
sdkLogger.info(`${LOG_PREFIX} deposit:
|
|
264
|
+
sdkLogger.info(`${LOG_PREFIX} deposit: complete`, {
|
|
265
265
|
hashes: result.hashes,
|
|
266
266
|
yieldId: result.yieldId,
|
|
267
|
+
status: result.status,
|
|
267
268
|
yieldOpportunityDetails: result.yieldOpportunityDetails,
|
|
268
269
|
});
|
|
269
270
|
return result;
|
|
@@ -308,9 +309,10 @@ export default class YieldXyz {
|
|
|
308
309
|
const result = Object.assign(Object.assign({}, base), (resolvedChain !== undefined && resolvedToken !== undefined
|
|
309
310
|
? { chain: resolvedChain, token: resolvedToken }
|
|
310
311
|
: {}));
|
|
311
|
-
sdkLogger.info(`${LOG_PREFIX} withdraw:
|
|
312
|
+
sdkLogger.info(`${LOG_PREFIX} withdraw: complete`, {
|
|
312
313
|
hashes: result.hashes,
|
|
313
314
|
yieldId: result.yieldId,
|
|
315
|
+
status: result.status,
|
|
314
316
|
yieldOpportunityDetails: result.yieldOpportunityDetails,
|
|
315
317
|
});
|
|
316
318
|
return result;
|
|
@@ -442,6 +444,7 @@ export default class YieldXyz {
|
|
|
442
444
|
const total = transactions.length;
|
|
443
445
|
const hashes = [];
|
|
444
446
|
let confirmationsReached = 0;
|
|
447
|
+
let confirmationsRequired = waitForConfirmation ? total : 0;
|
|
445
448
|
for (let index = 0; index < transactions.length; index++) {
|
|
446
449
|
const tx = transactions[index];
|
|
447
450
|
// Validate transaction exists (defensive check for sparse arrays)
|
|
@@ -613,15 +616,36 @@ export default class YieldXyz {
|
|
|
613
616
|
const rawResponse = (_d = response.data) === null || _d === void 0 ? void 0 : _d.rawResponse;
|
|
614
617
|
const yieldId = (_e = rawResponse === null || rawResponse === void 0 ? void 0 : rawResponse.yieldId) !== null && _e !== void 0 ? _e : '';
|
|
615
618
|
const yieldOpportunityDetails = this.buildYieldOpportunityDetails(response);
|
|
619
|
+
// Determine status based on confirmation semantics from docs:
|
|
620
|
+
// - If no confirmations required (no waitForConfirmation): SUCCESS
|
|
621
|
+
// - If all required confirmations reached: SUCCESS
|
|
622
|
+
// - If some confirmations reached but not all: PARTIAL_SUCCESS
|
|
623
|
+
// - If confirmations required but zero reached: FAILED
|
|
624
|
+
let status;
|
|
625
|
+
if (confirmationsRequired === 0) {
|
|
626
|
+
status = 'SUCCESS';
|
|
627
|
+
}
|
|
628
|
+
else if (confirmationsReached === confirmationsRequired) {
|
|
629
|
+
status = 'SUCCESS';
|
|
630
|
+
}
|
|
631
|
+
else if (confirmationsReached > 0) {
|
|
632
|
+
status = 'PARTIAL_SUCCESS';
|
|
633
|
+
}
|
|
634
|
+
else {
|
|
635
|
+
status = 'FAILED';
|
|
636
|
+
}
|
|
616
637
|
sdkLogger.info(`${LOG_PREFIX} ${method}: executeAndTrack complete`, {
|
|
617
638
|
yieldId,
|
|
618
639
|
hashCount: hashes.length,
|
|
619
|
-
confirmationsReached
|
|
640
|
+
confirmationsReached,
|
|
641
|
+
confirmationsRequired,
|
|
642
|
+
status,
|
|
620
643
|
});
|
|
621
644
|
return {
|
|
622
645
|
hashes,
|
|
623
646
|
yieldId,
|
|
624
647
|
yieldOpportunityDetails,
|
|
648
|
+
status,
|
|
625
649
|
};
|
|
626
650
|
});
|
|
627
651
|
}
|
package/lib/esm/mpc/index.js
CHANGED
|
@@ -11,7 +11,7 @@ import { PortalMpcError } from './errors';
|
|
|
11
11
|
import { sdkLogger } from '../logger';
|
|
12
12
|
import { BackupMethods, } from '../index';
|
|
13
13
|
import { generateTraceId } from '../shared/trace';
|
|
14
|
-
const WEB_SDK_VERSION = '3.14.0
|
|
14
|
+
const WEB_SDK_VERSION = '3.14.0';
|
|
15
15
|
class Mpc {
|
|
16
16
|
get ready() {
|
|
17
17
|
return this._ready;
|
|
@@ -1008,10 +1008,11 @@ class Mpc {
|
|
|
1008
1008
|
});
|
|
1009
1009
|
}
|
|
1010
1010
|
rpcRequest(data, options) {
|
|
1011
|
-
var _a, _b;
|
|
1012
1011
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1013
1012
|
const { timeoutMs = 30000, traceId } = options !== null && options !== void 0 ? options : {};
|
|
1014
|
-
const requestId =
|
|
1013
|
+
const requestId = typeof crypto !== 'undefined' && crypto.randomUUID
|
|
1014
|
+
? crypto.randomUUID()
|
|
1015
|
+
: `${Date.now()}-${Math.random()}`;
|
|
1015
1016
|
const resolvedTraceId = traceId !== null && traceId !== void 0 ? traceId : generateTraceId();
|
|
1016
1017
|
sdkLogger.debug('[Portal] rpcRequest', {
|
|
1017
1018
|
requestId,
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "Portal MPC Support for Web",
|
|
4
4
|
"author": "Portal Labs, Inc.",
|
|
5
5
|
"homepage": "https://portalhq.io/",
|
|
6
|
-
"version": "3.14.0
|
|
6
|
+
"version": "3.14.0",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"main": "lib/commonjs/index",
|
|
9
9
|
"module": "lib/esm/index",
|
|
@@ -58,6 +58,5 @@
|
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {
|
|
60
60
|
"@solana/web3.js": "^1.91.8"
|
|
61
|
-
}
|
|
62
|
-
"stableVersion": "3.13.1"
|
|
61
|
+
}
|
|
63
62
|
}
|
|
@@ -358,6 +358,39 @@ export default class LiFi implements ILiFi {
|
|
|
358
358
|
throw new LifiReportedError(msg)
|
|
359
359
|
}
|
|
360
360
|
|
|
361
|
+
let lifiTxHash = txHash
|
|
362
|
+
if (network.startsWith('eip155:') && o.evmRequestFn) {
|
|
363
|
+
try {
|
|
364
|
+
const userOpReceipt = await o.evmRequestFn(
|
|
365
|
+
'eth_getUserOperationReceipt',
|
|
366
|
+
[txHash],
|
|
367
|
+
network,
|
|
368
|
+
)
|
|
369
|
+
if (
|
|
370
|
+
userOpReceipt &&
|
|
371
|
+
typeof userOpReceipt === 'object' &&
|
|
372
|
+
'receipt' in userOpReceipt &&
|
|
373
|
+
userOpReceipt.receipt &&
|
|
374
|
+
typeof userOpReceipt.receipt === 'object' &&
|
|
375
|
+
'transactionHash' in userOpReceipt.receipt
|
|
376
|
+
) {
|
|
377
|
+
const bundleHash = (
|
|
378
|
+
userOpReceipt.receipt as { transactionHash?: string }
|
|
379
|
+
).transactionHash
|
|
380
|
+
if (bundleHash && typeof bundleHash === 'string') {
|
|
381
|
+
lifiTxHash = bundleHash
|
|
382
|
+
sdkLogger.debug(
|
|
383
|
+
`${LOG_PREFIX} Resolved AA bundle tx hash for LiFi: ${lifiTxHash}`,
|
|
384
|
+
)
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
} catch (error) {
|
|
388
|
+
sdkLogger.debug(
|
|
389
|
+
`${LOG_PREFIX} Could not resolve bundle hash (likely EOA tx), using original hash`,
|
|
390
|
+
)
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
361
394
|
const bridgeTool = statusBridgeFromStepTool(populated.tool)
|
|
362
395
|
const crossLike =
|
|
363
396
|
populated.type === 'cross' ||
|
|
@@ -376,7 +409,7 @@ export default class LiFi implements ILiFi {
|
|
|
376
409
|
const pollOpts = params.statusPoll ?? {}
|
|
377
410
|
const terminal = await this.pollStatus(
|
|
378
411
|
{
|
|
379
|
-
txHash,
|
|
412
|
+
txHash: lifiTxHash,
|
|
380
413
|
fromChain: params.fromChain,
|
|
381
414
|
toChain: params.toChain,
|
|
382
415
|
bridge: bridgeTool,
|
|
@@ -400,4 +400,137 @@ describe('YieldXyz high-level (deposit, withdraw, defaults)', () => {
|
|
|
400
400
|
expect(r.chain).toBe('eip155:1')
|
|
401
401
|
expect(r.token).toBe('ETH')
|
|
402
402
|
})
|
|
403
|
+
|
|
404
|
+
it('status=SUCCESS when no waitForConfirmation configured', async () => {
|
|
405
|
+
jest.spyOn(mpc, 'enterYieldXyzYield').mockResolvedValue(
|
|
406
|
+
enterResponseWithTxs([
|
|
407
|
+
{
|
|
408
|
+
id: 'tx1',
|
|
409
|
+
network: 'eip155:1',
|
|
410
|
+
unsignedTransaction: { to: '0x1' },
|
|
411
|
+
},
|
|
412
|
+
]),
|
|
413
|
+
)
|
|
414
|
+
jest.spyOn(mpc, 'trackYieldXyzTransaction').mockResolvedValue({})
|
|
415
|
+
|
|
416
|
+
const r = await yieldXyz.deposit({
|
|
417
|
+
yieldId: 'y',
|
|
418
|
+
amount: '1',
|
|
419
|
+
address: mockAddress,
|
|
420
|
+
})
|
|
421
|
+
|
|
422
|
+
expect(r.status).toBe('SUCCESS')
|
|
423
|
+
})
|
|
424
|
+
|
|
425
|
+
it('status=SUCCESS when all confirmations reach true', async () => {
|
|
426
|
+
const y = new YieldXyz({
|
|
427
|
+
mpc,
|
|
428
|
+
waitForConfirmation: jest.fn().mockResolvedValue(true),
|
|
429
|
+
})
|
|
430
|
+
y.setSignAndSendTransaction(jest.fn().mockResolvedValue('0xh'))
|
|
431
|
+
jest.spyOn(mpc, 'enterYieldXyzYield').mockResolvedValue(
|
|
432
|
+
enterResponseWithTxs([
|
|
433
|
+
{
|
|
434
|
+
id: 'tx1',
|
|
435
|
+
network: 'eip155:1',
|
|
436
|
+
unsignedTransaction: { to: '0x1' },
|
|
437
|
+
},
|
|
438
|
+
{
|
|
439
|
+
id: 'tx2',
|
|
440
|
+
network: 'eip155:1',
|
|
441
|
+
unsignedTransaction: { to: '0x2' },
|
|
442
|
+
},
|
|
443
|
+
]),
|
|
444
|
+
)
|
|
445
|
+
jest.spyOn(mpc, 'trackYieldXyzTransaction').mockResolvedValue({})
|
|
446
|
+
|
|
447
|
+
const r = await y.deposit({ yieldId: 'y', amount: '1', address: mockAddress })
|
|
448
|
+
|
|
449
|
+
expect(r.status).toBe('SUCCESS')
|
|
450
|
+
expect(r.hashes).toHaveLength(2)
|
|
451
|
+
})
|
|
452
|
+
|
|
453
|
+
it('status=FAILED when first confirmation returns false', async () => {
|
|
454
|
+
const y = new YieldXyz({
|
|
455
|
+
mpc,
|
|
456
|
+
waitForConfirmation: jest.fn().mockResolvedValue(false),
|
|
457
|
+
})
|
|
458
|
+
y.setSignAndSendTransaction(jest.fn().mockResolvedValue('0xh'))
|
|
459
|
+
jest.spyOn(mpc, 'enterYieldXyzYield').mockResolvedValue(
|
|
460
|
+
enterResponseWithTxs([
|
|
461
|
+
{
|
|
462
|
+
id: 'tx1',
|
|
463
|
+
network: 'eip155:1',
|
|
464
|
+
unsignedTransaction: { to: '0x1' },
|
|
465
|
+
},
|
|
466
|
+
]),
|
|
467
|
+
)
|
|
468
|
+
jest.spyOn(mpc, 'trackYieldXyzTransaction').mockResolvedValue({})
|
|
469
|
+
|
|
470
|
+
const r = await y.deposit({ yieldId: 'y', amount: '1', address: mockAddress })
|
|
471
|
+
|
|
472
|
+
expect(r.status).toBe('FAILED')
|
|
473
|
+
expect(r.hashes).toEqual(['0xh'])
|
|
474
|
+
})
|
|
475
|
+
|
|
476
|
+
it('status=PARTIAL_SUCCESS when first tx confirms but second fails', async () => {
|
|
477
|
+
const waiter = jest
|
|
478
|
+
.fn()
|
|
479
|
+
.mockResolvedValueOnce(true)
|
|
480
|
+
.mockResolvedValueOnce(false)
|
|
481
|
+
const y = new YieldXyz({
|
|
482
|
+
mpc,
|
|
483
|
+
waitForConfirmation: waiter,
|
|
484
|
+
})
|
|
485
|
+
const signer = jest
|
|
486
|
+
.fn()
|
|
487
|
+
.mockResolvedValueOnce('0xh1')
|
|
488
|
+
.mockResolvedValueOnce('0xh2')
|
|
489
|
+
y.setSignAndSendTransaction(signer)
|
|
490
|
+
jest.spyOn(mpc, 'enterYieldXyzYield').mockResolvedValue(
|
|
491
|
+
enterResponseWithTxs([
|
|
492
|
+
{
|
|
493
|
+
id: 'tx1',
|
|
494
|
+
network: 'eip155:1',
|
|
495
|
+
unsignedTransaction: { to: '0x1' },
|
|
496
|
+
},
|
|
497
|
+
{
|
|
498
|
+
id: 'tx2',
|
|
499
|
+
network: 'eip155:1',
|
|
500
|
+
unsignedTransaction: { to: '0x2' },
|
|
501
|
+
},
|
|
502
|
+
]),
|
|
503
|
+
)
|
|
504
|
+
jest.spyOn(mpc, 'trackYieldXyzTransaction').mockResolvedValue({})
|
|
505
|
+
|
|
506
|
+
const r = await y.deposit({ yieldId: 'y', amount: '1', address: mockAddress })
|
|
507
|
+
|
|
508
|
+
expect(r.status).toBe('PARTIAL_SUCCESS')
|
|
509
|
+
expect(r.hashes).toEqual(['0xh1', '0xh2'])
|
|
510
|
+
expect(signer).toHaveBeenCalledTimes(2)
|
|
511
|
+
expect(waiter).toHaveBeenCalledTimes(2)
|
|
512
|
+
})
|
|
513
|
+
|
|
514
|
+
it('withdraw: status=FAILED when confirmation returns false', async () => {
|
|
515
|
+
const y = new YieldXyz({
|
|
516
|
+
mpc,
|
|
517
|
+
waitForConfirmation: jest.fn().mockResolvedValue(false),
|
|
518
|
+
})
|
|
519
|
+
y.setSignAndSendTransaction(jest.fn().mockResolvedValue('0xh'))
|
|
520
|
+
jest.spyOn(mpc, 'exitYieldXyzYield').mockResolvedValue(
|
|
521
|
+
exitResponseWithTxs([
|
|
522
|
+
{
|
|
523
|
+
id: 'tx1',
|
|
524
|
+
network: 'eip155:1',
|
|
525
|
+
unsignedTransaction: { to: '0x1' },
|
|
526
|
+
},
|
|
527
|
+
]),
|
|
528
|
+
)
|
|
529
|
+
jest.spyOn(mpc, 'trackYieldXyzTransaction').mockResolvedValue({})
|
|
530
|
+
|
|
531
|
+
const r = await y.withdraw({ yieldId: 'y', amount: '1', address: mockAddress })
|
|
532
|
+
|
|
533
|
+
expect(r.status).toBe('FAILED')
|
|
534
|
+
expect(r.hashes).toEqual(['0xh'])
|
|
535
|
+
})
|
|
403
536
|
})
|
|
@@ -11,6 +11,7 @@ import type {
|
|
|
11
11
|
YieldDepositResult,
|
|
12
12
|
YieldSubmitOptions,
|
|
13
13
|
YieldSubmitProgress,
|
|
14
|
+
YieldSubmitResultStatus,
|
|
14
15
|
YieldWithdrawParams,
|
|
15
16
|
YieldWithdrawResult,
|
|
16
17
|
YieldXyzActionTransaction,
|
|
@@ -369,9 +370,10 @@ export default class YieldXyz {
|
|
|
369
370
|
: {}),
|
|
370
371
|
}
|
|
371
372
|
|
|
372
|
-
sdkLogger.info(`${LOG_PREFIX} deposit:
|
|
373
|
+
sdkLogger.info(`${LOG_PREFIX} deposit: complete`, {
|
|
373
374
|
hashes: result.hashes,
|
|
374
375
|
yieldId: result.yieldId,
|
|
376
|
+
status: result.status,
|
|
375
377
|
yieldOpportunityDetails: result.yieldOpportunityDetails,
|
|
376
378
|
})
|
|
377
379
|
return result
|
|
@@ -439,9 +441,10 @@ export default class YieldXyz {
|
|
|
439
441
|
: {}),
|
|
440
442
|
}
|
|
441
443
|
|
|
442
|
-
sdkLogger.info(`${LOG_PREFIX} withdraw:
|
|
444
|
+
sdkLogger.info(`${LOG_PREFIX} withdraw: complete`, {
|
|
443
445
|
hashes: result.hashes,
|
|
444
446
|
yieldId: result.yieldId,
|
|
447
|
+
status: result.status,
|
|
445
448
|
yieldOpportunityDetails: result.yieldOpportunityDetails,
|
|
446
449
|
})
|
|
447
450
|
return result
|
|
@@ -600,7 +603,7 @@ export default class YieldXyz {
|
|
|
600
603
|
): Promise<
|
|
601
604
|
Pick<
|
|
602
605
|
YieldDepositResult,
|
|
603
|
-
'hashes' | 'yieldId' | 'yieldOpportunityDetails'
|
|
606
|
+
'hashes' | 'yieldId' | 'yieldOpportunityDetails' | 'status'
|
|
604
607
|
>
|
|
605
608
|
> {
|
|
606
609
|
const transactions = this.extractTransactions(response)
|
|
@@ -617,6 +620,7 @@ export default class YieldXyz {
|
|
|
617
620
|
const total = transactions.length
|
|
618
621
|
const hashes: string[] = []
|
|
619
622
|
let confirmationsReached = 0
|
|
623
|
+
let confirmationsRequired = waitForConfirmation ? total : 0
|
|
620
624
|
|
|
621
625
|
for (let index = 0; index < transactions.length; index++) {
|
|
622
626
|
const tx = transactions[index]
|
|
@@ -838,17 +842,35 @@ export default class YieldXyz {
|
|
|
838
842
|
const yieldId = rawResponse?.yieldId ?? ''
|
|
839
843
|
const yieldOpportunityDetails = this.buildYieldOpportunityDetails(response)
|
|
840
844
|
|
|
845
|
+
// Determine status based on confirmation semantics from docs:
|
|
846
|
+
// - If no confirmations required (no waitForConfirmation): SUCCESS
|
|
847
|
+
// - If all required confirmations reached: SUCCESS
|
|
848
|
+
// - If some confirmations reached but not all: PARTIAL_SUCCESS
|
|
849
|
+
// - If confirmations required but zero reached: FAILED
|
|
850
|
+
let status: YieldSubmitResultStatus
|
|
851
|
+
if (confirmationsRequired === 0) {
|
|
852
|
+
status = 'SUCCESS'
|
|
853
|
+
} else if (confirmationsReached === confirmationsRequired) {
|
|
854
|
+
status = 'SUCCESS'
|
|
855
|
+
} else if (confirmationsReached > 0) {
|
|
856
|
+
status = 'PARTIAL_SUCCESS'
|
|
857
|
+
} else {
|
|
858
|
+
status = 'FAILED'
|
|
859
|
+
}
|
|
860
|
+
|
|
841
861
|
sdkLogger.info(`${LOG_PREFIX} ${method}: executeAndTrack complete`, {
|
|
842
862
|
yieldId,
|
|
843
863
|
hashCount: hashes.length,
|
|
844
|
-
confirmationsReached
|
|
845
|
-
|
|
864
|
+
confirmationsReached,
|
|
865
|
+
confirmationsRequired,
|
|
866
|
+
status,
|
|
846
867
|
})
|
|
847
868
|
|
|
848
869
|
return {
|
|
849
870
|
hashes,
|
|
850
871
|
yieldId,
|
|
851
872
|
yieldOpportunityDetails,
|
|
873
|
+
status,
|
|
852
874
|
}
|
|
853
875
|
}
|
|
854
876
|
}
|
package/src/mpc/index.ts
CHANGED
|
@@ -134,7 +134,7 @@ import {
|
|
|
134
134
|
} from '../../hypernative'
|
|
135
135
|
import { generateTraceId } from '../shared/trace'
|
|
136
136
|
|
|
137
|
-
const WEB_SDK_VERSION = '3.14.0
|
|
137
|
+
const WEB_SDK_VERSION = '3.14.0'
|
|
138
138
|
|
|
139
139
|
class Mpc {
|
|
140
140
|
public iframe?: HTMLIFrameElement
|
|
@@ -1288,7 +1288,9 @@ class Mpc {
|
|
|
1288
1288
|
): Promise<RpcProxyResponse> {
|
|
1289
1289
|
const { timeoutMs = 30_000, traceId } = options ?? {}
|
|
1290
1290
|
const requestId =
|
|
1291
|
-
crypto
|
|
1291
|
+
typeof crypto !== 'undefined' && crypto.randomUUID
|
|
1292
|
+
? crypto.randomUUID()
|
|
1293
|
+
: `${Date.now()}-${Math.random()}`
|
|
1292
1294
|
const resolvedTraceId = traceId ?? generateTraceId()
|
|
1293
1295
|
|
|
1294
1296
|
sdkLogger.debug('[Portal] rpcRequest', {
|
|
@@ -877,6 +877,11 @@ export type YieldDepositParams =
|
|
|
877
877
|
*/
|
|
878
878
|
export type YieldWithdrawParams = YieldDepositParams
|
|
879
879
|
|
|
880
|
+
/**
|
|
881
|
+
* Result status for deposit/withdraw operations
|
|
882
|
+
*/
|
|
883
|
+
export type YieldSubmitResultStatus = 'SUCCESS' | 'PARTIAL_SUCCESS' | 'FAILED'
|
|
884
|
+
|
|
880
885
|
/**
|
|
881
886
|
* Options for deposit/withdraw high-level methods (e.g. onProgress).
|
|
882
887
|
*/
|
|
@@ -933,6 +938,7 @@ export interface YieldDepositResult {
|
|
|
933
938
|
yieldId: string
|
|
934
939
|
chain?: string
|
|
935
940
|
token?: string
|
|
941
|
+
status: YieldSubmitResultStatus
|
|
936
942
|
yieldOpportunityDetails: {
|
|
937
943
|
yieldId: string
|
|
938
944
|
intent?: YieldXyzActionIntent
|
|
@@ -952,6 +958,7 @@ export interface YieldWithdrawResult {
|
|
|
952
958
|
yieldId: string
|
|
953
959
|
chain?: string
|
|
954
960
|
token?: string
|
|
961
|
+
status: YieldSubmitResultStatus
|
|
955
962
|
yieldOpportunityDetails: {
|
|
956
963
|
yieldId: string
|
|
957
964
|
intent?: YieldXyzActionIntent
|
|
@@ -14,9 +14,9 @@ export interface ZeroExQuoteRequest {
|
|
|
14
14
|
sellEntireBalance?: 'true' | 'false'
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
interface ZeroExQuoteSuccess {
|
|
18
18
|
/** When set (non-empty after trim), do not execute the quote (fail closed). */
|
|
19
|
-
error?:
|
|
19
|
+
error?: never
|
|
20
20
|
data: {
|
|
21
21
|
rawResponse: {
|
|
22
22
|
message?: string
|
|
@@ -96,6 +96,22 @@ export interface ZeroExQuoteResponse {
|
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
+
interface ZeroExQuoteError {
|
|
100
|
+
/** When set (non-empty after trim), do not execute the quote (fail closed). */
|
|
101
|
+
error: string
|
|
102
|
+
data?: never
|
|
103
|
+
metadata?: {
|
|
104
|
+
buyToken: string
|
|
105
|
+
sellToken: string
|
|
106
|
+
sellAmount: string
|
|
107
|
+
chainId: string
|
|
108
|
+
clientId: string
|
|
109
|
+
clientEip155Address: string
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export type ZeroExQuoteResponse = ZeroExQuoteSuccess | ZeroExQuoteError
|
|
114
|
+
|
|
99
115
|
export interface ZeroExSourcesRequest {
|
|
100
116
|
chainId: string
|
|
101
117
|
}
|