@imtbl/sdk 0.1.10-alpha → 0.1.10-alpha.2

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.
@@ -1,7 +1,24 @@
1
- import { OrderbookModuleConfiguration } from 'config/config';
1
+ import { OrderbookOverrides } from 'config/config';
2
2
  import { ListingResult, ListListingsResult } from 'openapi/sdk';
3
3
  import { ListListingsParams, PrepareListingParams, PrepareListingResponse, CreateListingParams, FulfillOrderResponse, CancelOrderResponse } from 'types';
4
4
 
5
+ declare enum Environment {
6
+ PRODUCTION = "production",
7
+ SANDBOX = "sandbox"
8
+ }
9
+ declare class ImmutableConfiguration {
10
+ readonly environment: Environment;
11
+ readonly apiKey?: string;
12
+ constructor(options: {
13
+ environment: Environment;
14
+ apiKey?: string;
15
+ });
16
+ }
17
+ interface ModuleConfiguration<T> {
18
+ baseConfig: ImmutableConfiguration;
19
+ overrides?: T;
20
+ }
21
+
5
22
  /**
6
23
  * zkEVM orderbook SDK
7
24
  * @constructor
@@ -11,7 +28,7 @@ declare class Orderbook {
11
28
  private config;
12
29
  private apiClient;
13
30
  private seaport;
14
- constructor(config: OrderbookModuleConfiguration);
31
+ constructor(config: ModuleConfiguration<OrderbookOverrides>);
15
32
  /**
16
33
  * Get an order by ID
17
34
  * @param {string} listingId - The listingId to find.
package/dist/orderbook.js CHANGED
@@ -1,6 +1,8 @@
1
1
  import axios from 'axios';
2
2
  import FormData from 'form-data';
3
- import { utils, Contract, BigNumber, constants } from 'ethers';
3
+ import { SEAPORT_CONTRACT_VERSION_V1_4 as SEAPORT_CONTRACT_VERSION_V1_4$1, SEAPORT_CONTRACT_VERSION_V1_5 } from '@opensea/seaport-js/lib/constants';
4
+ import { providers, BigNumber, constants, utils, Contract } from 'ethers';
5
+ import dotenv from 'dotenv';
4
6
  import { Seaport as Seaport$1 } from '@opensea/seaport-js';
5
7
 
6
8
  class BaseHttpRequest {
@@ -387,86 +389,6 @@ class AxiosHttpRequest extends BaseHttpRequest {
387
389
  }
388
390
  }
389
391
 
390
- class ListingsService {
391
- httpRequest;
392
- constructor(httpRequest) {
393
- this.httpRequest = httpRequest;
394
- }
395
- /**
396
- * List all listings
397
- * List all listings
398
- * @returns ListListingsResult OK response.
399
- * @throws ApiError
400
- */
401
- listListings({ chainName, status, sellItemContractAddress, buyItemContractAddress, sellItemTokenId, pageSize, sortBy, sortDirection, pageCursor, }) {
402
- return this.httpRequest.request({
403
- method: 'GET',
404
- url: '/v1/chains/{chain_name}/orders/listings',
405
- path: {
406
- 'chain_name': chainName,
407
- },
408
- query: {
409
- 'status': status,
410
- 'sell_item_contract_address': sellItemContractAddress,
411
- 'buy_item_contract_address': buyItemContractAddress,
412
- 'sell_item_token_id': sellItemTokenId,
413
- 'page_size': pageSize,
414
- 'sort_by': sortBy,
415
- 'sort_direction': sortDirection,
416
- 'page_cursor': pageCursor,
417
- },
418
- errors: {
419
- 400: `Bad Request (400)`,
420
- 404: `The specified resource was not found (404)`,
421
- 500: `Internal Server Error (500)`,
422
- },
423
- });
424
- }
425
- /**
426
- * Create a listing
427
- * Create a listing
428
- * @returns ListingResult Created response.
429
- * @throws ApiError
430
- */
431
- createListing({ chainName, requestBody, }) {
432
- return this.httpRequest.request({
433
- method: 'POST',
434
- url: '/v1/chains/{chain_name}/orders/listings',
435
- path: {
436
- 'chain_name': chainName,
437
- },
438
- body: requestBody,
439
- mediaType: 'application/json',
440
- errors: {
441
- 400: `Bad Request (400)`,
442
- 404: `The specified resource was not found (404)`,
443
- 500: `Internal Server Error (500)`,
444
- },
445
- });
446
- }
447
- /**
448
- * Get a single listing by ID
449
- * Get a single listing by ID
450
- * @returns ListingResult OK response.
451
- * @throws ApiError
452
- */
453
- getListing({ chainName, listingId, }) {
454
- return this.httpRequest.request({
455
- method: 'GET',
456
- url: '/v1/chains/{chain_name}/orders/listings/{listing_id}',
457
- path: {
458
- 'chain_name': chainName,
459
- 'listing_id': listingId,
460
- },
461
- errors: {
462
- 400: `Bad Request (400)`,
463
- 404: `The specified resource was not found (404)`,
464
- 500: `Internal Server Error (500)`,
465
- },
466
- });
467
- }
468
- }
469
-
470
392
  class OrdersService {
471
393
  httpRequest;
472
394
  constructor(httpRequest) {
@@ -548,7 +470,6 @@ class OrdersService {
548
470
  }
549
471
 
550
472
  class OrderBookClient {
551
- listings;
552
473
  orders;
553
474
  request;
554
475
  constructor(config, HttpRequest = AxiosHttpRequest) {
@@ -563,7 +484,6 @@ class OrderBookClient {
563
484
  HEADERS: config?.HEADERS,
564
485
  ENCODE_PATH: config?.ENCODE_PATH,
565
486
  });
566
- this.listings = new ListingsService(this.request);
567
487
  this.orders = new OrdersService(this.request);
568
488
  }
569
489
  }
@@ -719,7 +639,7 @@ function mapImmutableOrderToSeaportOrderComponents(order, counter, zoneAddress)
719
639
  };
720
640
  }
721
641
  });
722
- const fees = order.buy_fees.map((fee) => ({
642
+ const fees = order.fees.map((fee) => ({
723
643
  startAmount: fee.amount,
724
644
  endAmount: fee.amount,
725
645
  itemType: order.buy[0].item_type === 'ERC20' ? ItemType.ERC20 : ItemType.NATIVE,
@@ -755,12 +675,12 @@ function mapImmutableOrderToSeaportOrderComponents(order, counter, zoneAddress)
755
675
  }
756
676
 
757
677
  class Seaport {
758
- seaport;
678
+ seaportLibFactory;
759
679
  provider;
760
680
  seaportContractAddress;
761
681
  zoneContractAddress;
762
- constructor(seaport, provider, seaportContractAddress, zoneContractAddress) {
763
- this.seaport = seaport;
682
+ constructor(seaportLibFactory, provider, seaportContractAddress, zoneContractAddress) {
683
+ this.seaportLibFactory = seaportLibFactory;
764
684
  this.provider = provider;
765
685
  this.seaportContractAddress = seaportContractAddress;
766
686
  this.zoneContractAddress = zoneContractAddress;
@@ -784,12 +704,13 @@ class Seaport {
784
704
  unsignedApprovalTransaction: approvalTransaction,
785
705
  typedOrderMessageForSigning: await this.getTypedDataFromOrderComponents(orderComponents),
786
706
  orderComponents,
787
- orderHash: await this.seaport.getOrderHash(orderComponents),
707
+ orderHash: this.getSeaportLib().getOrderHash(orderComponents),
788
708
  };
789
709
  }
790
710
  async fulfilOrder(order, account) {
791
711
  const orderComponents = await this.mapImmutableOrderToSeaportOrderComponents(order);
792
- const { actions } = await this.seaport.fulfillOrders({
712
+ const seaportLib = this.getSeaportLib(order);
713
+ const { actions } = await seaportLib.fulfillOrders({
793
714
  accountAddress: account,
794
715
  fulfillOrderDetails: [{
795
716
  order: {
@@ -818,15 +739,17 @@ class Seaport {
818
739
  }
819
740
  async cancelOrder(order, account) {
820
741
  const orderComponents = await this.mapImmutableOrderToSeaportOrderComponents(order);
821
- const cancellationTransaction = await this.seaport.cancelOrders([orderComponents], account);
742
+ const seaportLib = this.getSeaportLib(order);
743
+ const cancellationTransaction = await seaportLib.cancelOrders([orderComponents], account);
822
744
  return prepareTransaction(cancellationTransaction);
823
745
  }
824
- async mapImmutableOrderToSeaportOrderComponents(order) {
825
- const counterForOfferer = await this.seaport.getCounter(order.account_address);
826
- return mapImmutableOrderToSeaportOrderComponents(order, counterForOfferer.toString(), this.zoneContractAddress);
746
+ mapImmutableOrderToSeaportOrderComponents(order) {
747
+ const orderCounter = order.protocol_data.counter;
748
+ return mapImmutableOrderToSeaportOrderComponents(order, orderCounter, this.zoneContractAddress);
827
749
  }
828
750
  createSeaportOrder(offerer, listingItem, considerationItem, royaltyInfo, orderStart, orderExpiry) {
829
- return this.seaport.createOrder({
751
+ const seaportLib = this.getSeaportLib();
752
+ return seaportLib.createOrder({
830
753
  allowPartialFills: false,
831
754
  offer: [
832
755
  {
@@ -857,7 +780,7 @@ class Seaport {
857
780
  const { chainId } = await this.provider.getNetwork();
858
781
  const domainData = {
859
782
  name: SEAPORT_CONTRACT_NAME,
860
- version: SEAPORT_CONTRACT_VERSION_V1_4,
783
+ version: SEAPORT_CONTRACT_VERSION_V1_4$1,
861
784
  chainId,
862
785
  verifyingContract: this.seaportContractAddress,
863
786
  };
@@ -867,27 +790,13 @@ class Seaport {
867
790
  value: orderComponents,
868
791
  };
869
792
  }
870
- }
871
-
872
- class SeaportFactory {
873
- seaportContractAddress;
874
- zoneContractAddress;
875
- provider;
876
- seaport;
877
- constructor(seaportContractAddress, zoneContractAddress, provider) {
878
- this.seaportContractAddress = seaportContractAddress;
879
- this.zoneContractAddress = zoneContractAddress;
880
- this.provider = provider;
881
- this.seaport = new Seaport$1(provider, {
882
- seaportVersion: '1.4',
883
- balanceAndApprovalChecksOnOrderCreation: true,
884
- overrides: {
885
- contractAddress: seaportContractAddress,
886
- },
887
- });
888
- }
889
- create() {
890
- return new Seaport(this.seaport, this.provider, this.seaportContractAddress, this.zoneContractAddress);
793
+ getSeaportLib(order) {
794
+ const seaportAddress = order?.protocol_data?.seaport_address ?? this.seaportContractAddress;
795
+ let seaportVersion = SEAPORT_CONTRACT_VERSION_V1_4$1;
796
+ if (order?.protocol_data?.seaport_version === SEAPORT_CONTRACT_VERSION_V1_5) {
797
+ seaportVersion = SEAPORT_CONTRACT_VERSION_V1_5;
798
+ }
799
+ return this.seaportLibFactory.create(seaportVersion, seaportAddress);
891
800
  }
892
801
  }
893
802
 
@@ -941,7 +850,7 @@ class ImmutableApiClient {
941
850
  contract_address: orderComponents.consideration[0].token,
942
851
  },
943
852
  ],
944
- buy_fees: orderComponents.consideration.length > 1
853
+ fees: orderComponents.consideration.length > 1
945
854
  ? [
946
855
  {
947
856
  amount: orderComponents.consideration[1].startAmount,
@@ -990,6 +899,73 @@ class ImmutableApiClientFactory {
990
899
  }
991
900
  }
992
901
 
902
+ // eslint-disable-next-line
903
+ dotenv.config();
904
+ function getConfig() {
905
+ if (!process.env.ORDERBOOK_MR_API_URL
906
+ || !process.env.SEAPORT_CONTRACT_ADDRESS
907
+ || !process.env.ZONE_CONTRACT_ADDRESS) {
908
+ throw new Error('missing config');
909
+ }
910
+ return {
911
+ apiUrl: process.env.ORDERBOOK_MR_API_URL,
912
+ seaportContractAddress: process.env.SEAPORT_CONTRACT_ADDRESS,
913
+ zoneContractAddress: process.env.ZONE_CONTRACT_ADDRESS,
914
+ };
915
+ }
916
+
917
+ dotenv.config();
918
+ function getLocalhostProvider() {
919
+ const endpoint = process.env.LOCAL_RPC_ENDPOINT;
920
+ if (!endpoint) {
921
+ throw new Error('LOCAL_RPC_ENDPOINT not set');
922
+ }
923
+ return new providers.JsonRpcProvider(endpoint);
924
+ }
925
+
926
+ dotenv.config();
927
+
928
+ const LOCAL_CHAIN_NAME = 'imtbl-zkevm-local';
929
+ const DEVNET_CHAIN_NAME = 'imtbl-zkevm-devnet';
930
+ const TESTNET_CHAIN_NAME = 'imtbl-zkevm-testnet';
931
+ const MAINNET_CHAIN_NAME = 'imtbl-zkevm-mainnet';
932
+ function getOrderbookConfig(chainName) {
933
+ const localConfig = getConfig();
934
+ switch (chainName) {
935
+ case LOCAL_CHAIN_NAME:
936
+ return {
937
+ seaportContractAddress: localConfig.seaportContractAddress,
938
+ zoneContractAddress: localConfig.zoneContractAddress,
939
+ apiEndpoint: localConfig.apiUrl,
940
+ provider: getLocalhostProvider(),
941
+ };
942
+ case DEVNET_CHAIN_NAME:
943
+ return {
944
+ seaportContractAddress: '0x41388404Efb7a68Fd31d75CEf71dF91e2BDBa2fb',
945
+ zoneContractAddress: '0xCb5063b0c1dcF4f7fed8E7eaa79faf9859792767',
946
+ apiEndpoint: 'https://order-book-mr.dev.imtbl.com',
947
+ provider: new providers.JsonRpcProvider('https://zkevm-rpc.dev.x.immutable.com'),
948
+ };
949
+ case TESTNET_CHAIN_NAME:
950
+ return {
951
+ seaportContractAddress: '0x45E23dA18804F99Cf67408AeBE85F67c958381Ff',
952
+ zoneContractAddress: '0x25b00b7eb97eab6194798E9B8eF63Aa526D5bd7E',
953
+ apiEndpoint: 'https://order-book-mr.sandbox.imtbl.com',
954
+ provider: new providers.JsonRpcProvider('https://zkevm-rpc.sandbox.x.immutable.com'),
955
+ };
956
+ case MAINNET_CHAIN_NAME:
957
+ // not yet deployed
958
+ return {
959
+ seaportContractAddress: '',
960
+ zoneContractAddress: '',
961
+ apiEndpoint: 'https://order-book-mr.imtbl.com',
962
+ provider: new providers.JsonRpcProvider('https://zkevm-rpc.x.immutable.com'),
963
+ };
964
+ default:
965
+ return null;
966
+ }
967
+ }
968
+
993
969
  class ERC721 {
994
970
  erc721;
995
971
  constructor(erc721) {
@@ -1912,6 +1888,26 @@ class ERC721Factory {
1912
1888
  }
1913
1889
  }
1914
1890
 
1891
+ class SeaportLibFactory {
1892
+ defaultSeaportContractAddress;
1893
+ provider;
1894
+ constructor(defaultSeaportContractAddress, provider) {
1895
+ this.defaultSeaportContractAddress = defaultSeaportContractAddress;
1896
+ this.provider = provider;
1897
+ }
1898
+ create(orderSeaportVersion, orderSeaportAddress) {
1899
+ const seaportVersion = orderSeaportVersion ?? SEAPORT_CONTRACT_VERSION_V1_4$1;
1900
+ const seaportContractAddress = orderSeaportAddress ?? this.defaultSeaportContractAddress;
1901
+ return new Seaport$1(this.provider, {
1902
+ seaportVersion,
1903
+ balanceAndApprovalChecksOnOrderCreation: true,
1904
+ overrides: {
1905
+ contractAddress: seaportContractAddress,
1906
+ },
1907
+ });
1908
+ }
1909
+ }
1910
+
1915
1911
  /**
1916
1912
  * zkEVM orderbook SDK
1917
1913
  * @constructor
@@ -1923,8 +1919,8 @@ class Orderbook {
1923
1919
  seaport;
1924
1920
  constructor(config) {
1925
1921
  this.config = config;
1926
- // TODO: Move endpoint lookup to a map based on env. Just using override to get dev started
1927
- const apiEndpoint = config.overrides?.apiEndpoint;
1922
+ const orderbookConfig = getOrderbookConfig(config.overrides?.chainName);
1923
+ const apiEndpoint = orderbookConfig?.apiEndpoint;
1928
1924
  if (!apiEndpoint) {
1929
1925
  throw new Error('API endpoint must be provided as an override');
1930
1926
  }
@@ -1933,8 +1929,9 @@ class Orderbook {
1933
1929
  if (!chainName) {
1934
1930
  throw new Error('chainName must be provided as an override');
1935
1931
  }
1936
- this.apiClient = new ImmutableApiClientFactory(apiEndpoint, chainName, this.config.seaportContractAddress).create();
1937
- this.seaport = new SeaportFactory(this.config.seaportContractAddress, this.config.zoneContractAddress, this.config.provider).create();
1932
+ this.apiClient = new ImmutableApiClientFactory(apiEndpoint, chainName, orderbookConfig.seaportContractAddress).create();
1933
+ const seaportLibFactory = new SeaportLibFactory(orderbookConfig.seaportContractAddress, orderbookConfig.provider);
1934
+ this.seaport = new Seaport(seaportLibFactory, orderbookConfig.provider, orderbookConfig.seaportContractAddress, orderbookConfig.zoneContractAddress);
1938
1935
  }
1939
1936
  /**
1940
1937
  * Get an order by ID
@@ -1962,7 +1959,8 @@ class Orderbook {
1962
1959
  * the order components that can be submitted to `createListing` with a signature.
1963
1960
  */
1964
1961
  async prepareListing({ makerAddress, sell, buy, orderExpiry, }) {
1965
- const erc721 = new ERC721Factory(sell.contractAddress, this.config.provider).create();
1962
+ const orderbookConfig = getOrderbookConfig(this.config.overrides?.chainName);
1963
+ const erc721 = new ERC721Factory(sell.contractAddress, orderbookConfig.provider).create();
1966
1964
  const royaltyInfo = await erc721.royaltyInfo(sell.tokenId, buy.amount);
1967
1965
  return this.seaport.prepareSeaportOrder(makerAddress, sell, buy, royaltyInfo,
1968
1966
  // Default order start to now
package/dist/passport.js CHANGED
@@ -21,7 +21,7 @@ const createImmutableXConfiguration = ({ basePath, chainID, coreContractAddress,
21
21
  chainID,
22
22
  coreContractAddress,
23
23
  registrationContractAddress,
24
- sdkVersion: 'ts-immutable-sdk-0.1.10-alpha',
24
+ sdkVersion: 'ts-immutable-sdk-0.1.10-alpha.2',
25
25
  });
26
26
  /**
27
27
  * Sets `sdkVersion` at the time of build
@@ -4449,8 +4449,10 @@ class GuardianClient {
4449
4449
  }));
4450
4450
  this.imxEtherAddress = imxEtherAddress;
4451
4451
  }
4452
- async validate({ popupWindowSize, payloadHash }) {
4452
+ loading(popupWindowSize) {
4453
4453
  this.confirmationScreen.loading(popupWindowSize);
4454
+ }
4455
+ async validate({ payloadHash }) {
4454
4456
  const finallyFn = () => {
4455
4457
  this.confirmationScreen.closeWindow();
4456
4458
  };
@@ -4527,6 +4529,7 @@ async function exchangeTransfer({ user, starkSigner, request, exchangesApi, }) {
4527
4529
  const ERC721$1 = 'ERC721';
4528
4530
  async function createOrder({ starkSigner, user, request, ordersApi, guardianClient, }) {
4529
4531
  return withPassportError(async () => {
4532
+ guardianClient.loading();
4530
4533
  const { ethAddress } = user.imx;
4531
4534
  const amountSell = request.sell.type === ERC721$1 ? '1' : request.sell.amount;
4532
4535
  const amountBuy = request.buy.type === ERC721$1 ? '1' : request.buy.amount;
@@ -4578,6 +4581,7 @@ async function createOrder({ starkSigner, user, request, ordersApi, guardianClie
4578
4581
  }
4579
4582
  async function cancelOrder({ user, starkSigner, request, ordersApi, guardianClient, }) {
4580
4583
  return withPassportError(async () => {
4584
+ guardianClient.loading();
4581
4585
  const getSignableCancelOrderRequest = {
4582
4586
  order_id: request.order_id,
4583
4587
  };
@@ -4635,6 +4639,7 @@ async function registerPassport({ ethSigner, starkSigner, usersApi }, authorizat
4635
4639
 
4636
4640
  async function createTrade({ request, tradesApi, user, starkSigner, guardianClient, }) {
4637
4641
  return withPassportError(async () => {
4642
+ guardianClient.loading();
4638
4643
  const { ethAddress } = user.imx;
4639
4644
  const getSignableTradeRequest = {
4640
4645
  expiration_timestamp: request.expiration_timestamp,
@@ -4681,6 +4686,7 @@ async function createTrade({ request, tradesApi, user, starkSigner, guardianClie
4681
4686
  const ERC721 = 'ERC721';
4682
4687
  async function transfer({ request, transfersApi, starkSigner, user, guardianClient, }) {
4683
4688
  return withPassportError(async () => {
4689
+ guardianClient.loading();
4684
4690
  const transferAmount = request.type === ERC721 ? '1' : request.amount;
4685
4691
  const getSignableTransferRequest = {
4686
4692
  sender: user.imx.ethAddress,
@@ -4726,6 +4732,8 @@ async function transfer({ request, transfersApi, starkSigner, user, guardianClie
4726
4732
  }
4727
4733
  async function batchNftTransfer({ user, starkSigner, request, transfersApi, guardianClient, }) {
4728
4734
  return withPassportError(async () => {
4735
+ const popupWindowSize = { width: 480, height: 784 };
4736
+ guardianClient.loading(popupWindowSize);
4729
4737
  const { ethAddress } = user.imx;
4730
4738
  const signableRequests = request.map((nftTransfer) => ({
4731
4739
  amount: '1',
@@ -4747,10 +4755,8 @@ async function batchNftTransfer({ user, starkSigner, request, transfersApi, guar
4747
4755
  const signableResult = await transfersApi.getSignableTransfer({
4748
4756
  getSignableTransferRequestV2,
4749
4757
  }, { headers });
4750
- const popupWindowSize = { width: 480, height: 784 };
4751
4758
  await guardianClient.validate({
4752
4759
  payloadHash: signableResult.data.signable_responses[0]?.payload_hash,
4753
- popupWindowSize,
4754
4760
  });
4755
4761
  const requests = await Promise.all(signableResult.data.signable_responses.map(async (resp) => {
4756
4762
  const starkSignature = await starkSigner.signMessage(resp.payload_hash);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@imtbl/sdk",
3
3
  "description": "Immutable Unified SDK",
4
- "version": "0.1.10-alpha",
4
+ "version": "0.1.10-alpha.2",
5
5
  "author": "Immutable",
6
6
  "bugs": "https://github.com/immutable/ts-immutable-sdk/issues",
7
7
  "dependencies": {
@@ -85,6 +85,14 @@
85
85
  "types": "./dist/provider.d.ts",
86
86
  "import": "./dist/provider.js"
87
87
  },
88
+ "./checkout_sdk": {
89
+ "types": "./dist/checkout_sdk.d.ts",
90
+ "import": "./dist/checkout_sdk.js"
91
+ },
92
+ "./checkout_widgets": {
93
+ "types": "./dist/checkout_widgets.d.ts",
94
+ "import": "./dist/checkout_widgets.js"
95
+ },
88
96
  "./erc20": {
89
97
  "types": "./dist/erc20.d.ts",
90
98
  "import": "./dist/erc20.js"