@0xsequence/provider 1.7.2 → 1.8.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.
@@ -9,6 +9,7 @@ var network = require('@0xsequence/network');
9
9
  var core = require('@0xsequence/core');
10
10
  var auth = require('@0xsequence/auth');
11
11
  var abi = require('@0xsequence/abi');
12
+ var tracker = require('@databeat/tracker');
12
13
 
13
14
  function _extends() {
14
15
  _extends = Object.assign ? Object.assign.bind() : function (target) {
@@ -3571,9 +3572,47 @@ class SingleNetworkSequenceProvider extends SequenceProvider {
3571
3572
  }
3572
3573
  }
3573
3574
 
3575
+ // Analytics sub-class to add some custom helper methods
3576
+ class Analytics extends tracker.Databeat {}
3577
+
3578
+ // Setup analytics tracker
3579
+ const setupAnalytics = (projectAccessKey, server) => {
3580
+ if (!server) {
3581
+ server = 'https://nodes.sequence.app';
3582
+ }
3583
+
3584
+ // disable tracking if projectAccessKey is not set
3585
+ const noop = !projectAccessKey;
3586
+
3587
+ // auth
3588
+ const auth = {};
3589
+ if (projectAccessKey) {
3590
+ auth.headers = {
3591
+ 'X-Access-Key': projectAccessKey
3592
+ };
3593
+ }
3594
+ return new Analytics(server, auth, {
3595
+ noop: noop,
3596
+ defaultEnabled: true,
3597
+ privacy: {
3598
+ userIdHash: true,
3599
+ userAgentSalt: false
3600
+ },
3601
+ initProps: () => {
3602
+ if (!tracker.isBrowser()) {
3603
+ return {};
3604
+ } else {
3605
+ return {
3606
+ origin: window.location.origin
3607
+ };
3608
+ }
3609
+ }
3610
+ });
3611
+ };
3612
+
3574
3613
  var packageJson = {
3575
3614
  name: "@0xsequence/provider",
3576
- version: "1.7.2",
3615
+ version: "1.8.1",
3577
3616
  description: "provider sub-package for Sequence",
3578
3617
  repository: "https://github.com/0xsequence/sequence.js/tree/master/packages/provider",
3579
3618
  source: "src/index.ts",
@@ -3602,6 +3641,7 @@ var packageJson = {
3602
3641
  "@0xsequence/relayer": "workspace:*",
3603
3642
  "@0xsequence/utils": "workspace:*",
3604
3643
  "@0xsequence/wallet": "workspace:*",
3644
+ "@databeat/tracker": "^0.8.1",
3605
3645
  eventemitter2: "^6.4.5",
3606
3646
  "webextension-polyfill": "^0.10.0"
3607
3647
  },
@@ -3610,8 +3650,8 @@ var packageJson = {
3610
3650
  },
3611
3651
  devDependencies: {
3612
3652
  "@types/webextension-polyfill": "^0.10.0",
3613
- hardhat: "^2.12.2",
3614
- ethers: "^5.7.2"
3653
+ ethers: "^5.7.2",
3654
+ hardhat: "^2.12.2"
3615
3655
  },
3616
3656
  files: [
3617
3657
  "src",
@@ -3705,14 +3745,15 @@ DefaultChainIdTracker.SESSION_CHAIN_ID_KEY = '@sequence.session.defaultChainId';
3705
3745
 
3706
3746
  // TODO: rename Client to transport.. or something.. like SequenceTransport ..
3707
3747
  class SequenceClient {
3708
- constructor(transport, store, options, projectAccessKey) {
3709
- var _options$defaultEIP;
3710
- this.projectAccessKey = projectAccessKey;
3748
+ constructor(transport, store, options) {
3749
+ var _options$defaultEIP, _this$session$getSess;
3711
3750
  this.session = void 0;
3712
3751
  this.defaultChainId = void 0;
3713
3752
  this.callbacks = {};
3714
3753
  this.transport = void 0;
3715
3754
  this.defaultEIP6492 = void 0;
3755
+ this.projectAccessKey = void 0;
3756
+ this.analytics = void 0;
3716
3757
  if (isMuxTransportTemplate(transport)) {
3717
3758
  this.transport = MuxMessageProvider.new(transport);
3718
3759
  } else if (isProviderTransport(transport)) {
@@ -3720,8 +3761,8 @@ class SequenceClient {
3720
3761
  } else {
3721
3762
  throw new Error('Invalid transport');
3722
3763
  }
3723
- const defaultChainId = typeof options === 'number' ? options : options == null ? void 0 : options.defaultChainId;
3724
- this.defaultEIP6492 = typeof options === 'number' ? false : (_options$defaultEIP = options == null ? void 0 : options.defaultEIP6492) != null ? _options$defaultEIP : false;
3764
+ const defaultChainId = options == null ? void 0 : options.defaultChainId;
3765
+ this.defaultEIP6492 = (_options$defaultEIP = options == null ? void 0 : options.defaultEIP6492) != null ? _options$defaultEIP : false;
3725
3766
  this.session = new SequenceClientSession(store);
3726
3767
  this.defaultChainId = new DefaultChainIdTracker(store, defaultChainId);
3727
3768
  this.transport.on('accountsChanged', accounts => {
@@ -3772,6 +3813,18 @@ class SequenceClient {
3772
3813
  const chainIdHex = ethers.ethers.utils.hexValue(chainId);
3773
3814
  (_this$callbacks$chain2 = this.callbacks.chainChanged) == null || _this$callbacks$chain2.forEach(cb => cb(chainIdHex));
3774
3815
  });
3816
+ if (options != null && options.projectAccessKey) {
3817
+ this.projectAccessKey = options.projectAccessKey;
3818
+ }
3819
+ if (this.projectAccessKey && options != null && options.analytics) {
3820
+ this.analytics = setupAnalytics(this.projectAccessKey);
3821
+ } else {
3822
+ this.analytics = setupAnalytics(''); // noop analytics
3823
+ }
3824
+ if ((_this$session$getSess = this.session.getSession()) != null && _this$session$getSess.accountAddress) {
3825
+ var _this$analytics, _this$session$getSess2;
3826
+ (_this$analytics = this.analytics) == null || _this$analytics.identify((_this$session$getSess2 = this.session.getSession()) == null ? void 0 : _this$session$getSess2.accountAddress);
3827
+ }
3775
3828
  }
3776
3829
 
3777
3830
  // Callbacks
@@ -3895,17 +3948,24 @@ class SequenceClient {
3895
3948
  connectDetails.chainId = ethers.ethers.BigNumber.from(connectDetails.chainId).toString();
3896
3949
  }
3897
3950
  if (connectDetails.connected) {
3951
+ var _connectDetails$sessi;
3898
3952
  if (!connectDetails.session) {
3899
3953
  throw new Error('impossible state, connect response is missing session');
3900
3954
  }
3901
3955
  this.session.setSession(connectDetails.session);
3956
+ if ((_connectDetails$sessi = connectDetails.session) != null && _connectDetails$sessi.accountAddress) {
3957
+ var _this$analytics2;
3958
+ (_this$analytics2 = this.analytics) == null || _this$analytics2.identify(connectDetails.session.accountAddress);
3959
+ }
3902
3960
  }
3903
3961
  return connectDetails;
3904
3962
  }
3905
3963
  disconnect() {
3964
+ var _this$analytics3;
3906
3965
  if (this.isOpened()) {
3907
3966
  this.closeWallet();
3908
3967
  }
3968
+ (_this$analytics3 = this.analytics) == null || _this$analytics3.reset();
3909
3969
  return this.session.clearSession();
3910
3970
  }
3911
3971
 
@@ -3985,7 +4045,14 @@ class SequenceClient {
3985
4045
  return method;
3986
4046
  }
3987
4047
  async signMessage(message, options) {
4048
+ var _this$analytics4;
3988
4049
  const method = this.signMethod(options);
4050
+ (_this$analytics4 = this.analytics) == null || _this$analytics4.track({
4051
+ event: 'SIGN_MESSAGE_REQUEST',
4052
+ props: {
4053
+ chainId: `${(options == null ? void 0 : options.chainId) || this.getChainId()}`
4054
+ }
4055
+ });
3989
4056
 
3990
4057
  // Address is ignored by the wallet webapp
3991
4058
  return this.send({
@@ -3994,6 +4061,7 @@ class SequenceClient {
3994
4061
  }, options == null ? void 0 : options.chainId);
3995
4062
  }
3996
4063
  async signTypedData(typedData, options) {
4064
+ var _this$analytics5;
3997
4065
  const method = this.signTypedDataMethod(options);
3998
4066
 
3999
4067
  // TODO: Stop using ethers for this, this is the only place where we use it
@@ -4005,14 +4073,27 @@ class SequenceClient {
4005
4073
  // - The one provided in the typedData.domain.chainId
4006
4074
  // - The default chainId
4007
4075
 
4076
+ (_this$analytics5 = this.analytics) == null || _this$analytics5.track({
4077
+ event: 'SIGN_TYPED_DATA_REQUEST',
4078
+ props: {
4079
+ chainId: `${(options == null ? void 0 : options.chainId) || this.getChainId()}`
4080
+ }
4081
+ });
4008
4082
  return this.send({
4009
4083
  method,
4010
4084
  params: [this.getAddress(), encoded]
4011
4085
  }, (options == null ? void 0 : options.chainId) || typedData.domain.chainId && ethers.ethers.BigNumber.from(typedData.domain.chainId).toNumber() || this.getChainId());
4012
4086
  }
4013
4087
  async sendTransaction(tx, options) {
4088
+ var _this$analytics6;
4014
4089
  const sequenceTxs = Array.isArray(tx) ? tx : [tx];
4015
4090
  const extendedTxs = toExtended(sequenceTxs);
4091
+ (_this$analytics6 = this.analytics) == null || _this$analytics6.track({
4092
+ event: 'SEND_TRANSACTION_REQUEST',
4093
+ props: {
4094
+ chainId: `${(options == null ? void 0 : options.chainId) || this.getChainId()}`
4095
+ }
4096
+ });
4016
4097
  return this.send({
4017
4098
  method: 'eth_sendTransaction',
4018
4099
  params: [extendedTxs]
@@ -4048,7 +4129,8 @@ const DefaultProviderConfig = {
4048
4129
  enabled: false
4049
4130
  }
4050
4131
  },
4051
- defaultNetwork: 1
4132
+ defaultNetwork: 1,
4133
+ analytics: true
4052
4134
  };
4053
4135
  let sequenceWalletProvider;
4054
4136
 
@@ -4121,8 +4203,10 @@ const initWallet = (projectAccessKey, partialConfig) => {
4121
4203
  // Create client, provider and return signer
4122
4204
  const client = new SequenceClient(config.transports, itemStore, {
4123
4205
  defaultChainId: defaultNetwork,
4124
- defaultEIP6492: config.defaultEIP6492
4125
- }, projectAccessKey);
4206
+ defaultEIP6492: config.defaultEIP6492,
4207
+ projectAccessKey: projectAccessKey,
4208
+ analytics: config.analytics
4209
+ });
4126
4210
  sequenceWalletProvider = new SequenceProvider(client, providerForChainId);
4127
4211
  return sequenceWalletProvider;
4128
4212
  };
@@ -9,6 +9,7 @@ var network = require('@0xsequence/network');
9
9
  var core = require('@0xsequence/core');
10
10
  var auth = require('@0xsequence/auth');
11
11
  var abi = require('@0xsequence/abi');
12
+ var tracker = require('@databeat/tracker');
12
13
 
13
14
  function _extends() {
14
15
  _extends = Object.assign ? Object.assign.bind() : function (target) {
@@ -3571,9 +3572,47 @@ class SingleNetworkSequenceProvider extends SequenceProvider {
3571
3572
  }
3572
3573
  }
3573
3574
 
3575
+ // Analytics sub-class to add some custom helper methods
3576
+ class Analytics extends tracker.Databeat {}
3577
+
3578
+ // Setup analytics tracker
3579
+ const setupAnalytics = (projectAccessKey, server) => {
3580
+ if (!server) {
3581
+ server = 'https://nodes.sequence.app';
3582
+ }
3583
+
3584
+ // disable tracking if projectAccessKey is not set
3585
+ const noop = !projectAccessKey;
3586
+
3587
+ // auth
3588
+ const auth = {};
3589
+ if (projectAccessKey) {
3590
+ auth.headers = {
3591
+ 'X-Access-Key': projectAccessKey
3592
+ };
3593
+ }
3594
+ return new Analytics(server, auth, {
3595
+ noop: noop,
3596
+ defaultEnabled: true,
3597
+ privacy: {
3598
+ userIdHash: true,
3599
+ userAgentSalt: false
3600
+ },
3601
+ initProps: () => {
3602
+ if (!tracker.isBrowser()) {
3603
+ return {};
3604
+ } else {
3605
+ return {
3606
+ origin: window.location.origin
3607
+ };
3608
+ }
3609
+ }
3610
+ });
3611
+ };
3612
+
3574
3613
  var packageJson = {
3575
3614
  name: "@0xsequence/provider",
3576
- version: "1.7.2",
3615
+ version: "1.8.1",
3577
3616
  description: "provider sub-package for Sequence",
3578
3617
  repository: "https://github.com/0xsequence/sequence.js/tree/master/packages/provider",
3579
3618
  source: "src/index.ts",
@@ -3602,6 +3641,7 @@ var packageJson = {
3602
3641
  "@0xsequence/relayer": "workspace:*",
3603
3642
  "@0xsequence/utils": "workspace:*",
3604
3643
  "@0xsequence/wallet": "workspace:*",
3644
+ "@databeat/tracker": "^0.8.1",
3605
3645
  eventemitter2: "^6.4.5",
3606
3646
  "webextension-polyfill": "^0.10.0"
3607
3647
  },
@@ -3610,8 +3650,8 @@ var packageJson = {
3610
3650
  },
3611
3651
  devDependencies: {
3612
3652
  "@types/webextension-polyfill": "^0.10.0",
3613
- hardhat: "^2.12.2",
3614
- ethers: "^5.7.2"
3653
+ ethers: "^5.7.2",
3654
+ hardhat: "^2.12.2"
3615
3655
  },
3616
3656
  files: [
3617
3657
  "src",
@@ -3705,14 +3745,15 @@ DefaultChainIdTracker.SESSION_CHAIN_ID_KEY = '@sequence.session.defaultChainId';
3705
3745
 
3706
3746
  // TODO: rename Client to transport.. or something.. like SequenceTransport ..
3707
3747
  class SequenceClient {
3708
- constructor(transport, store, options, projectAccessKey) {
3709
- var _options$defaultEIP;
3710
- this.projectAccessKey = projectAccessKey;
3748
+ constructor(transport, store, options) {
3749
+ var _options$defaultEIP, _this$session$getSess;
3711
3750
  this.session = void 0;
3712
3751
  this.defaultChainId = void 0;
3713
3752
  this.callbacks = {};
3714
3753
  this.transport = void 0;
3715
3754
  this.defaultEIP6492 = void 0;
3755
+ this.projectAccessKey = void 0;
3756
+ this.analytics = void 0;
3716
3757
  if (isMuxTransportTemplate(transport)) {
3717
3758
  this.transport = MuxMessageProvider.new(transport);
3718
3759
  } else if (isProviderTransport(transport)) {
@@ -3720,8 +3761,8 @@ class SequenceClient {
3720
3761
  } else {
3721
3762
  throw new Error('Invalid transport');
3722
3763
  }
3723
- const defaultChainId = typeof options === 'number' ? options : options == null ? void 0 : options.defaultChainId;
3724
- this.defaultEIP6492 = typeof options === 'number' ? false : (_options$defaultEIP = options == null ? void 0 : options.defaultEIP6492) != null ? _options$defaultEIP : false;
3764
+ const defaultChainId = options == null ? void 0 : options.defaultChainId;
3765
+ this.defaultEIP6492 = (_options$defaultEIP = options == null ? void 0 : options.defaultEIP6492) != null ? _options$defaultEIP : false;
3725
3766
  this.session = new SequenceClientSession(store);
3726
3767
  this.defaultChainId = new DefaultChainIdTracker(store, defaultChainId);
3727
3768
  this.transport.on('accountsChanged', accounts => {
@@ -3772,6 +3813,18 @@ class SequenceClient {
3772
3813
  const chainIdHex = ethers.ethers.utils.hexValue(chainId);
3773
3814
  (_this$callbacks$chain2 = this.callbacks.chainChanged) == null || _this$callbacks$chain2.forEach(cb => cb(chainIdHex));
3774
3815
  });
3816
+ if (options != null && options.projectAccessKey) {
3817
+ this.projectAccessKey = options.projectAccessKey;
3818
+ }
3819
+ if (this.projectAccessKey && options != null && options.analytics) {
3820
+ this.analytics = setupAnalytics(this.projectAccessKey);
3821
+ } else {
3822
+ this.analytics = setupAnalytics(''); // noop analytics
3823
+ }
3824
+ if ((_this$session$getSess = this.session.getSession()) != null && _this$session$getSess.accountAddress) {
3825
+ var _this$analytics, _this$session$getSess2;
3826
+ (_this$analytics = this.analytics) == null || _this$analytics.identify((_this$session$getSess2 = this.session.getSession()) == null ? void 0 : _this$session$getSess2.accountAddress);
3827
+ }
3775
3828
  }
3776
3829
 
3777
3830
  // Callbacks
@@ -3895,17 +3948,24 @@ class SequenceClient {
3895
3948
  connectDetails.chainId = ethers.ethers.BigNumber.from(connectDetails.chainId).toString();
3896
3949
  }
3897
3950
  if (connectDetails.connected) {
3951
+ var _connectDetails$sessi;
3898
3952
  if (!connectDetails.session) {
3899
3953
  throw new Error('impossible state, connect response is missing session');
3900
3954
  }
3901
3955
  this.session.setSession(connectDetails.session);
3956
+ if ((_connectDetails$sessi = connectDetails.session) != null && _connectDetails$sessi.accountAddress) {
3957
+ var _this$analytics2;
3958
+ (_this$analytics2 = this.analytics) == null || _this$analytics2.identify(connectDetails.session.accountAddress);
3959
+ }
3902
3960
  }
3903
3961
  return connectDetails;
3904
3962
  }
3905
3963
  disconnect() {
3964
+ var _this$analytics3;
3906
3965
  if (this.isOpened()) {
3907
3966
  this.closeWallet();
3908
3967
  }
3968
+ (_this$analytics3 = this.analytics) == null || _this$analytics3.reset();
3909
3969
  return this.session.clearSession();
3910
3970
  }
3911
3971
 
@@ -3985,7 +4045,14 @@ class SequenceClient {
3985
4045
  return method;
3986
4046
  }
3987
4047
  async signMessage(message, options) {
4048
+ var _this$analytics4;
3988
4049
  const method = this.signMethod(options);
4050
+ (_this$analytics4 = this.analytics) == null || _this$analytics4.track({
4051
+ event: 'SIGN_MESSAGE_REQUEST',
4052
+ props: {
4053
+ chainId: `${(options == null ? void 0 : options.chainId) || this.getChainId()}`
4054
+ }
4055
+ });
3989
4056
 
3990
4057
  // Address is ignored by the wallet webapp
3991
4058
  return this.send({
@@ -3994,6 +4061,7 @@ class SequenceClient {
3994
4061
  }, options == null ? void 0 : options.chainId);
3995
4062
  }
3996
4063
  async signTypedData(typedData, options) {
4064
+ var _this$analytics5;
3997
4065
  const method = this.signTypedDataMethod(options);
3998
4066
 
3999
4067
  // TODO: Stop using ethers for this, this is the only place where we use it
@@ -4005,14 +4073,27 @@ class SequenceClient {
4005
4073
  // - The one provided in the typedData.domain.chainId
4006
4074
  // - The default chainId
4007
4075
 
4076
+ (_this$analytics5 = this.analytics) == null || _this$analytics5.track({
4077
+ event: 'SIGN_TYPED_DATA_REQUEST',
4078
+ props: {
4079
+ chainId: `${(options == null ? void 0 : options.chainId) || this.getChainId()}`
4080
+ }
4081
+ });
4008
4082
  return this.send({
4009
4083
  method,
4010
4084
  params: [this.getAddress(), encoded]
4011
4085
  }, (options == null ? void 0 : options.chainId) || typedData.domain.chainId && ethers.ethers.BigNumber.from(typedData.domain.chainId).toNumber() || this.getChainId());
4012
4086
  }
4013
4087
  async sendTransaction(tx, options) {
4088
+ var _this$analytics6;
4014
4089
  const sequenceTxs = Array.isArray(tx) ? tx : [tx];
4015
4090
  const extendedTxs = toExtended(sequenceTxs);
4091
+ (_this$analytics6 = this.analytics) == null || _this$analytics6.track({
4092
+ event: 'SEND_TRANSACTION_REQUEST',
4093
+ props: {
4094
+ chainId: `${(options == null ? void 0 : options.chainId) || this.getChainId()}`
4095
+ }
4096
+ });
4016
4097
  return this.send({
4017
4098
  method: 'eth_sendTransaction',
4018
4099
  params: [extendedTxs]
@@ -4048,7 +4129,8 @@ const DefaultProviderConfig = {
4048
4129
  enabled: false
4049
4130
  }
4050
4131
  },
4051
- defaultNetwork: 1
4132
+ defaultNetwork: 1,
4133
+ analytics: true
4052
4134
  };
4053
4135
  let sequenceWalletProvider;
4054
4136
 
@@ -4121,8 +4203,10 @@ const initWallet = (projectAccessKey, partialConfig) => {
4121
4203
  // Create client, provider and return signer
4122
4204
  const client = new SequenceClient(config.transports, itemStore, {
4123
4205
  defaultChainId: defaultNetwork,
4124
- defaultEIP6492: config.defaultEIP6492
4125
- }, projectAccessKey);
4206
+ defaultEIP6492: config.defaultEIP6492,
4207
+ projectAccessKey: projectAccessKey,
4208
+ analytics: config.analytics
4209
+ });
4126
4210
  sequenceWalletProvider = new SequenceProvider(client, providerForChainId);
4127
4211
  return sequenceWalletProvider;
4128
4212
  };
@@ -5,6 +5,7 @@ import { findSupportedNetwork, ChainId, findNetworkConfig, allNetworks, JsonRpcR
5
5
  import { commons } from '@0xsequence/core';
6
6
  import { signAuthorization } from '@0xsequence/auth';
7
7
  import { walletContracts } from '@0xsequence/abi';
8
+ import { isBrowser, Databeat } from '@databeat/tracker';
8
9
 
9
10
  function _extends() {
10
11
  _extends = Object.assign ? Object.assign.bind() : function (target) {
@@ -3567,9 +3568,47 @@ class SingleNetworkSequenceProvider extends SequenceProvider {
3567
3568
  }
3568
3569
  }
3569
3570
 
3571
+ // Analytics sub-class to add some custom helper methods
3572
+ class Analytics extends Databeat {}
3573
+
3574
+ // Setup analytics tracker
3575
+ const setupAnalytics = (projectAccessKey, server) => {
3576
+ if (!server) {
3577
+ server = 'https://nodes.sequence.app';
3578
+ }
3579
+
3580
+ // disable tracking if projectAccessKey is not set
3581
+ const noop = !projectAccessKey;
3582
+
3583
+ // auth
3584
+ const auth = {};
3585
+ if (projectAccessKey) {
3586
+ auth.headers = {
3587
+ 'X-Access-Key': projectAccessKey
3588
+ };
3589
+ }
3590
+ return new Analytics(server, auth, {
3591
+ noop: noop,
3592
+ defaultEnabled: true,
3593
+ privacy: {
3594
+ userIdHash: true,
3595
+ userAgentSalt: false
3596
+ },
3597
+ initProps: () => {
3598
+ if (!isBrowser()) {
3599
+ return {};
3600
+ } else {
3601
+ return {
3602
+ origin: window.location.origin
3603
+ };
3604
+ }
3605
+ }
3606
+ });
3607
+ };
3608
+
3570
3609
  var packageJson = {
3571
3610
  name: "@0xsequence/provider",
3572
- version: "1.7.2",
3611
+ version: "1.8.1",
3573
3612
  description: "provider sub-package for Sequence",
3574
3613
  repository: "https://github.com/0xsequence/sequence.js/tree/master/packages/provider",
3575
3614
  source: "src/index.ts",
@@ -3598,6 +3637,7 @@ var packageJson = {
3598
3637
  "@0xsequence/relayer": "workspace:*",
3599
3638
  "@0xsequence/utils": "workspace:*",
3600
3639
  "@0xsequence/wallet": "workspace:*",
3640
+ "@databeat/tracker": "^0.8.1",
3601
3641
  eventemitter2: "^6.4.5",
3602
3642
  "webextension-polyfill": "^0.10.0"
3603
3643
  },
@@ -3606,8 +3646,8 @@ var packageJson = {
3606
3646
  },
3607
3647
  devDependencies: {
3608
3648
  "@types/webextension-polyfill": "^0.10.0",
3609
- hardhat: "^2.12.2",
3610
- ethers: "^5.7.2"
3649
+ ethers: "^5.7.2",
3650
+ hardhat: "^2.12.2"
3611
3651
  },
3612
3652
  files: [
3613
3653
  "src",
@@ -3701,14 +3741,15 @@ DefaultChainIdTracker.SESSION_CHAIN_ID_KEY = '@sequence.session.defaultChainId';
3701
3741
 
3702
3742
  // TODO: rename Client to transport.. or something.. like SequenceTransport ..
3703
3743
  class SequenceClient {
3704
- constructor(transport, store, options, projectAccessKey) {
3705
- var _options$defaultEIP;
3706
- this.projectAccessKey = projectAccessKey;
3744
+ constructor(transport, store, options) {
3745
+ var _options$defaultEIP, _this$session$getSess;
3707
3746
  this.session = void 0;
3708
3747
  this.defaultChainId = void 0;
3709
3748
  this.callbacks = {};
3710
3749
  this.transport = void 0;
3711
3750
  this.defaultEIP6492 = void 0;
3751
+ this.projectAccessKey = void 0;
3752
+ this.analytics = void 0;
3712
3753
  if (isMuxTransportTemplate(transport)) {
3713
3754
  this.transport = MuxMessageProvider.new(transport);
3714
3755
  } else if (isProviderTransport(transport)) {
@@ -3716,8 +3757,8 @@ class SequenceClient {
3716
3757
  } else {
3717
3758
  throw new Error('Invalid transport');
3718
3759
  }
3719
- const defaultChainId = typeof options === 'number' ? options : options == null ? void 0 : options.defaultChainId;
3720
- this.defaultEIP6492 = typeof options === 'number' ? false : (_options$defaultEIP = options == null ? void 0 : options.defaultEIP6492) != null ? _options$defaultEIP : false;
3760
+ const defaultChainId = options == null ? void 0 : options.defaultChainId;
3761
+ this.defaultEIP6492 = (_options$defaultEIP = options == null ? void 0 : options.defaultEIP6492) != null ? _options$defaultEIP : false;
3721
3762
  this.session = new SequenceClientSession(store);
3722
3763
  this.defaultChainId = new DefaultChainIdTracker(store, defaultChainId);
3723
3764
  this.transport.on('accountsChanged', accounts => {
@@ -3768,6 +3809,18 @@ class SequenceClient {
3768
3809
  const chainIdHex = ethers.utils.hexValue(chainId);
3769
3810
  (_this$callbacks$chain2 = this.callbacks.chainChanged) == null || _this$callbacks$chain2.forEach(cb => cb(chainIdHex));
3770
3811
  });
3812
+ if (options != null && options.projectAccessKey) {
3813
+ this.projectAccessKey = options.projectAccessKey;
3814
+ }
3815
+ if (this.projectAccessKey && options != null && options.analytics) {
3816
+ this.analytics = setupAnalytics(this.projectAccessKey);
3817
+ } else {
3818
+ this.analytics = setupAnalytics(''); // noop analytics
3819
+ }
3820
+ if ((_this$session$getSess = this.session.getSession()) != null && _this$session$getSess.accountAddress) {
3821
+ var _this$analytics, _this$session$getSess2;
3822
+ (_this$analytics = this.analytics) == null || _this$analytics.identify((_this$session$getSess2 = this.session.getSession()) == null ? void 0 : _this$session$getSess2.accountAddress);
3823
+ }
3771
3824
  }
3772
3825
 
3773
3826
  // Callbacks
@@ -3891,17 +3944,24 @@ class SequenceClient {
3891
3944
  connectDetails.chainId = ethers.BigNumber.from(connectDetails.chainId).toString();
3892
3945
  }
3893
3946
  if (connectDetails.connected) {
3947
+ var _connectDetails$sessi;
3894
3948
  if (!connectDetails.session) {
3895
3949
  throw new Error('impossible state, connect response is missing session');
3896
3950
  }
3897
3951
  this.session.setSession(connectDetails.session);
3952
+ if ((_connectDetails$sessi = connectDetails.session) != null && _connectDetails$sessi.accountAddress) {
3953
+ var _this$analytics2;
3954
+ (_this$analytics2 = this.analytics) == null || _this$analytics2.identify(connectDetails.session.accountAddress);
3955
+ }
3898
3956
  }
3899
3957
  return connectDetails;
3900
3958
  }
3901
3959
  disconnect() {
3960
+ var _this$analytics3;
3902
3961
  if (this.isOpened()) {
3903
3962
  this.closeWallet();
3904
3963
  }
3964
+ (_this$analytics3 = this.analytics) == null || _this$analytics3.reset();
3905
3965
  return this.session.clearSession();
3906
3966
  }
3907
3967
 
@@ -3981,7 +4041,14 @@ class SequenceClient {
3981
4041
  return method;
3982
4042
  }
3983
4043
  async signMessage(message, options) {
4044
+ var _this$analytics4;
3984
4045
  const method = this.signMethod(options);
4046
+ (_this$analytics4 = this.analytics) == null || _this$analytics4.track({
4047
+ event: 'SIGN_MESSAGE_REQUEST',
4048
+ props: {
4049
+ chainId: `${(options == null ? void 0 : options.chainId) || this.getChainId()}`
4050
+ }
4051
+ });
3985
4052
 
3986
4053
  // Address is ignored by the wallet webapp
3987
4054
  return this.send({
@@ -3990,6 +4057,7 @@ class SequenceClient {
3990
4057
  }, options == null ? void 0 : options.chainId);
3991
4058
  }
3992
4059
  async signTypedData(typedData, options) {
4060
+ var _this$analytics5;
3993
4061
  const method = this.signTypedDataMethod(options);
3994
4062
 
3995
4063
  // TODO: Stop using ethers for this, this is the only place where we use it
@@ -4001,14 +4069,27 @@ class SequenceClient {
4001
4069
  // - The one provided in the typedData.domain.chainId
4002
4070
  // - The default chainId
4003
4071
 
4072
+ (_this$analytics5 = this.analytics) == null || _this$analytics5.track({
4073
+ event: 'SIGN_TYPED_DATA_REQUEST',
4074
+ props: {
4075
+ chainId: `${(options == null ? void 0 : options.chainId) || this.getChainId()}`
4076
+ }
4077
+ });
4004
4078
  return this.send({
4005
4079
  method,
4006
4080
  params: [this.getAddress(), encoded]
4007
4081
  }, (options == null ? void 0 : options.chainId) || typedData.domain.chainId && ethers.BigNumber.from(typedData.domain.chainId).toNumber() || this.getChainId());
4008
4082
  }
4009
4083
  async sendTransaction(tx, options) {
4084
+ var _this$analytics6;
4010
4085
  const sequenceTxs = Array.isArray(tx) ? tx : [tx];
4011
4086
  const extendedTxs = toExtended(sequenceTxs);
4087
+ (_this$analytics6 = this.analytics) == null || _this$analytics6.track({
4088
+ event: 'SEND_TRANSACTION_REQUEST',
4089
+ props: {
4090
+ chainId: `${(options == null ? void 0 : options.chainId) || this.getChainId()}`
4091
+ }
4092
+ });
4012
4093
  return this.send({
4013
4094
  method: 'eth_sendTransaction',
4014
4095
  params: [extendedTxs]
@@ -4044,7 +4125,8 @@ const DefaultProviderConfig = {
4044
4125
  enabled: false
4045
4126
  }
4046
4127
  },
4047
- defaultNetwork: 1
4128
+ defaultNetwork: 1,
4129
+ analytics: true
4048
4130
  };
4049
4131
  let sequenceWalletProvider;
4050
4132
 
@@ -4117,8 +4199,10 @@ const initWallet = (projectAccessKey, partialConfig) => {
4117
4199
  // Create client, provider and return signer
4118
4200
  const client = new SequenceClient(config.transports, itemStore, {
4119
4201
  defaultChainId: defaultNetwork,
4120
- defaultEIP6492: config.defaultEIP6492
4121
- }, projectAccessKey);
4202
+ defaultEIP6492: config.defaultEIP6492,
4203
+ projectAccessKey: projectAccessKey,
4204
+ analytics: config.analytics
4205
+ });
4122
4206
  sequenceWalletProvider = new SequenceProvider(client, providerForChainId);
4123
4207
  return sequenceWalletProvider;
4124
4208
  };
@@ -0,0 +1,13 @@
1
+ import { Databeat, Event as DatabeatEvent } from '@databeat/tracker';
2
+ export declare enum EventType {
3
+ INIT = 0,
4
+ VIEW = 1,
5
+ SIGN_MESSAGE_REQUEST = 2,
6
+ SIGN_TYPED_DATA_REQUEST = 3,
7
+ SEND_TRANSACTION_REQUEST = 4
8
+ }
9
+ export type EventTypes = keyof typeof EventType;
10
+ export type Event = DatabeatEvent<EventTypes>;
11
+ export declare class Analytics extends Databeat<EventTypes> {
12
+ }
13
+ export declare const setupAnalytics: (projectAccessKey: string, server?: string) => Analytics;
@@ -2,6 +2,7 @@ import { JsonRpcRequest, NetworkConfig } from '@0xsequence/network';
2
2
  import { ConnectDetails, ConnectOptions, ItemStore, MuxTransportTemplate, OpenWalletIntent, OptionalChainId, OptionalEIP6492, ProviderTransport, WalletEventTypes, WalletSession } from "./index.js";
3
3
  import { commons } from '@0xsequence/core';
4
4
  import { TypedData } from '@0xsequence/utils';
5
+ import { Analytics } from "./analytics.js";
5
6
  import { ethers } from 'ethers';
6
7
  /**
7
8
  * This session class is meant to persist the state of the wallet connection
@@ -36,6 +37,8 @@ export declare class DefaultChainIdTracker {
36
37
  export type SequenceClientOptions = {
37
38
  defaultChainId?: number;
38
39
  defaultEIP6492?: boolean;
40
+ projectAccessKey?: string;
41
+ analytics?: boolean;
39
42
  };
40
43
  /**
41
44
  * This is a wallet client for sequence wallet-webapp. It connects using *some* transport
@@ -44,13 +47,14 @@ export type SequenceClientOptions = {
44
47
  * It doesn't implement a full ethereum Provider, it doesn't include read-only methods.
45
48
  */
46
49
  export declare class SequenceClient {
47
- projectAccessKey?: string | undefined;
48
50
  private readonly session;
49
51
  private readonly defaultChainId;
50
52
  private readonly callbacks;
51
53
  readonly transport: ProviderTransport;
52
54
  readonly defaultEIP6492: boolean;
53
- constructor(transport: ProviderTransport | MuxTransportTemplate, store: ItemStore, options?: SequenceClientOptions | number, projectAccessKey?: string | undefined);
55
+ readonly projectAccessKey?: string;
56
+ readonly analytics?: Analytics;
57
+ constructor(transport: ProviderTransport | MuxTransportTemplate, store: ItemStore, options?: SequenceClientOptions);
54
58
  registerCallback<K extends keyof WalletEventTypes>(eventName: K, callback: WalletEventTypes[K]): () => void;
55
59
  onOpen(callback: WalletEventTypes['open']): () => void;
56
60
  onClose(callback: WalletEventTypes['close']): () => void;
@@ -8,6 +8,7 @@ export interface ProviderConfig {
8
8
  defaultEIP6492?: boolean;
9
9
  networks?: Partial<NetworkConfig>[];
10
10
  transports?: MuxTransportTemplate;
11
+ analytics?: boolean;
11
12
  }
12
13
  export declare const DefaultProviderConfig: {
13
14
  transports: {
@@ -20,6 +21,7 @@ export declare const DefaultProviderConfig: {
20
21
  };
21
22
  };
22
23
  defaultNetwork: number;
24
+ analytics: boolean;
23
25
  };
24
26
  /**
25
27
  * Initializes a wallet with the provided project access key and optional configuration.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@0xsequence/provider",
3
- "version": "1.7.2",
3
+ "version": "1.8.1",
4
4
  "description": "provider sub-package for Sequence",
5
5
  "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/provider",
6
6
  "source": "src/index.ts",
@@ -9,25 +9,26 @@
9
9
  "author": "Horizon Blockchain Games",
10
10
  "license": "Apache-2.0",
11
11
  "dependencies": {
12
+ "@databeat/tracker": "^0.8.1",
12
13
  "eventemitter2": "^6.4.5",
13
14
  "webextension-polyfill": "^0.10.0",
14
- "@0xsequence/abi": "1.7.2",
15
- "@0xsequence/account": "1.7.2",
16
- "@0xsequence/auth": "1.7.2",
17
- "@0xsequence/core": "1.7.2",
18
- "@0xsequence/migration": "1.7.2",
19
- "@0xsequence/network": "1.7.2",
20
- "@0xsequence/relayer": "1.7.2",
21
- "@0xsequence/utils": "1.7.2",
22
- "@0xsequence/wallet": "1.7.2"
15
+ "@0xsequence/abi": "1.8.1",
16
+ "@0xsequence/account": "1.8.1",
17
+ "@0xsequence/auth": "1.8.1",
18
+ "@0xsequence/migration": "1.8.1",
19
+ "@0xsequence/core": "1.8.1",
20
+ "@0xsequence/network": "1.8.1",
21
+ "@0xsequence/relayer": "1.8.1",
22
+ "@0xsequence/utils": "1.8.1",
23
+ "@0xsequence/wallet": "1.8.1"
23
24
  },
24
25
  "peerDependencies": {
25
26
  "ethers": ">=5.5 < 6"
26
27
  },
27
28
  "devDependencies": {
28
29
  "@types/webextension-polyfill": "^0.10.0",
29
- "hardhat": "^2.12.2",
30
- "ethers": "^5.7.2"
30
+ "ethers": "^5.7.2",
31
+ "hardhat": "^2.12.2"
31
32
  },
32
33
  "files": [
33
34
  "src",
@@ -0,0 +1,47 @@
1
+ import { Databeat, Event as DatabeatEvent, Auth, isBrowser } from '@databeat/tracker'
2
+
3
+ export enum EventType {
4
+ // Core types part of Databeat
5
+ INIT,
6
+ VIEW,
7
+
8
+ // Provider specific
9
+ SIGN_MESSAGE_REQUEST,
10
+ SIGN_TYPED_DATA_REQUEST,
11
+ SEND_TRANSACTION_REQUEST
12
+ }
13
+
14
+ export type EventTypes = keyof typeof EventType
15
+ export type Event = DatabeatEvent<EventTypes>
16
+
17
+ // Analytics sub-class to add some custom helper methods
18
+ export class Analytics extends Databeat<EventTypes> {}
19
+
20
+ // Setup analytics tracker
21
+ export const setupAnalytics = (projectAccessKey: string, server?: string) => {
22
+ if (!server) {
23
+ server = 'https://nodes.sequence.app'
24
+ }
25
+
26
+ // disable tracking if projectAccessKey is not set
27
+ const noop = !projectAccessKey
28
+
29
+ // auth
30
+ const auth: Auth = {}
31
+ if (projectAccessKey) {
32
+ auth.headers = { 'X-Access-Key': projectAccessKey }
33
+ }
34
+
35
+ return new Analytics(server, auth, {
36
+ noop: noop,
37
+ defaultEnabled: true,
38
+ privacy: { userIdHash: true, userAgentSalt: false },
39
+ initProps: () => {
40
+ if (!isBrowser()) {
41
+ return {}
42
+ } else {
43
+ return { origin: window.location.origin }
44
+ }
45
+ }
46
+ })
47
+ }
package/src/client.ts CHANGED
@@ -17,6 +17,7 @@ import {
17
17
  import { commons } from '@0xsequence/core'
18
18
  import { TypedData } from '@0xsequence/utils'
19
19
  import { toExtended } from './extended'
20
+ import { Analytics, setupAnalytics } from './analytics'
20
21
  import { ethers } from 'ethers'
21
22
 
22
23
  import packageJson from '../package.json'
@@ -117,6 +118,8 @@ export class DefaultChainIdTracker {
117
118
  export type SequenceClientOptions = {
118
119
  defaultChainId?: number
119
120
  defaultEIP6492?: boolean
121
+ projectAccessKey?: string
122
+ analytics?: boolean
120
123
  }
121
124
 
122
125
  /**
@@ -135,13 +138,10 @@ export class SequenceClient {
135
138
  public readonly transport: ProviderTransport
136
139
 
137
140
  public readonly defaultEIP6492: boolean
141
+ public readonly projectAccessKey?: string
142
+ public readonly analytics?: Analytics
138
143
 
139
- constructor(
140
- transport: ProviderTransport | MuxTransportTemplate,
141
- store: ItemStore,
142
- options?: SequenceClientOptions | number,
143
- public projectAccessKey?: string
144
- ) {
144
+ constructor(transport: ProviderTransport | MuxTransportTemplate, store: ItemStore, options?: SequenceClientOptions) {
145
145
  if (isMuxTransportTemplate(transport)) {
146
146
  this.transport = MuxMessageProvider.new(transport)
147
147
  } else if (isProviderTransport(transport)) {
@@ -150,8 +150,8 @@ export class SequenceClient {
150
150
  throw new Error('Invalid transport')
151
151
  }
152
152
 
153
- const defaultChainId = typeof options === 'number' ? options : options?.defaultChainId
154
- this.defaultEIP6492 = typeof options === 'number' ? false : options?.defaultEIP6492 ?? false
153
+ const defaultChainId = options?.defaultChainId
154
+ this.defaultEIP6492 = options?.defaultEIP6492 ?? false
155
155
 
156
156
  this.session = new SequenceClientSession(store)
157
157
  this.defaultChainId = new DefaultChainIdTracker(store, defaultChainId)
@@ -206,6 +206,19 @@ export class SequenceClient {
206
206
  const chainIdHex = ethers.utils.hexValue(chainId)
207
207
  this.callbacks.chainChanged?.forEach(cb => cb(chainIdHex))
208
208
  })
209
+
210
+ if (options?.projectAccessKey) {
211
+ this.projectAccessKey = options.projectAccessKey
212
+ }
213
+ if (this.projectAccessKey && options?.analytics) {
214
+ this.analytics = setupAnalytics(this.projectAccessKey)
215
+ } else {
216
+ this.analytics = setupAnalytics('') // noop analytics
217
+ }
218
+
219
+ if (this.session.getSession()?.accountAddress) {
220
+ this.analytics?.identify(this.session.getSession()?.accountAddress)
221
+ }
209
222
  }
210
223
 
211
224
  // Callbacks
@@ -348,6 +361,10 @@ export class SequenceClient {
348
361
  }
349
362
 
350
363
  this.session.setSession(connectDetails.session)
364
+
365
+ if (connectDetails.session?.accountAddress) {
366
+ this.analytics?.identify(connectDetails.session.accountAddress)
367
+ }
351
368
  }
352
369
 
353
370
  return connectDetails
@@ -358,6 +375,8 @@ export class SequenceClient {
358
375
  this.closeWallet()
359
376
  }
360
377
 
378
+ this.analytics?.reset()
379
+
361
380
  return this.session.clearSession()
362
381
  }
363
382
 
@@ -454,6 +473,8 @@ export class SequenceClient {
454
473
  async signMessage(message: ethers.BytesLike, options?: OptionalEIP6492 & OptionalChainId): Promise<string> {
455
474
  const method = this.signMethod(options)
456
475
 
476
+ this.analytics?.track({ event: 'SIGN_MESSAGE_REQUEST', props: { chainId: `${options?.chainId || this.getChainId()}` } })
477
+
457
478
  // Address is ignored by the wallet webapp
458
479
  return this.send({ method, params: [message, this.getAddress()] }, options?.chainId)
459
480
  }
@@ -470,6 +491,8 @@ export class SequenceClient {
470
491
  // - The one provided in the typedData.domain.chainId
471
492
  // - The default chainId
472
493
 
494
+ this.analytics?.track({ event: 'SIGN_TYPED_DATA_REQUEST', props: { chainId: `${options?.chainId || this.getChainId()}` } })
495
+
473
496
  return this.send(
474
497
  { method, params: [this.getAddress(), encoded] },
475
498
  options?.chainId ||
@@ -485,6 +508,8 @@ export class SequenceClient {
485
508
  const sequenceTxs = Array.isArray(tx) ? tx : [tx]
486
509
  const extendedTxs = toExtended(sequenceTxs)
487
510
 
511
+ this.analytics?.track({ event: 'SEND_TRANSACTION_REQUEST', props: { chainId: `${options?.chainId || this.getChainId()}` } })
512
+
488
513
  return this.send({ method: 'eth_sendTransaction', params: [extendedTxs] }, options?.chainId)
489
514
  }
490
515
 
package/src/init.ts CHANGED
@@ -40,6 +40,9 @@ export interface ProviderConfig {
40
40
 
41
41
  // transports for dapp to wallet jron-rpc communication
42
42
  transports?: MuxTransportTemplate
43
+
44
+ // analytics .... (default: true)
45
+ analytics?: boolean
43
46
  }
44
47
 
45
48
  export const DefaultProviderConfig = {
@@ -49,7 +52,8 @@ export const DefaultProviderConfig = {
49
52
  proxyTransport: { enabled: false }
50
53
  },
51
54
 
52
- defaultNetwork: 1
55
+ defaultNetwork: 1,
56
+ analytics: true
53
57
  }
54
58
 
55
59
  let sequenceWalletProvider: SequenceProvider | undefined
@@ -134,15 +138,12 @@ export const initWallet = (projectAccessKey: string, partialConfig?: Partial<Pro
134
138
  const itemStore = config.localStorage || useBestStore()
135
139
 
136
140
  // Create client, provider and return signer
137
- const client = new SequenceClient(
138
- config.transports,
139
- itemStore,
140
- {
141
- defaultChainId: defaultNetwork,
142
- defaultEIP6492: config.defaultEIP6492
143
- },
144
- projectAccessKey
145
- )
141
+ const client = new SequenceClient(config.transports, itemStore, {
142
+ defaultChainId: defaultNetwork,
143
+ defaultEIP6492: config.defaultEIP6492,
144
+ projectAccessKey: projectAccessKey,
145
+ analytics: config.analytics
146
+ })
146
147
 
147
148
  sequenceWalletProvider = new SequenceProvider(client, providerForChainId)
148
149
  return sequenceWalletProvider