@0xsequence/relayer 0.35.10 → 0.36.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/0xsequence-relayer.cjs.dev.js +59 -19
- package/dist/0xsequence-relayer.cjs.prod.js +59 -19
- package/dist/0xsequence-relayer.esm.js +59 -19
- package/dist/declarations/src/index.d.ts +9 -1
- package/dist/declarations/src/local-relayer.d.ts +6 -3
- package/dist/declarations/src/provider-relayer.d.ts +6 -2
- package/dist/declarations/src/rpc-relayer/index.d.ts +6 -2
- package/dist/declarations/src/rpc-relayer/relayer.gen.d.ts +3 -1
- package/package.json +5 -5
- package/src/index.ts +31 -3
- package/src/local-relayer.ts +18 -4
- package/src/provider-relayer.ts +14 -3
- package/src/rpc-relayer/index.ts +32 -12
- package/src/rpc-relayer/relayer.gen.ts +6 -3
|
@@ -5,10 +5,10 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
5
5
|
var ethers = require('ethers');
|
|
6
6
|
var abi = require('@0xsequence/abi');
|
|
7
7
|
var transactions = require('@0xsequence/transactions');
|
|
8
|
+
var utils = require('@0xsequence/utils');
|
|
8
9
|
var providers = require('@ethersproject/providers');
|
|
9
10
|
var config = require('@0xsequence/config');
|
|
10
11
|
var utils$1 = require('ethers/lib/utils');
|
|
11
|
-
var utils = require('@0xsequence/utils');
|
|
12
12
|
var fetchPonyfill = require('fetch-ponyfill');
|
|
13
13
|
|
|
14
14
|
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
|
|
@@ -311,11 +311,24 @@ class LocalRelayer extends ProviderRelayer {
|
|
|
311
311
|
}));
|
|
312
312
|
}
|
|
313
313
|
|
|
314
|
-
async
|
|
315
|
-
return
|
|
314
|
+
async getFeeOptions(_config, _context, ..._transactions) {
|
|
315
|
+
return {
|
|
316
|
+
options: []
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
async gasRefundOptions(config, context, ...transactions) {
|
|
321
|
+
const {
|
|
322
|
+
options
|
|
323
|
+
} = await this.getFeeOptions(config, context, ...transactions);
|
|
324
|
+
return options;
|
|
316
325
|
}
|
|
317
326
|
|
|
318
|
-
async relay(signedTxs) {
|
|
327
|
+
async relay(signedTxs, quote) {
|
|
328
|
+
if (quote !== undefined) {
|
|
329
|
+
utils.logger.warn(`LocalRelayer doesn't accept fee quotes`);
|
|
330
|
+
}
|
|
331
|
+
|
|
319
332
|
if (!signedTxs.context.guestModule || signedTxs.context.guestModule.length !== 42) {
|
|
320
333
|
throw new Error('LocalRelayer requires the context.guestModule address');
|
|
321
334
|
}
|
|
@@ -339,7 +352,7 @@ class LocalRelayer extends ProviderRelayer {
|
|
|
339
352
|
}
|
|
340
353
|
|
|
341
354
|
/* eslint-disable */
|
|
342
|
-
// sequence-relayer v0.4.0
|
|
355
|
+
// sequence-relayer v0.4.0 4dca0b91c1531d1166ae2f7ebd8af571b0c0e43b
|
|
343
356
|
// --
|
|
344
357
|
// This file has been generated by https://github.com/webrpc/webrpc using gen/typescript
|
|
345
358
|
// Do not edit by hand. Update your webrpc schema and re-generate.
|
|
@@ -348,7 +361,7 @@ const WebRPCVersion = 'v1'; // Schema version of your RIDL schema
|
|
|
348
361
|
|
|
349
362
|
const WebRPCSchemaVersion = 'v0.4.0'; // Schema hash generated from your RIDL schema
|
|
350
363
|
|
|
351
|
-
const WebRPCSchemaHash = '
|
|
364
|
+
const WebRPCSchemaHash = '4dca0b91c1531d1166ae2f7ebd8af571b0c0e43b'; //
|
|
352
365
|
// Types
|
|
353
366
|
//
|
|
354
367
|
|
|
@@ -515,7 +528,8 @@ class Relayer {
|
|
|
515
528
|
return this.fetch(this.url('FeeOptions'), createHTTPRequest(args, headers)).then(res => {
|
|
516
529
|
return buildResponse(res).then(_data => {
|
|
517
530
|
return {
|
|
518
|
-
options: _data.options
|
|
531
|
+
options: _data.options,
|
|
532
|
+
quote: _data.quote
|
|
519
533
|
};
|
|
520
534
|
});
|
|
521
535
|
});
|
|
@@ -684,7 +698,7 @@ class RpcRelayer extends BaseRelayer {
|
|
|
684
698
|
return prevNonce === undefined ? modTxns : transactions.appendNonce(modTxns, prevNonce);
|
|
685
699
|
}
|
|
686
700
|
|
|
687
|
-
async
|
|
701
|
+
async getFeeOptions(config$1, context, ...transactions$1) {
|
|
688
702
|
// NOTE/TODO: for a given `service` the feeTokens will not change between execution, so we should memoize this value
|
|
689
703
|
// for a short-period of time, perhaps for 1 day or in memory. Perhaps one day we can make this happen automatically
|
|
690
704
|
// with http cache response for this endpoint and service-worker.. lots of approaches
|
|
@@ -692,7 +706,7 @@ class RpcRelayer extends BaseRelayer {
|
|
|
692
706
|
|
|
693
707
|
if (feeTokens.isFeeRequired) {
|
|
694
708
|
const symbols = feeTokens.tokens.map(token => token.symbol).join(', ');
|
|
695
|
-
utils.logger.info(`[rpc-relayer/
|
|
709
|
+
utils.logger.info(`[rpc-relayer/getFeeOptions] relayer fees are required, accepted tokens are ${symbols}`);
|
|
696
710
|
const wallet = config.addressOf(config$1, context);
|
|
697
711
|
let nonce = transactions.readSequenceNonce(...transactions$1);
|
|
698
712
|
|
|
@@ -701,7 +715,7 @@ class RpcRelayer extends BaseRelayer {
|
|
|
701
715
|
}
|
|
702
716
|
|
|
703
717
|
if (!this.provider) {
|
|
704
|
-
utils.logger.warn(`[rpc-relayer/
|
|
718
|
+
utils.logger.warn(`[rpc-relayer/getFeeOptions] provider not set, needed for stub signature`);
|
|
705
719
|
throw new Error('provider is not set');
|
|
706
720
|
}
|
|
707
721
|
|
|
@@ -718,20 +732,36 @@ class RpcRelayer extends BaseRelayer {
|
|
|
718
732
|
const walletInterface = new ethers.ethers.utils.Interface(abi.walletContracts.mainModule.abi);
|
|
719
733
|
const data = walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [transactions.sequenceTxAbiEncode(execute.transactions), execute.nonce, execute.signature]);
|
|
720
734
|
const {
|
|
721
|
-
options
|
|
735
|
+
options,
|
|
736
|
+
quote
|
|
722
737
|
} = await this.service.feeOptions({
|
|
723
738
|
wallet,
|
|
724
739
|
to,
|
|
725
740
|
data
|
|
726
741
|
});
|
|
727
|
-
utils.logger.info(`[rpc-relayer/
|
|
728
|
-
return
|
|
742
|
+
utils.logger.info(`[rpc-relayer/getFeeOptions] got refund options ${JSON.stringify(options)}`);
|
|
743
|
+
return {
|
|
744
|
+
options,
|
|
745
|
+
quote: {
|
|
746
|
+
_tag: 'FeeQuote',
|
|
747
|
+
_quote: quote
|
|
748
|
+
}
|
|
749
|
+
};
|
|
729
750
|
} else {
|
|
730
|
-
utils.logger.info(`[rpc-relayer/
|
|
731
|
-
return
|
|
751
|
+
utils.logger.info(`[rpc-relayer/getFeeOptions] relayer fees are not required`);
|
|
752
|
+
return {
|
|
753
|
+
options: []
|
|
754
|
+
};
|
|
732
755
|
}
|
|
733
756
|
}
|
|
734
757
|
|
|
758
|
+
async gasRefundOptions(config, context, ...transactions) {
|
|
759
|
+
const {
|
|
760
|
+
options
|
|
761
|
+
} = await this.getFeeOptions(config, context, ...transactions);
|
|
762
|
+
return options;
|
|
763
|
+
}
|
|
764
|
+
|
|
735
765
|
async getNonce(config$1, context, space) {
|
|
736
766
|
const addr = config.addressOf(config$1, context);
|
|
737
767
|
utils.logger.info(`[rpc-relayer/getNonce] get nonce for wallet ${addr} space: ${space}`);
|
|
@@ -746,8 +776,17 @@ class RpcRelayer extends BaseRelayer {
|
|
|
746
776
|
return nonce;
|
|
747
777
|
}
|
|
748
778
|
|
|
749
|
-
async relay(signedTxs) {
|
|
750
|
-
utils.logger.info(`[rpc-relayer/relay] relaying signed meta-transactions ${JSON.stringify(signedTxs)}`);
|
|
779
|
+
async relay(signedTxs, quote) {
|
|
780
|
+
utils.logger.info(`[rpc-relayer/relay] relaying signed meta-transactions ${JSON.stringify(signedTxs)} with quote ${JSON.stringify(quote)}`);
|
|
781
|
+
let typecheckedQuote;
|
|
782
|
+
|
|
783
|
+
if (quote !== undefined) {
|
|
784
|
+
if (typeof quote._quote === 'string') {
|
|
785
|
+
typecheckedQuote = quote._quote;
|
|
786
|
+
} else {
|
|
787
|
+
utils.logger.warn('[rpc-relayer/relay] ignoring invalid fee quote');
|
|
788
|
+
}
|
|
789
|
+
}
|
|
751
790
|
|
|
752
791
|
if (!this.provider) {
|
|
753
792
|
utils.logger.warn(`[rpc-relayer/relay] provider not set, failed relay`);
|
|
@@ -766,7 +805,8 @@ class RpcRelayer extends BaseRelayer {
|
|
|
766
805
|
walletAddress,
|
|
767
806
|
contract,
|
|
768
807
|
input
|
|
769
|
-
}
|
|
808
|
+
},
|
|
809
|
+
quote: typecheckedQuote
|
|
770
810
|
});
|
|
771
811
|
utils.logger.info(`[rpc-relayer/relay] got relay result ${JSON.stringify(metaTxn)}`);
|
|
772
812
|
return this.wait(metaTxn.txnHash);
|
|
@@ -807,7 +847,7 @@ class MetaTransactionResponseException {
|
|
|
807
847
|
}
|
|
808
848
|
|
|
809
849
|
function isRelayer(cand) {
|
|
810
|
-
return cand && cand.estimateGasLimits
|
|
850
|
+
return typeof cand === 'object' && typeof cand.simulate === 'function' && typeof cand.estimateGasLimits === 'function' && typeof cand.getFeeOptions === 'function' && typeof cand.gasRefundOptions === 'function' && typeof cand.getNonce === 'function' && typeof cand.relay === 'function' && typeof cand.wait === 'function';
|
|
811
851
|
}
|
|
812
852
|
|
|
813
853
|
exports.BaseRelayer = BaseRelayer;
|
|
@@ -5,10 +5,10 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
5
5
|
var ethers = require('ethers');
|
|
6
6
|
var abi = require('@0xsequence/abi');
|
|
7
7
|
var transactions = require('@0xsequence/transactions');
|
|
8
|
+
var utils = require('@0xsequence/utils');
|
|
8
9
|
var providers = require('@ethersproject/providers');
|
|
9
10
|
var config = require('@0xsequence/config');
|
|
10
11
|
var utils$1 = require('ethers/lib/utils');
|
|
11
|
-
var utils = require('@0xsequence/utils');
|
|
12
12
|
var fetchPonyfill = require('fetch-ponyfill');
|
|
13
13
|
|
|
14
14
|
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
|
|
@@ -311,11 +311,24 @@ class LocalRelayer extends ProviderRelayer {
|
|
|
311
311
|
}));
|
|
312
312
|
}
|
|
313
313
|
|
|
314
|
-
async
|
|
315
|
-
return
|
|
314
|
+
async getFeeOptions(_config, _context, ..._transactions) {
|
|
315
|
+
return {
|
|
316
|
+
options: []
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
async gasRefundOptions(config, context, ...transactions) {
|
|
321
|
+
const {
|
|
322
|
+
options
|
|
323
|
+
} = await this.getFeeOptions(config, context, ...transactions);
|
|
324
|
+
return options;
|
|
316
325
|
}
|
|
317
326
|
|
|
318
|
-
async relay(signedTxs) {
|
|
327
|
+
async relay(signedTxs, quote) {
|
|
328
|
+
if (quote !== undefined) {
|
|
329
|
+
utils.logger.warn(`LocalRelayer doesn't accept fee quotes`);
|
|
330
|
+
}
|
|
331
|
+
|
|
319
332
|
if (!signedTxs.context.guestModule || signedTxs.context.guestModule.length !== 42) {
|
|
320
333
|
throw new Error('LocalRelayer requires the context.guestModule address');
|
|
321
334
|
}
|
|
@@ -339,7 +352,7 @@ class LocalRelayer extends ProviderRelayer {
|
|
|
339
352
|
}
|
|
340
353
|
|
|
341
354
|
/* eslint-disable */
|
|
342
|
-
// sequence-relayer v0.4.0
|
|
355
|
+
// sequence-relayer v0.4.0 4dca0b91c1531d1166ae2f7ebd8af571b0c0e43b
|
|
343
356
|
// --
|
|
344
357
|
// This file has been generated by https://github.com/webrpc/webrpc using gen/typescript
|
|
345
358
|
// Do not edit by hand. Update your webrpc schema and re-generate.
|
|
@@ -348,7 +361,7 @@ const WebRPCVersion = 'v1'; // Schema version of your RIDL schema
|
|
|
348
361
|
|
|
349
362
|
const WebRPCSchemaVersion = 'v0.4.0'; // Schema hash generated from your RIDL schema
|
|
350
363
|
|
|
351
|
-
const WebRPCSchemaHash = '
|
|
364
|
+
const WebRPCSchemaHash = '4dca0b91c1531d1166ae2f7ebd8af571b0c0e43b'; //
|
|
352
365
|
// Types
|
|
353
366
|
//
|
|
354
367
|
|
|
@@ -515,7 +528,8 @@ class Relayer {
|
|
|
515
528
|
return this.fetch(this.url('FeeOptions'), createHTTPRequest(args, headers)).then(res => {
|
|
516
529
|
return buildResponse(res).then(_data => {
|
|
517
530
|
return {
|
|
518
|
-
options: _data.options
|
|
531
|
+
options: _data.options,
|
|
532
|
+
quote: _data.quote
|
|
519
533
|
};
|
|
520
534
|
});
|
|
521
535
|
});
|
|
@@ -684,7 +698,7 @@ class RpcRelayer extends BaseRelayer {
|
|
|
684
698
|
return prevNonce === undefined ? modTxns : transactions.appendNonce(modTxns, prevNonce);
|
|
685
699
|
}
|
|
686
700
|
|
|
687
|
-
async
|
|
701
|
+
async getFeeOptions(config$1, context, ...transactions$1) {
|
|
688
702
|
// NOTE/TODO: for a given `service` the feeTokens will not change between execution, so we should memoize this value
|
|
689
703
|
// for a short-period of time, perhaps for 1 day or in memory. Perhaps one day we can make this happen automatically
|
|
690
704
|
// with http cache response for this endpoint and service-worker.. lots of approaches
|
|
@@ -692,7 +706,7 @@ class RpcRelayer extends BaseRelayer {
|
|
|
692
706
|
|
|
693
707
|
if (feeTokens.isFeeRequired) {
|
|
694
708
|
const symbols = feeTokens.tokens.map(token => token.symbol).join(', ');
|
|
695
|
-
utils.logger.info(`[rpc-relayer/
|
|
709
|
+
utils.logger.info(`[rpc-relayer/getFeeOptions] relayer fees are required, accepted tokens are ${symbols}`);
|
|
696
710
|
const wallet = config.addressOf(config$1, context);
|
|
697
711
|
let nonce = transactions.readSequenceNonce(...transactions$1);
|
|
698
712
|
|
|
@@ -701,7 +715,7 @@ class RpcRelayer extends BaseRelayer {
|
|
|
701
715
|
}
|
|
702
716
|
|
|
703
717
|
if (!this.provider) {
|
|
704
|
-
utils.logger.warn(`[rpc-relayer/
|
|
718
|
+
utils.logger.warn(`[rpc-relayer/getFeeOptions] provider not set, needed for stub signature`);
|
|
705
719
|
throw new Error('provider is not set');
|
|
706
720
|
}
|
|
707
721
|
|
|
@@ -718,20 +732,36 @@ class RpcRelayer extends BaseRelayer {
|
|
|
718
732
|
const walletInterface = new ethers.ethers.utils.Interface(abi.walletContracts.mainModule.abi);
|
|
719
733
|
const data = walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [transactions.sequenceTxAbiEncode(execute.transactions), execute.nonce, execute.signature]);
|
|
720
734
|
const {
|
|
721
|
-
options
|
|
735
|
+
options,
|
|
736
|
+
quote
|
|
722
737
|
} = await this.service.feeOptions({
|
|
723
738
|
wallet,
|
|
724
739
|
to,
|
|
725
740
|
data
|
|
726
741
|
});
|
|
727
|
-
utils.logger.info(`[rpc-relayer/
|
|
728
|
-
return
|
|
742
|
+
utils.logger.info(`[rpc-relayer/getFeeOptions] got refund options ${JSON.stringify(options)}`);
|
|
743
|
+
return {
|
|
744
|
+
options,
|
|
745
|
+
quote: {
|
|
746
|
+
_tag: 'FeeQuote',
|
|
747
|
+
_quote: quote
|
|
748
|
+
}
|
|
749
|
+
};
|
|
729
750
|
} else {
|
|
730
|
-
utils.logger.info(`[rpc-relayer/
|
|
731
|
-
return
|
|
751
|
+
utils.logger.info(`[rpc-relayer/getFeeOptions] relayer fees are not required`);
|
|
752
|
+
return {
|
|
753
|
+
options: []
|
|
754
|
+
};
|
|
732
755
|
}
|
|
733
756
|
}
|
|
734
757
|
|
|
758
|
+
async gasRefundOptions(config, context, ...transactions) {
|
|
759
|
+
const {
|
|
760
|
+
options
|
|
761
|
+
} = await this.getFeeOptions(config, context, ...transactions);
|
|
762
|
+
return options;
|
|
763
|
+
}
|
|
764
|
+
|
|
735
765
|
async getNonce(config$1, context, space) {
|
|
736
766
|
const addr = config.addressOf(config$1, context);
|
|
737
767
|
utils.logger.info(`[rpc-relayer/getNonce] get nonce for wallet ${addr} space: ${space}`);
|
|
@@ -746,8 +776,17 @@ class RpcRelayer extends BaseRelayer {
|
|
|
746
776
|
return nonce;
|
|
747
777
|
}
|
|
748
778
|
|
|
749
|
-
async relay(signedTxs) {
|
|
750
|
-
utils.logger.info(`[rpc-relayer/relay] relaying signed meta-transactions ${JSON.stringify(signedTxs)}`);
|
|
779
|
+
async relay(signedTxs, quote) {
|
|
780
|
+
utils.logger.info(`[rpc-relayer/relay] relaying signed meta-transactions ${JSON.stringify(signedTxs)} with quote ${JSON.stringify(quote)}`);
|
|
781
|
+
let typecheckedQuote;
|
|
782
|
+
|
|
783
|
+
if (quote !== undefined) {
|
|
784
|
+
if (typeof quote._quote === 'string') {
|
|
785
|
+
typecheckedQuote = quote._quote;
|
|
786
|
+
} else {
|
|
787
|
+
utils.logger.warn('[rpc-relayer/relay] ignoring invalid fee quote');
|
|
788
|
+
}
|
|
789
|
+
}
|
|
751
790
|
|
|
752
791
|
if (!this.provider) {
|
|
753
792
|
utils.logger.warn(`[rpc-relayer/relay] provider not set, failed relay`);
|
|
@@ -766,7 +805,8 @@ class RpcRelayer extends BaseRelayer {
|
|
|
766
805
|
walletAddress,
|
|
767
806
|
contract,
|
|
768
807
|
input
|
|
769
|
-
}
|
|
808
|
+
},
|
|
809
|
+
quote: typecheckedQuote
|
|
770
810
|
});
|
|
771
811
|
utils.logger.info(`[rpc-relayer/relay] got relay result ${JSON.stringify(metaTxn)}`);
|
|
772
812
|
return this.wait(metaTxn.txnHash);
|
|
@@ -807,7 +847,7 @@ class MetaTransactionResponseException {
|
|
|
807
847
|
}
|
|
808
848
|
|
|
809
849
|
function isRelayer(cand) {
|
|
810
|
-
return cand && cand.estimateGasLimits
|
|
850
|
+
return typeof cand === 'object' && typeof cand.simulate === 'function' && typeof cand.estimateGasLimits === 'function' && typeof cand.getFeeOptions === 'function' && typeof cand.gasRefundOptions === 'function' && typeof cand.getNonce === 'function' && typeof cand.relay === 'function' && typeof cand.wait === 'function';
|
|
811
851
|
}
|
|
812
852
|
|
|
813
853
|
exports.BaseRelayer = BaseRelayer;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { ethers, providers, Signer } from 'ethers';
|
|
2
2
|
import { walletContracts } from '@0xsequence/abi';
|
|
3
3
|
import { sequenceTxAbiEncode, readSequenceNonce, encodeNonce, computeMetaTxnHash, MetaTransactionsType, appendNonce, decodeNonce } from '@0xsequence/transactions';
|
|
4
|
+
import { isBigNumberish, logger } from '@0xsequence/utils';
|
|
4
5
|
import { Provider } from '@ethersproject/providers';
|
|
5
6
|
import { imageHash, addressOf, encodeSignature, buildStubSignature } from '@0xsequence/config';
|
|
6
7
|
import { Interface } from 'ethers/lib/utils';
|
|
7
|
-
import { isBigNumberish, logger } from '@0xsequence/utils';
|
|
8
8
|
import fetchPonyfill from 'fetch-ponyfill';
|
|
9
9
|
|
|
10
10
|
function _extends() {
|
|
@@ -303,11 +303,24 @@ class LocalRelayer extends ProviderRelayer {
|
|
|
303
303
|
}));
|
|
304
304
|
}
|
|
305
305
|
|
|
306
|
-
async
|
|
307
|
-
return
|
|
306
|
+
async getFeeOptions(_config, _context, ..._transactions) {
|
|
307
|
+
return {
|
|
308
|
+
options: []
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
async gasRefundOptions(config, context, ...transactions) {
|
|
313
|
+
const {
|
|
314
|
+
options
|
|
315
|
+
} = await this.getFeeOptions(config, context, ...transactions);
|
|
316
|
+
return options;
|
|
308
317
|
}
|
|
309
318
|
|
|
310
|
-
async relay(signedTxs) {
|
|
319
|
+
async relay(signedTxs, quote) {
|
|
320
|
+
if (quote !== undefined) {
|
|
321
|
+
logger.warn(`LocalRelayer doesn't accept fee quotes`);
|
|
322
|
+
}
|
|
323
|
+
|
|
311
324
|
if (!signedTxs.context.guestModule || signedTxs.context.guestModule.length !== 42) {
|
|
312
325
|
throw new Error('LocalRelayer requires the context.guestModule address');
|
|
313
326
|
}
|
|
@@ -331,7 +344,7 @@ class LocalRelayer extends ProviderRelayer {
|
|
|
331
344
|
}
|
|
332
345
|
|
|
333
346
|
/* eslint-disable */
|
|
334
|
-
// sequence-relayer v0.4.0
|
|
347
|
+
// sequence-relayer v0.4.0 4dca0b91c1531d1166ae2f7ebd8af571b0c0e43b
|
|
335
348
|
// --
|
|
336
349
|
// This file has been generated by https://github.com/webrpc/webrpc using gen/typescript
|
|
337
350
|
// Do not edit by hand. Update your webrpc schema and re-generate.
|
|
@@ -340,7 +353,7 @@ const WebRPCVersion = 'v1'; // Schema version of your RIDL schema
|
|
|
340
353
|
|
|
341
354
|
const WebRPCSchemaVersion = 'v0.4.0'; // Schema hash generated from your RIDL schema
|
|
342
355
|
|
|
343
|
-
const WebRPCSchemaHash = '
|
|
356
|
+
const WebRPCSchemaHash = '4dca0b91c1531d1166ae2f7ebd8af571b0c0e43b'; //
|
|
344
357
|
// Types
|
|
345
358
|
//
|
|
346
359
|
|
|
@@ -507,7 +520,8 @@ class Relayer {
|
|
|
507
520
|
return this.fetch(this.url('FeeOptions'), createHTTPRequest(args, headers)).then(res => {
|
|
508
521
|
return buildResponse(res).then(_data => {
|
|
509
522
|
return {
|
|
510
|
-
options: _data.options
|
|
523
|
+
options: _data.options,
|
|
524
|
+
quote: _data.quote
|
|
511
525
|
};
|
|
512
526
|
});
|
|
513
527
|
});
|
|
@@ -676,7 +690,7 @@ class RpcRelayer extends BaseRelayer {
|
|
|
676
690
|
return prevNonce === undefined ? modTxns : appendNonce(modTxns, prevNonce);
|
|
677
691
|
}
|
|
678
692
|
|
|
679
|
-
async
|
|
693
|
+
async getFeeOptions(config, context, ...transactions) {
|
|
680
694
|
// NOTE/TODO: for a given `service` the feeTokens will not change between execution, so we should memoize this value
|
|
681
695
|
// for a short-period of time, perhaps for 1 day or in memory. Perhaps one day we can make this happen automatically
|
|
682
696
|
// with http cache response for this endpoint and service-worker.. lots of approaches
|
|
@@ -684,7 +698,7 @@ class RpcRelayer extends BaseRelayer {
|
|
|
684
698
|
|
|
685
699
|
if (feeTokens.isFeeRequired) {
|
|
686
700
|
const symbols = feeTokens.tokens.map(token => token.symbol).join(', ');
|
|
687
|
-
logger.info(`[rpc-relayer/
|
|
701
|
+
logger.info(`[rpc-relayer/getFeeOptions] relayer fees are required, accepted tokens are ${symbols}`);
|
|
688
702
|
const wallet = addressOf(config, context);
|
|
689
703
|
let nonce = readSequenceNonce(...transactions);
|
|
690
704
|
|
|
@@ -693,7 +707,7 @@ class RpcRelayer extends BaseRelayer {
|
|
|
693
707
|
}
|
|
694
708
|
|
|
695
709
|
if (!this.provider) {
|
|
696
|
-
logger.warn(`[rpc-relayer/
|
|
710
|
+
logger.warn(`[rpc-relayer/getFeeOptions] provider not set, needed for stub signature`);
|
|
697
711
|
throw new Error('provider is not set');
|
|
698
712
|
}
|
|
699
713
|
|
|
@@ -710,20 +724,36 @@ class RpcRelayer extends BaseRelayer {
|
|
|
710
724
|
const walletInterface = new ethers.utils.Interface(walletContracts.mainModule.abi);
|
|
711
725
|
const data = walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [sequenceTxAbiEncode(execute.transactions), execute.nonce, execute.signature]);
|
|
712
726
|
const {
|
|
713
|
-
options
|
|
727
|
+
options,
|
|
728
|
+
quote
|
|
714
729
|
} = await this.service.feeOptions({
|
|
715
730
|
wallet,
|
|
716
731
|
to,
|
|
717
732
|
data
|
|
718
733
|
});
|
|
719
|
-
logger.info(`[rpc-relayer/
|
|
720
|
-
return
|
|
734
|
+
logger.info(`[rpc-relayer/getFeeOptions] got refund options ${JSON.stringify(options)}`);
|
|
735
|
+
return {
|
|
736
|
+
options,
|
|
737
|
+
quote: {
|
|
738
|
+
_tag: 'FeeQuote',
|
|
739
|
+
_quote: quote
|
|
740
|
+
}
|
|
741
|
+
};
|
|
721
742
|
} else {
|
|
722
|
-
logger.info(`[rpc-relayer/
|
|
723
|
-
return
|
|
743
|
+
logger.info(`[rpc-relayer/getFeeOptions] relayer fees are not required`);
|
|
744
|
+
return {
|
|
745
|
+
options: []
|
|
746
|
+
};
|
|
724
747
|
}
|
|
725
748
|
}
|
|
726
749
|
|
|
750
|
+
async gasRefundOptions(config, context, ...transactions) {
|
|
751
|
+
const {
|
|
752
|
+
options
|
|
753
|
+
} = await this.getFeeOptions(config, context, ...transactions);
|
|
754
|
+
return options;
|
|
755
|
+
}
|
|
756
|
+
|
|
727
757
|
async getNonce(config, context, space) {
|
|
728
758
|
const addr = addressOf(config, context);
|
|
729
759
|
logger.info(`[rpc-relayer/getNonce] get nonce for wallet ${addr} space: ${space}`);
|
|
@@ -738,8 +768,17 @@ class RpcRelayer extends BaseRelayer {
|
|
|
738
768
|
return nonce;
|
|
739
769
|
}
|
|
740
770
|
|
|
741
|
-
async relay(signedTxs) {
|
|
742
|
-
logger.info(`[rpc-relayer/relay] relaying signed meta-transactions ${JSON.stringify(signedTxs)}`);
|
|
771
|
+
async relay(signedTxs, quote) {
|
|
772
|
+
logger.info(`[rpc-relayer/relay] relaying signed meta-transactions ${JSON.stringify(signedTxs)} with quote ${JSON.stringify(quote)}`);
|
|
773
|
+
let typecheckedQuote;
|
|
774
|
+
|
|
775
|
+
if (quote !== undefined) {
|
|
776
|
+
if (typeof quote._quote === 'string') {
|
|
777
|
+
typecheckedQuote = quote._quote;
|
|
778
|
+
} else {
|
|
779
|
+
logger.warn('[rpc-relayer/relay] ignoring invalid fee quote');
|
|
780
|
+
}
|
|
781
|
+
}
|
|
743
782
|
|
|
744
783
|
if (!this.provider) {
|
|
745
784
|
logger.warn(`[rpc-relayer/relay] provider not set, failed relay`);
|
|
@@ -758,7 +797,8 @@ class RpcRelayer extends BaseRelayer {
|
|
|
758
797
|
walletAddress,
|
|
759
798
|
contract,
|
|
760
799
|
input
|
|
761
|
-
}
|
|
800
|
+
},
|
|
801
|
+
quote: typecheckedQuote
|
|
762
802
|
});
|
|
763
803
|
logger.info(`[rpc-relayer/relay] got relay result ${JSON.stringify(metaTxn)}`);
|
|
764
804
|
return this.wait(metaTxn.txnHash);
|
|
@@ -799,7 +839,7 @@ class MetaTransactionResponseException {
|
|
|
799
839
|
}
|
|
800
840
|
|
|
801
841
|
function isRelayer(cand) {
|
|
802
|
-
return cand && cand.estimateGasLimits
|
|
842
|
+
return typeof cand === 'object' && typeof cand.simulate === 'function' && typeof cand.estimateGasLimits === 'function' && typeof cand.getFeeOptions === 'function' && typeof cand.gasRefundOptions === 'function' && typeof cand.getNonce === 'function' && typeof cand.relay === 'function' && typeof cand.wait === 'function';
|
|
803
843
|
}
|
|
804
844
|
|
|
805
845
|
export { BaseRelayer, BaseRelayerDefaults, LocalRelayer, ProviderRelayer, ProviderRelayerDefaults, RpcRelayer, relayer_gen as RpcRelayerProto, isBaseRelayerOptions, isLocalRelayerOptions, isProviderRelayerOptions, isRelayer, isRpcRelayerOptions, relayer_gen as proto };
|
|
@@ -6,9 +6,13 @@ import { proto } from './rpc-relayer';
|
|
|
6
6
|
export interface Relayer {
|
|
7
7
|
simulate(wallet: string, ...transactions: Transaction[]): Promise<SimulateResult[]>;
|
|
8
8
|
estimateGasLimits(config: WalletConfig, context: WalletContext, ...transactions: Transaction[]): Promise<Transaction[]>;
|
|
9
|
+
getFeeOptions(config: WalletConfig, context: WalletContext, ...transactions: Transaction[]): Promise<{
|
|
10
|
+
options: FeeOption[];
|
|
11
|
+
quote?: FeeQuote;
|
|
12
|
+
}>;
|
|
9
13
|
gasRefundOptions(config: WalletConfig, context: WalletContext, ...transactions: Transaction[]): Promise<FeeOption[]>;
|
|
10
14
|
getNonce(config: WalletConfig, context: WalletContext, space?: ethers.BigNumberish, blockTag?: providers.BlockTag): Promise<ethers.BigNumberish>;
|
|
11
|
-
relay(signedTxs: SignedTransactions): Promise<providers.TransactionResponse>;
|
|
15
|
+
relay(signedTxs: SignedTransactions, quote?: FeeQuote): Promise<providers.TransactionResponse>;
|
|
12
16
|
wait(metaTxnId: string | SignedTransactions, timeout: number): Promise<providers.TransactionResponse>;
|
|
13
17
|
}
|
|
14
18
|
export * from './local-relayer';
|
|
@@ -18,4 +22,8 @@ export * from './rpc-relayer';
|
|
|
18
22
|
export { proto as RpcRelayerProto } from './rpc-relayer';
|
|
19
23
|
export declare type SimulateResult = proto.SimulateResult;
|
|
20
24
|
export declare type FeeOption = proto.FeeOption;
|
|
25
|
+
export interface FeeQuote {
|
|
26
|
+
_tag: 'FeeQuote';
|
|
27
|
+
_quote: unknown;
|
|
28
|
+
}
|
|
21
29
|
export declare function isRelayer(cand: any): cand is Relayer;
|
|
@@ -3,7 +3,7 @@ import { Signer as AbstractSigner } from 'ethers';
|
|
|
3
3
|
import { SignedTransactions, Transaction } from '@0xsequence/transactions';
|
|
4
4
|
import { WalletContext } from '@0xsequence/network';
|
|
5
5
|
import { WalletConfig } from '@0xsequence/config';
|
|
6
|
-
import { FeeOption, Relayer } from '.';
|
|
6
|
+
import { FeeOption, FeeQuote, Relayer } from '.';
|
|
7
7
|
import { ProviderRelayer, ProviderRelayerOptions } from './provider-relayer';
|
|
8
8
|
export declare type LocalRelayerOptions = Omit<ProviderRelayerOptions, "provider"> & {
|
|
9
9
|
signer: AbstractSigner;
|
|
@@ -13,6 +13,9 @@ export declare class LocalRelayer extends ProviderRelayer implements Relayer {
|
|
|
13
13
|
private signer;
|
|
14
14
|
constructor(options: LocalRelayerOptions | AbstractSigner);
|
|
15
15
|
deployWallet(config: WalletConfig, context: WalletContext): Promise<TransactionResponse>;
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
getFeeOptions(_config: WalletConfig, _context: WalletContext, ..._transactions: Transaction[]): Promise<{
|
|
17
|
+
options: FeeOption[];
|
|
18
|
+
}>;
|
|
19
|
+
gasRefundOptions(config: WalletConfig, context: WalletContext, ...transactions: Transaction[]): Promise<FeeOption[]>;
|
|
20
|
+
relay(signedTxs: SignedTransactions, quote?: FeeQuote): Promise<TransactionResponse>;
|
|
18
21
|
}
|
|
@@ -4,7 +4,7 @@ import { SignedTransactions, Transaction } from '@0xsequence/transactions';
|
|
|
4
4
|
import { WalletContext } from '@0xsequence/network';
|
|
5
5
|
import { WalletConfig } from '@0xsequence/config';
|
|
6
6
|
import { BaseRelayer, BaseRelayerOptions } from './base-relayer';
|
|
7
|
-
import { FeeOption, Relayer, SimulateResult } from '.';
|
|
7
|
+
import { FeeOption, FeeQuote, Relayer, SimulateResult } from '.';
|
|
8
8
|
import { Optionals, Mask } from '@0xsequence/utils';
|
|
9
9
|
export interface ProviderRelayerOptions extends BaseRelayerOptions {
|
|
10
10
|
provider: Provider;
|
|
@@ -20,8 +20,12 @@ export declare abstract class ProviderRelayer extends BaseRelayer implements Rel
|
|
|
20
20
|
deltaBlocksLog: number;
|
|
21
21
|
fromBlockLog: number;
|
|
22
22
|
constructor(options: ProviderRelayerOptions);
|
|
23
|
+
abstract getFeeOptions(config: WalletConfig, context: WalletContext, ...transactions: Transaction[]): Promise<{
|
|
24
|
+
options: FeeOption[];
|
|
25
|
+
quote?: FeeQuote;
|
|
26
|
+
}>;
|
|
23
27
|
abstract gasRefundOptions(config: WalletConfig, context: WalletContext, ...transactions: Transaction[]): Promise<FeeOption[]>;
|
|
24
|
-
abstract relay(signedTxs: SignedTransactions): Promise<TransactionResponse>;
|
|
28
|
+
abstract relay(signedTxs: SignedTransactions, quote?: FeeQuote): Promise<TransactionResponse>;
|
|
25
29
|
simulate(wallet: string, ...transactions: Transaction[]): Promise<SimulateResult[]>;
|
|
26
30
|
estimateGasLimits(config: WalletConfig, context: WalletContext, ...transactions: Transaction[]): Promise<Transaction[]>;
|
|
27
31
|
getNonce(config: WalletConfig, context: WalletContext, space?: ethers.BigNumberish, blockTag?: BlockTag): Promise<ethers.BigNumberish>;
|
|
@@ -2,7 +2,7 @@ import { TransactionResponse } from '@ethersproject/providers';
|
|
|
2
2
|
import { ethers } from 'ethers';
|
|
3
3
|
import { Transaction, SignedTransactions } from '@0xsequence/transactions';
|
|
4
4
|
import { BaseRelayer, BaseRelayerOptions } from '../base-relayer';
|
|
5
|
-
import { FeeOption, Relayer, SimulateResult } from '..';
|
|
5
|
+
import { FeeOption, FeeQuote, Relayer, SimulateResult } from '..';
|
|
6
6
|
import { WalletContext } from '@0xsequence/network';
|
|
7
7
|
import { WalletConfig } from '@0xsequence/config';
|
|
8
8
|
import * as proto from './relayer.gen';
|
|
@@ -17,8 +17,12 @@ export declare class RpcRelayer extends BaseRelayer implements Relayer {
|
|
|
17
17
|
waitReceipt(metaTxnHash: string | SignedTransactions, wait?: number): Promise<proto.GetMetaTxnReceiptReturn>;
|
|
18
18
|
simulate(wallet: string, ...transactions: Transaction[]): Promise<SimulateResult[]>;
|
|
19
19
|
estimateGasLimits(config: WalletConfig, context: WalletContext, ...transactions: Transaction[]): Promise<Transaction[]>;
|
|
20
|
+
getFeeOptions(config: WalletConfig, context: WalletContext, ...transactions: Transaction[]): Promise<{
|
|
21
|
+
options: FeeOption[];
|
|
22
|
+
quote?: FeeQuote;
|
|
23
|
+
}>;
|
|
20
24
|
gasRefundOptions(config: WalletConfig, context: WalletContext, ...transactions: Transaction[]): Promise<FeeOption[]>;
|
|
21
25
|
getNonce(config: WalletConfig, context: WalletContext, space?: ethers.BigNumberish): Promise<ethers.BigNumberish>;
|
|
22
|
-
relay(signedTxs: SignedTransactions): Promise<TransactionResponse>;
|
|
26
|
+
relay(signedTxs: SignedTransactions, quote?: FeeQuote): Promise<TransactionResponse>;
|
|
23
27
|
wait(metaTxnHash: string | SignedTransactions, wait?: number): Promise<TransactionResponse>;
|
|
24
28
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export declare const WebRPCVersion = "v1";
|
|
2
2
|
export declare const WebRPCSchemaVersion = "v0.4.0";
|
|
3
|
-
export declare const WebRPCSchemaHash = "
|
|
3
|
+
export declare const WebRPCSchemaHash = "4dca0b91c1531d1166ae2f7ebd8af571b0c0e43b";
|
|
4
4
|
export declare enum ETHTxnStatus {
|
|
5
5
|
UNKNOWN = "UNKNOWN",
|
|
6
6
|
DROPPED = "DROPPED",
|
|
@@ -231,6 +231,7 @@ export interface GetChainIDReturn {
|
|
|
231
231
|
}
|
|
232
232
|
export interface SendMetaTxnArgs {
|
|
233
233
|
call: MetaTxn;
|
|
234
|
+
quote?: string;
|
|
234
235
|
}
|
|
235
236
|
export interface SendMetaTxnReturn {
|
|
236
237
|
status: boolean;
|
|
@@ -277,6 +278,7 @@ export interface FeeOptionsArgs {
|
|
|
277
278
|
}
|
|
278
279
|
export interface FeeOptionsReturn {
|
|
279
280
|
options: Array<FeeOption>;
|
|
281
|
+
quote?: string;
|
|
280
282
|
}
|
|
281
283
|
export interface GetMetaTxnNetworkFeeOptionsArgs {
|
|
282
284
|
walletConfig: WalletConfig;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@0xsequence/relayer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.36.1",
|
|
4
4
|
"description": "relayer sub-package for Sequence",
|
|
5
5
|
"repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/relayer",
|
|
6
6
|
"source": "src/index.ts",
|
|
@@ -17,10 +17,10 @@
|
|
|
17
17
|
"typecheck": "tsc --noEmit"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@0xsequence/abi": "^0.
|
|
21
|
-
"@0xsequence/config": "^0.
|
|
22
|
-
"@0xsequence/transactions": "^0.
|
|
23
|
-
"@0xsequence/utils": "^0.
|
|
20
|
+
"@0xsequence/abi": "^0.36.1",
|
|
21
|
+
"@0xsequence/config": "^0.36.1",
|
|
22
|
+
"@0xsequence/transactions": "^0.36.1",
|
|
23
|
+
"@0xsequence/utils": "^0.36.1",
|
|
24
24
|
"@ethersproject/providers": "^5.5.1",
|
|
25
25
|
"ethers": "^5.5.2",
|
|
26
26
|
"fetch-ponyfill": "^7.1.0"
|
package/src/index.ts
CHANGED
|
@@ -16,6 +16,14 @@ export interface Relayer {
|
|
|
16
16
|
...transactions: Transaction[]
|
|
17
17
|
): Promise<Transaction[]>
|
|
18
18
|
|
|
19
|
+
// getFeeOptions returns the fee options that the relayer will accept as payment.
|
|
20
|
+
// If a quote is returned, it may be passed back to the relayer for dispatch.
|
|
21
|
+
getFeeOptions(
|
|
22
|
+
config: WalletConfig,
|
|
23
|
+
context: WalletContext,
|
|
24
|
+
...transactions: Transaction[]
|
|
25
|
+
): Promise<{ options: FeeOption[], quote?: FeeQuote }>
|
|
26
|
+
|
|
19
27
|
// gasRefundOptions returns the transactions which can be included to refund a
|
|
20
28
|
// relayer for submitting your transaction to a network.
|
|
21
29
|
gasRefundOptions(
|
|
@@ -30,7 +38,8 @@ export interface Relayer {
|
|
|
30
38
|
getNonce(config: WalletConfig, context: WalletContext, space?: ethers.BigNumberish, blockTag?: providers.BlockTag): Promise<ethers.BigNumberish>
|
|
31
39
|
|
|
32
40
|
// relayer will submit the transaction(s) to the network and return the transaction response.
|
|
33
|
-
|
|
41
|
+
// The quote should be the one returned from getFeeOptions, if any.
|
|
42
|
+
relay(signedTxs: SignedTransactions, quote?: FeeQuote): Promise<providers.TransactionResponse>
|
|
34
43
|
|
|
35
44
|
// wait for transaction confirmation
|
|
36
45
|
wait(metaTxnId: string | SignedTransactions, timeout: number): Promise<providers.TransactionResponse>
|
|
@@ -44,7 +53,26 @@ export { proto as RpcRelayerProto } from './rpc-relayer'
|
|
|
44
53
|
export type SimulateResult = proto.SimulateResult
|
|
45
54
|
export type FeeOption = proto.FeeOption
|
|
46
55
|
|
|
56
|
+
// A fee quote is simply an opaque value that can be obtained via Relayer.getFeeOptions(), and
|
|
57
|
+
// returned back to the same relayer via Relayer.relay(). Fee quotes should be treated as an
|
|
58
|
+
// implementation detail of the relayer that produces them.
|
|
59
|
+
//
|
|
60
|
+
// This interface exists for type-safety purposes to protect against passing non-FeeQuotes to
|
|
61
|
+
// Relayer.relay(), or any other functions that call it indirectly (e.g. Account.sendTransaction).
|
|
62
|
+
export interface FeeQuote {
|
|
63
|
+
_tag: 'FeeQuote'
|
|
64
|
+
_quote: unknown
|
|
65
|
+
}
|
|
66
|
+
|
|
47
67
|
export function isRelayer(cand: any): cand is Relayer {
|
|
48
|
-
return
|
|
49
|
-
cand
|
|
68
|
+
return (
|
|
69
|
+
typeof cand === 'object' &&
|
|
70
|
+
typeof cand.simulate === 'function' &&
|
|
71
|
+
typeof cand.estimateGasLimits === 'function' &&
|
|
72
|
+
typeof cand.getFeeOptions === 'function' &&
|
|
73
|
+
typeof cand.gasRefundOptions === 'function' &&
|
|
74
|
+
typeof cand.getNonce === 'function' &&
|
|
75
|
+
typeof cand.relay === 'function' &&
|
|
76
|
+
typeof cand.wait === 'function'
|
|
77
|
+
)
|
|
50
78
|
}
|
package/src/local-relayer.ts
CHANGED
|
@@ -4,7 +4,8 @@ import { walletContracts } from '@0xsequence/abi'
|
|
|
4
4
|
import { SignedTransactions, Transaction, sequenceTxAbiEncode } from '@0xsequence/transactions'
|
|
5
5
|
import { WalletContext } from '@0xsequence/network'
|
|
6
6
|
import { WalletConfig } from '@0xsequence/config'
|
|
7
|
-
import {
|
|
7
|
+
import { logger } from '@0xsequence/utils'
|
|
8
|
+
import { FeeOption, FeeQuote, Relayer } from '.'
|
|
8
9
|
import { ProviderRelayer, ProviderRelayerOptions } from './provider-relayer'
|
|
9
10
|
|
|
10
11
|
export type LocalRelayerOptions = Omit<ProviderRelayerOptions, "provider"> & {
|
|
@@ -34,15 +35,28 @@ export class LocalRelayer extends ProviderRelayer implements Relayer {
|
|
|
34
35
|
return this.signer.sendTransaction({ ...walletDeployTxn, gasLimit: ethers.constants.Two.pow(17) } )
|
|
35
36
|
}
|
|
36
37
|
|
|
37
|
-
async
|
|
38
|
+
async getFeeOptions(
|
|
38
39
|
_config: WalletConfig,
|
|
39
40
|
_context: WalletContext,
|
|
40
41
|
..._transactions: Transaction[]
|
|
42
|
+
): Promise<{ options: FeeOption[] }> {
|
|
43
|
+
return { options: [] }
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async gasRefundOptions(
|
|
47
|
+
config: WalletConfig,
|
|
48
|
+
context: WalletContext,
|
|
49
|
+
...transactions: Transaction[]
|
|
41
50
|
): Promise<FeeOption[]> {
|
|
42
|
-
|
|
51
|
+
const { options } = await this.getFeeOptions(config, context, ...transactions)
|
|
52
|
+
return options
|
|
43
53
|
}
|
|
44
54
|
|
|
45
|
-
async relay(signedTxs: SignedTransactions): Promise<TransactionResponse> {
|
|
55
|
+
async relay(signedTxs: SignedTransactions, quote?: FeeQuote): Promise<TransactionResponse> {
|
|
56
|
+
if (quote !== undefined) {
|
|
57
|
+
logger.warn(`LocalRelayer doesn't accept fee quotes`)
|
|
58
|
+
}
|
|
59
|
+
|
|
46
60
|
if (!signedTxs.context.guestModule || signedTxs.context.guestModule.length !== 42) {
|
|
47
61
|
throw new Error('LocalRelayer requires the context.guestModule address')
|
|
48
62
|
}
|
package/src/provider-relayer.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { computeMetaTxnHash, encodeNonce, SignedTransactions, Transaction } from
|
|
|
5
5
|
import { WalletContext } from '@0xsequence/network'
|
|
6
6
|
import { WalletConfig, addressOf } from '@0xsequence/config'
|
|
7
7
|
import { BaseRelayer, BaseRelayerOptions } from './base-relayer'
|
|
8
|
-
import { FeeOption, Relayer, SimulateResult } from '.'
|
|
8
|
+
import { FeeOption, FeeQuote, Relayer, SimulateResult } from '.'
|
|
9
9
|
import { Optionals, Mask } from '@0xsequence/utils'
|
|
10
10
|
|
|
11
11
|
const DEFAULT_GAS_LIMIT = ethers.BigNumber.from(800000)
|
|
@@ -42,8 +42,19 @@ export abstract class ProviderRelayer extends BaseRelayer implements Relayer {
|
|
|
42
42
|
this.fromBlockLog = opts.fromBlockLog
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
abstract
|
|
46
|
-
|
|
45
|
+
abstract getFeeOptions(
|
|
46
|
+
config: WalletConfig,
|
|
47
|
+
context: WalletContext,
|
|
48
|
+
...transactions: Transaction[]
|
|
49
|
+
): Promise<{ options: FeeOption[], quote?: FeeQuote }>
|
|
50
|
+
|
|
51
|
+
abstract gasRefundOptions(
|
|
52
|
+
config: WalletConfig,
|
|
53
|
+
context: WalletContext,
|
|
54
|
+
...transactions: Transaction[]
|
|
55
|
+
): Promise<FeeOption[]>
|
|
56
|
+
|
|
57
|
+
abstract relay(signedTxs: SignedTransactions, quote?: FeeQuote): Promise<TransactionResponse>
|
|
47
58
|
|
|
48
59
|
async simulate(wallet: string, ...transactions: Transaction[]): Promise<SimulateResult[]> {
|
|
49
60
|
return (await Promise.all(transactions.map(async tx => {
|
package/src/rpc-relayer/index.ts
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
decodeNonce
|
|
14
14
|
} from '@0xsequence/transactions'
|
|
15
15
|
import { BaseRelayer, BaseRelayerOptions } from '../base-relayer'
|
|
16
|
-
import { FeeOption, Relayer, SimulateResult } from '..'
|
|
16
|
+
import { FeeOption, FeeQuote, Relayer, SimulateResult } from '..'
|
|
17
17
|
import { WalletContext } from '@0xsequence/network'
|
|
18
18
|
import { WalletConfig, addressOf, buildStubSignature } from '@0xsequence/config'
|
|
19
19
|
import { logger } from '@0xsequence/utils'
|
|
@@ -113,7 +113,11 @@ export class RpcRelayer extends BaseRelayer implements Relayer {
|
|
|
113
113
|
return prevNonce === undefined ? modTxns : appendNonce(modTxns, prevNonce)
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
-
async
|
|
116
|
+
async getFeeOptions(
|
|
117
|
+
config: WalletConfig,
|
|
118
|
+
context: WalletContext,
|
|
119
|
+
...transactions: Transaction[]
|
|
120
|
+
): Promise<{ options: FeeOption[]; quote?: FeeQuote }> {
|
|
117
121
|
// NOTE/TODO: for a given `service` the feeTokens will not change between execution, so we should memoize this value
|
|
118
122
|
// for a short-period of time, perhaps for 1 day or in memory. Perhaps one day we can make this happen automatically
|
|
119
123
|
// with http cache response for this endpoint and service-worker.. lots of approaches
|
|
@@ -121,7 +125,7 @@ export class RpcRelayer extends BaseRelayer implements Relayer {
|
|
|
121
125
|
|
|
122
126
|
if (feeTokens.isFeeRequired) {
|
|
123
127
|
const symbols = feeTokens.tokens.map(token => token.symbol).join(', ')
|
|
124
|
-
logger.info(`[rpc-relayer/
|
|
128
|
+
logger.info(`[rpc-relayer/getFeeOptions] relayer fees are required, accepted tokens are ${symbols}`)
|
|
125
129
|
|
|
126
130
|
const wallet = addressOf(config, context)
|
|
127
131
|
|
|
@@ -131,7 +135,7 @@ export class RpcRelayer extends BaseRelayer implements Relayer {
|
|
|
131
135
|
}
|
|
132
136
|
|
|
133
137
|
if (!this.provider) {
|
|
134
|
-
logger.warn(`[rpc-relayer/
|
|
138
|
+
logger.warn(`[rpc-relayer/getFeeOptions] provider not set, needed for stub signature`)
|
|
135
139
|
throw new Error('provider is not set')
|
|
136
140
|
}
|
|
137
141
|
|
|
@@ -150,16 +154,21 @@ export class RpcRelayer extends BaseRelayer implements Relayer {
|
|
|
150
154
|
execute.signature
|
|
151
155
|
])
|
|
152
156
|
|
|
153
|
-
const { options } = await this.service.feeOptions({ wallet, to, data })
|
|
157
|
+
const { options, quote } = await this.service.feeOptions({ wallet, to, data })
|
|
154
158
|
|
|
155
|
-
logger.info(`[rpc-relayer/
|
|
156
|
-
return options
|
|
159
|
+
logger.info(`[rpc-relayer/getFeeOptions] got refund options ${JSON.stringify(options)}`)
|
|
160
|
+
return { options, quote: { _tag: 'FeeQuote', _quote: quote } }
|
|
157
161
|
} else {
|
|
158
|
-
logger.info(`[rpc-relayer/
|
|
159
|
-
return []
|
|
162
|
+
logger.info(`[rpc-relayer/getFeeOptions] relayer fees are not required`)
|
|
163
|
+
return { options: [] }
|
|
160
164
|
}
|
|
161
165
|
}
|
|
162
166
|
|
|
167
|
+
async gasRefundOptions(config: WalletConfig, context: WalletContext, ...transactions: Transaction[]): Promise<FeeOption[]> {
|
|
168
|
+
const { options } = await this.getFeeOptions(config, context, ...transactions)
|
|
169
|
+
return options
|
|
170
|
+
}
|
|
171
|
+
|
|
163
172
|
async getNonce(config: WalletConfig, context: WalletContext, space?: ethers.BigNumberish): Promise<ethers.BigNumberish> {
|
|
164
173
|
const addr = addressOf(config, context)
|
|
165
174
|
logger.info(`[rpc-relayer/getNonce] get nonce for wallet ${addr} space: ${space}`)
|
|
@@ -171,8 +180,19 @@ export class RpcRelayer extends BaseRelayer implements Relayer {
|
|
|
171
180
|
return nonce
|
|
172
181
|
}
|
|
173
182
|
|
|
174
|
-
async relay(signedTxs: SignedTransactions): Promise<TransactionResponse> {
|
|
175
|
-
logger.info(
|
|
183
|
+
async relay(signedTxs: SignedTransactions, quote?: FeeQuote): Promise<TransactionResponse> {
|
|
184
|
+
logger.info(
|
|
185
|
+
`[rpc-relayer/relay] relaying signed meta-transactions ${JSON.stringify(signedTxs)} with quote ${JSON.stringify(quote)}`
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
let typecheckedQuote: string | undefined
|
|
189
|
+
if (quote !== undefined) {
|
|
190
|
+
if (typeof quote._quote === 'string') {
|
|
191
|
+
typecheckedQuote = quote._quote
|
|
192
|
+
} else {
|
|
193
|
+
logger.warn('[rpc-relayer/relay] ignoring invalid fee quote')
|
|
194
|
+
}
|
|
195
|
+
}
|
|
176
196
|
|
|
177
197
|
if (!this.provider) {
|
|
178
198
|
logger.warn(`[rpc-relayer/relay] provider not set, failed relay`)
|
|
@@ -189,7 +209,7 @@ export class RpcRelayer extends BaseRelayer implements Relayer {
|
|
|
189
209
|
execute.signature
|
|
190
210
|
])
|
|
191
211
|
|
|
192
|
-
const metaTxn = await this.service.sendMetaTxn({ call: { walletAddress, contract, input } })
|
|
212
|
+
const metaTxn = await this.service.sendMetaTxn({ call: { walletAddress, contract, input }, quote: typecheckedQuote })
|
|
193
213
|
|
|
194
214
|
logger.info(`[rpc-relayer/relay] got relay result ${JSON.stringify(metaTxn)}`)
|
|
195
215
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* eslint-disable */
|
|
2
|
-
// sequence-relayer v0.4.0
|
|
2
|
+
// sequence-relayer v0.4.0 4dca0b91c1531d1166ae2f7ebd8af571b0c0e43b
|
|
3
3
|
// --
|
|
4
4
|
// This file has been generated by https://github.com/webrpc/webrpc using gen/typescript
|
|
5
5
|
// Do not edit by hand. Update your webrpc schema and re-generate.
|
|
@@ -11,7 +11,7 @@ export const WebRPCVersion = 'v1'
|
|
|
11
11
|
export const WebRPCSchemaVersion = 'v0.4.0'
|
|
12
12
|
|
|
13
13
|
// Schema hash generated from your RIDL schema
|
|
14
|
-
export const WebRPCSchemaHash = '
|
|
14
|
+
export const WebRPCSchemaHash = '4dca0b91c1531d1166ae2f7ebd8af571b0c0e43b'
|
|
15
15
|
|
|
16
16
|
//
|
|
17
17
|
// Types
|
|
@@ -265,6 +265,7 @@ export interface GetChainIDReturn {
|
|
|
265
265
|
}
|
|
266
266
|
export interface SendMetaTxnArgs {
|
|
267
267
|
call: MetaTxn
|
|
268
|
+
quote?: string
|
|
268
269
|
}
|
|
269
270
|
|
|
270
271
|
export interface SendMetaTxnReturn {
|
|
@@ -317,6 +318,7 @@ export interface FeeOptionsArgs {
|
|
|
317
318
|
|
|
318
319
|
export interface FeeOptionsReturn {
|
|
319
320
|
options: Array<FeeOption>
|
|
321
|
+
quote?: string
|
|
320
322
|
}
|
|
321
323
|
export interface GetMetaTxnNetworkFeeOptionsArgs {
|
|
322
324
|
walletConfig: WalletConfig
|
|
@@ -477,7 +479,8 @@ export class Relayer implements Relayer {
|
|
|
477
479
|
return this.fetch(this.url('FeeOptions'), createHTTPRequest(args, headers)).then(res => {
|
|
478
480
|
return buildResponse(res).then(_data => {
|
|
479
481
|
return {
|
|
480
|
-
options: <Array<FeeOption>>_data.options
|
|
482
|
+
options: <Array<FeeOption>>_data.options,
|
|
483
|
+
quote: <string>_data.quote
|
|
481
484
|
}
|
|
482
485
|
})
|
|
483
486
|
})
|