@settlemint/sdk-portal 2.5.5 → 2.5.6
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/README.md +42 -42
- package/dist/browser/portal.js.map +1 -1
- package/dist/portal.cjs.map +1 -1
- package/dist/portal.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -601,7 +601,7 @@ console.log("Transaction hash:", result.StableCoinFactoryCreate?.transactionHash
|
|
|
601
601
|
|
|
602
602
|
> **createPortalClient**\<`Setup`\>(`options`, `clientOptions?`): `object`
|
|
603
603
|
|
|
604
|
-
Defined in: [sdk/portal/src/portal.ts:72](https://github.com/settlemint/sdk/blob/v2.5.
|
|
604
|
+
Defined in: [sdk/portal/src/portal.ts:72](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/portal.ts#L72)
|
|
605
605
|
|
|
606
606
|
Creates a Portal GraphQL client with the provided configuration.
|
|
607
607
|
|
|
@@ -629,8 +629,8 @@ An object containing the configured GraphQL client and graphql helper function
|
|
|
629
629
|
|
|
630
630
|
| Name | Type | Defined in |
|
|
631
631
|
| ------ | ------ | ------ |
|
|
632
|
-
| `client` | `GraphQLClient` | [sdk/portal/src/portal.ts:76](https://github.com/settlemint/sdk/blob/v2.5.
|
|
633
|
-
| `graphql` | `initGraphQLTada`\<`Setup`\> | [sdk/portal/src/portal.ts:77](https://github.com/settlemint/sdk/blob/v2.5.
|
|
632
|
+
| `client` | `GraphQLClient` | [sdk/portal/src/portal.ts:76](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/portal.ts#L76) |
|
|
633
|
+
| `graphql` | `initGraphQLTada`\<`Setup`\> | [sdk/portal/src/portal.ts:77](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/portal.ts#L77) |
|
|
634
634
|
|
|
635
635
|
##### Throws
|
|
636
636
|
|
|
@@ -682,7 +682,7 @@ const result = await portalClient.request(query);
|
|
|
682
682
|
|
|
683
683
|
> **getWebsocketClient**(`options`): `Client`
|
|
684
684
|
|
|
685
|
-
Defined in: [sdk/portal/src/utils/websocket-client.ts:30](https://github.com/settlemint/sdk/blob/v2.5.
|
|
685
|
+
Defined in: [sdk/portal/src/utils/websocket-client.ts:30](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/utils/websocket-client.ts#L30)
|
|
686
686
|
|
|
687
687
|
Creates a GraphQL WebSocket client for the Portal API
|
|
688
688
|
|
|
@@ -715,7 +715,7 @@ const client = getWebsocketClient({
|
|
|
715
715
|
|
|
716
716
|
> **handleWalletVerificationChallenge**\<`Setup`\>(`options`): `Promise`\<\{ `challengeResponse`: `string`; `verificationId?`: `string`; \}\>
|
|
717
717
|
|
|
718
|
-
Defined in: [sdk/portal/src/utils/wallet-verification-challenge.ts:103](https://github.com/settlemint/sdk/blob/v2.5.
|
|
718
|
+
Defined in: [sdk/portal/src/utils/wallet-verification-challenge.ts:103](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/utils/wallet-verification-challenge.ts#L103)
|
|
719
719
|
|
|
720
720
|
Handles a wallet verification challenge by generating an appropriate response
|
|
721
721
|
|
|
@@ -768,7 +768,7 @@ const result = await handleWalletVerificationChallenge({
|
|
|
768
768
|
|
|
769
769
|
> **waitForTransactionReceipt**(`transactionHash`, `options`): `Promise`\<[`Transaction`](#transaction)\>
|
|
770
770
|
|
|
771
|
-
Defined in: [sdk/portal/src/utils/wait-for-transaction-receipt.ts:80](https://github.com/settlemint/sdk/blob/v2.5.
|
|
771
|
+
Defined in: [sdk/portal/src/utils/wait-for-transaction-receipt.ts:80](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L80)
|
|
772
772
|
|
|
773
773
|
Waits for a blockchain transaction receipt by subscribing to transaction updates via GraphQL.
|
|
774
774
|
This function polls until the transaction is confirmed or the timeout is reached.
|
|
@@ -806,7 +806,7 @@ const transaction = await waitForTransactionReceipt("0x123...", {
|
|
|
806
806
|
|
|
807
807
|
#### HandleWalletVerificationChallengeOptions\<Setup\>
|
|
808
808
|
|
|
809
|
-
Defined in: [sdk/portal/src/utils/wallet-verification-challenge.ts:64](https://github.com/settlemint/sdk/blob/v2.5.
|
|
809
|
+
Defined in: [sdk/portal/src/utils/wallet-verification-challenge.ts:64](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/utils/wallet-verification-challenge.ts#L64)
|
|
810
810
|
|
|
811
811
|
Options for handling a wallet verification challenge
|
|
812
812
|
|
|
@@ -820,18 +820,18 @@ Options for handling a wallet verification challenge
|
|
|
820
820
|
|
|
821
821
|
| Property | Type | Description | Defined in |
|
|
822
822
|
| ------ | ------ | ------ | ------ |
|
|
823
|
-
| <a id="code"></a> `code` | `string` \| `number` | The verification code provided by the user | [sdk/portal/src/utils/wallet-verification-challenge.ts:74](https://github.com/settlemint/sdk/blob/v2.5.
|
|
824
|
-
| <a id="portalclient"></a> `portalClient` | `GraphQLClient` | The portal client instance | [sdk/portal/src/utils/wallet-verification-challenge.ts:66](https://github.com/settlemint/sdk/blob/v2.5.
|
|
825
|
-
| <a id="portalgraphql"></a> `portalGraphql` | `initGraphQLTada`\<`Setup`\> | The GraphQL query builder | [sdk/portal/src/utils/wallet-verification-challenge.ts:68](https://github.com/settlemint/sdk/blob/v2.5.
|
|
826
|
-
| <a id="userwalletaddress"></a> `userWalletAddress` | `` `0x${string}` `` | The wallet address to verify | [sdk/portal/src/utils/wallet-verification-challenge.ts:72](https://github.com/settlemint/sdk/blob/v2.5.
|
|
827
|
-
| <a id="verificationid"></a> `verificationId` | `string` | The ID of the verification challenge | [sdk/portal/src/utils/wallet-verification-challenge.ts:70](https://github.com/settlemint/sdk/blob/v2.5.
|
|
828
|
-
| <a id="verificationtype"></a> `verificationType` | `"otp"` \| `"secret-code"` \| `"pincode"` | The type of verification being performed | [sdk/portal/src/utils/wallet-verification-challenge.ts:76](https://github.com/settlemint/sdk/blob/v2.5.
|
|
823
|
+
| <a id="code"></a> `code` | `string` \| `number` | The verification code provided by the user | [sdk/portal/src/utils/wallet-verification-challenge.ts:74](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/utils/wallet-verification-challenge.ts#L74) |
|
|
824
|
+
| <a id="portalclient"></a> `portalClient` | `GraphQLClient` | The portal client instance | [sdk/portal/src/utils/wallet-verification-challenge.ts:66](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/utils/wallet-verification-challenge.ts#L66) |
|
|
825
|
+
| <a id="portalgraphql"></a> `portalGraphql` | `initGraphQLTada`\<`Setup`\> | The GraphQL query builder | [sdk/portal/src/utils/wallet-verification-challenge.ts:68](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/utils/wallet-verification-challenge.ts#L68) |
|
|
826
|
+
| <a id="userwalletaddress"></a> `userWalletAddress` | `` `0x${string}` `` | The wallet address to verify | [sdk/portal/src/utils/wallet-verification-challenge.ts:72](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/utils/wallet-verification-challenge.ts#L72) |
|
|
827
|
+
| <a id="verificationid"></a> `verificationId` | `string` | The ID of the verification challenge | [sdk/portal/src/utils/wallet-verification-challenge.ts:70](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/utils/wallet-verification-challenge.ts#L70) |
|
|
828
|
+
| <a id="verificationtype"></a> `verificationType` | `"otp"` \| `"secret-code"` \| `"pincode"` | The type of verification being performed | [sdk/portal/src/utils/wallet-verification-challenge.ts:76](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/utils/wallet-verification-challenge.ts#L76) |
|
|
829
829
|
|
|
830
830
|
***
|
|
831
831
|
|
|
832
832
|
#### Transaction
|
|
833
833
|
|
|
834
|
-
Defined in: [sdk/portal/src/utils/wait-for-transaction-receipt.ts:34](https://github.com/settlemint/sdk/blob/v2.5.
|
|
834
|
+
Defined in: [sdk/portal/src/utils/wait-for-transaction-receipt.ts:34](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L34)
|
|
835
835
|
|
|
836
836
|
Represents the structure of a blockchain transaction with its receipt
|
|
837
837
|
|
|
@@ -839,18 +839,18 @@ Represents the structure of a blockchain transaction with its receipt
|
|
|
839
839
|
|
|
840
840
|
| Property | Type | Description | Defined in |
|
|
841
841
|
| ------ | ------ | ------ | ------ |
|
|
842
|
-
| <a id="address"></a> `address` | `string` | The contract address involved in the transaction | [sdk/portal/src/utils/wait-for-transaction-receipt.ts:43](https://github.com/settlemint/sdk/blob/v2.5.
|
|
843
|
-
| <a id="createdat"></a> `createdAt` | `string` | Timestamp when the transaction was created | [sdk/portal/src/utils/wait-for-transaction-receipt.ts:41](https://github.com/settlemint/sdk/blob/v2.5.
|
|
844
|
-
| <a id="from"></a> `from` | `string` | The sender address (duplicate of receipt.from) | [sdk/portal/src/utils/wait-for-transaction-receipt.ts:39](https://github.com/settlemint/sdk/blob/v2.5.
|
|
845
|
-
| <a id="functionname"></a> `functionName` | `string` | The name of the function called in the transaction | [sdk/portal/src/utils/wait-for-transaction-receipt.ts:45](https://github.com/settlemint/sdk/blob/v2.5.
|
|
846
|
-
| <a id="iscontract"></a> `isContract` | `boolean` | Whether the transaction is a contract deployment | [sdk/portal/src/utils/wait-for-transaction-receipt.ts:47](https://github.com/settlemint/sdk/blob/v2.5.
|
|
847
|
-
| <a id="transactionhash"></a> `transactionHash` | `string` | The hash of the transaction (duplicate of receipt.transactionHash) | [sdk/portal/src/utils/wait-for-transaction-receipt.ts:37](https://github.com/settlemint/sdk/blob/v2.5.
|
|
842
|
+
| <a id="address"></a> `address` | `string` | The contract address involved in the transaction | [sdk/portal/src/utils/wait-for-transaction-receipt.ts:43](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L43) |
|
|
843
|
+
| <a id="createdat"></a> `createdAt` | `string` | Timestamp when the transaction was created | [sdk/portal/src/utils/wait-for-transaction-receipt.ts:41](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L41) |
|
|
844
|
+
| <a id="from"></a> `from` | `string` | The sender address (duplicate of receipt.from) | [sdk/portal/src/utils/wait-for-transaction-receipt.ts:39](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L39) |
|
|
845
|
+
| <a id="functionname"></a> `functionName` | `string` | The name of the function called in the transaction | [sdk/portal/src/utils/wait-for-transaction-receipt.ts:45](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L45) |
|
|
846
|
+
| <a id="iscontract"></a> `isContract` | `boolean` | Whether the transaction is a contract deployment | [sdk/portal/src/utils/wait-for-transaction-receipt.ts:47](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L47) |
|
|
847
|
+
| <a id="transactionhash"></a> `transactionHash` | `string` | The hash of the transaction (duplicate of receipt.transactionHash) | [sdk/portal/src/utils/wait-for-transaction-receipt.ts:37](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L37) |
|
|
848
848
|
|
|
849
849
|
***
|
|
850
850
|
|
|
851
851
|
#### TransactionEvent
|
|
852
852
|
|
|
853
|
-
Defined in: [sdk/portal/src/utils/wait-for-transaction-receipt.ts:8](https://github.com/settlemint/sdk/blob/v2.5.
|
|
853
|
+
Defined in: [sdk/portal/src/utils/wait-for-transaction-receipt.ts:8](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L8)
|
|
854
854
|
|
|
855
855
|
Represents an event emitted during a transaction execution
|
|
856
856
|
|
|
@@ -858,15 +858,15 @@ Represents an event emitted during a transaction execution
|
|
|
858
858
|
|
|
859
859
|
| Property | Type | Description | Defined in |
|
|
860
860
|
| ------ | ------ | ------ | ------ |
|
|
861
|
-
| <a id="args"></a> `args` | `Record`\<`string`, `unknown`\> | The arguments emitted by the event | [sdk/portal/src/utils/wait-for-transaction-receipt.ts:12](https://github.com/settlemint/sdk/blob/v2.5.
|
|
862
|
-
| <a id="eventname"></a> `eventName` | `string` | The name of the event that was emitted | [sdk/portal/src/utils/wait-for-transaction-receipt.ts:10](https://github.com/settlemint/sdk/blob/v2.5.
|
|
863
|
-
| <a id="topics"></a> `topics` | `` `0x${string}` ``[] | Indexed event parameters used for filtering and searching | [sdk/portal/src/utils/wait-for-transaction-receipt.ts:14](https://github.com/settlemint/sdk/blob/v2.5.
|
|
861
|
+
| <a id="args"></a> `args` | `Record`\<`string`, `unknown`\> | The arguments emitted by the event | [sdk/portal/src/utils/wait-for-transaction-receipt.ts:12](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L12) |
|
|
862
|
+
| <a id="eventname"></a> `eventName` | `string` | The name of the event that was emitted | [sdk/portal/src/utils/wait-for-transaction-receipt.ts:10](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L10) |
|
|
863
|
+
| <a id="topics"></a> `topics` | `` `0x${string}` ``[] | Indexed event parameters used for filtering and searching | [sdk/portal/src/utils/wait-for-transaction-receipt.ts:14](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L14) |
|
|
864
864
|
|
|
865
865
|
***
|
|
866
866
|
|
|
867
867
|
#### TransactionReceipt
|
|
868
868
|
|
|
869
|
-
Defined in: [sdk/portal/src/utils/wait-for-transaction-receipt.ts:20](https://github.com/settlemint/sdk/blob/v2.5.
|
|
869
|
+
Defined in: [sdk/portal/src/utils/wait-for-transaction-receipt.ts:20](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L20)
|
|
870
870
|
|
|
871
871
|
Represents the structure of a blockchain transaction receipt
|
|
872
872
|
|
|
@@ -878,16 +878,16 @@ Represents the structure of a blockchain transaction receipt
|
|
|
878
878
|
|
|
879
879
|
| Property | Type | Description | Overrides | Defined in |
|
|
880
880
|
| ------ | ------ | ------ | ------ | ------ |
|
|
881
|
-
| <a id="contractaddress"></a> `contractAddress` | `` `0x${string}` `` | The address of the contract deployed in the transaction | `TransactionReceiptViem.contractAddress` | [sdk/portal/src/utils/wait-for-transaction-receipt.ts:28](https://github.com/settlemint/sdk/blob/v2.5.
|
|
882
|
-
| <a id="events"></a> `events` | [`TransactionEvent`](#transactionevent)[] | Array of events emitted during the transaction | - | [sdk/portal/src/utils/wait-for-transaction-receipt.ts:26](https://github.com/settlemint/sdk/blob/v2.5.
|
|
883
|
-
| <a id="revertreason"></a> `revertReason` | `string` | The raw reason for transaction reversion, if applicable | - | [sdk/portal/src/utils/wait-for-transaction-receipt.ts:22](https://github.com/settlemint/sdk/blob/v2.5.
|
|
884
|
-
| <a id="revertreasondecoded"></a> `revertReasonDecoded` | `string` | Human-readable version of the revert reason | - | [sdk/portal/src/utils/wait-for-transaction-receipt.ts:24](https://github.com/settlemint/sdk/blob/v2.5.
|
|
881
|
+
| <a id="contractaddress"></a> `contractAddress` | `` `0x${string}` `` | The address of the contract deployed in the transaction | `TransactionReceiptViem.contractAddress` | [sdk/portal/src/utils/wait-for-transaction-receipt.ts:28](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L28) |
|
|
882
|
+
| <a id="events"></a> `events` | [`TransactionEvent`](#transactionevent)[] | Array of events emitted during the transaction | - | [sdk/portal/src/utils/wait-for-transaction-receipt.ts:26](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L26) |
|
|
883
|
+
| <a id="revertreason"></a> `revertReason` | `string` | The raw reason for transaction reversion, if applicable | - | [sdk/portal/src/utils/wait-for-transaction-receipt.ts:22](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L22) |
|
|
884
|
+
| <a id="revertreasondecoded"></a> `revertReasonDecoded` | `string` | Human-readable version of the revert reason | - | [sdk/portal/src/utils/wait-for-transaction-receipt.ts:24](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L24) |
|
|
885
885
|
|
|
886
886
|
***
|
|
887
887
|
|
|
888
888
|
#### WaitForTransactionReceiptOptions
|
|
889
889
|
|
|
890
|
-
Defined in: [sdk/portal/src/utils/wait-for-transaction-receipt.ts:57](https://github.com/settlemint/sdk/blob/v2.5.
|
|
890
|
+
Defined in: [sdk/portal/src/utils/wait-for-transaction-receipt.ts:57](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L57)
|
|
891
891
|
|
|
892
892
|
Options for waiting for a transaction receipt
|
|
893
893
|
|
|
@@ -899,15 +899,15 @@ Options for waiting for a transaction receipt
|
|
|
899
899
|
|
|
900
900
|
| Property | Type | Description | Inherited from | Defined in |
|
|
901
901
|
| ------ | ------ | ------ | ------ | ------ |
|
|
902
|
-
| <a id="accesstoken"></a> `accessToken?` | `string` | The access token for authentication with the Portal API | [`WebsocketClientOptions`](#websocketclientoptions).[`accessToken`](#accesstoken-1) | [sdk/portal/src/utils/websocket-client.ts:14](https://github.com/settlemint/sdk/blob/v2.5.
|
|
903
|
-
| <a id="portalgraphqlendpoint"></a> `portalGraphqlEndpoint` | `string` | The GraphQL endpoint URL for the Portal API | [`WebsocketClientOptions`](#websocketclientoptions).[`portalGraphqlEndpoint`](#portalgraphqlendpoint-1) | [sdk/portal/src/utils/websocket-client.ts:10](https://github.com/settlemint/sdk/blob/v2.5.
|
|
904
|
-
| <a id="timeout"></a> `timeout?` | `number` | Optional timeout in milliseconds before the operation fails | - | [sdk/portal/src/utils/wait-for-transaction-receipt.ts:59](https://github.com/settlemint/sdk/blob/v2.5.
|
|
902
|
+
| <a id="accesstoken"></a> `accessToken?` | `string` | The access token for authentication with the Portal API | [`WebsocketClientOptions`](#websocketclientoptions).[`accessToken`](#accesstoken-1) | [sdk/portal/src/utils/websocket-client.ts:14](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/utils/websocket-client.ts#L14) |
|
|
903
|
+
| <a id="portalgraphqlendpoint"></a> `portalGraphqlEndpoint` | `string` | The GraphQL endpoint URL for the Portal API | [`WebsocketClientOptions`](#websocketclientoptions).[`portalGraphqlEndpoint`](#portalgraphqlendpoint-1) | [sdk/portal/src/utils/websocket-client.ts:10](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/utils/websocket-client.ts#L10) |
|
|
904
|
+
| <a id="timeout"></a> `timeout?` | `number` | Optional timeout in milliseconds before the operation fails | - | [sdk/portal/src/utils/wait-for-transaction-receipt.ts:59](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L59) |
|
|
905
905
|
|
|
906
906
|
***
|
|
907
907
|
|
|
908
908
|
#### WebsocketClientOptions
|
|
909
909
|
|
|
910
|
-
Defined in: [sdk/portal/src/utils/websocket-client.ts:6](https://github.com/settlemint/sdk/blob/v2.5.
|
|
910
|
+
Defined in: [sdk/portal/src/utils/websocket-client.ts:6](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/utils/websocket-client.ts#L6)
|
|
911
911
|
|
|
912
912
|
Options for the GraphQL WebSocket client
|
|
913
913
|
|
|
@@ -919,8 +919,8 @@ Options for the GraphQL WebSocket client
|
|
|
919
919
|
|
|
920
920
|
| Property | Type | Description | Defined in |
|
|
921
921
|
| ------ | ------ | ------ | ------ |
|
|
922
|
-
| <a id="accesstoken-1"></a> `accessToken?` | `string` | The access token for authentication with the Portal API | [sdk/portal/src/utils/websocket-client.ts:14](https://github.com/settlemint/sdk/blob/v2.5.
|
|
923
|
-
| <a id="portalgraphqlendpoint-1"></a> `portalGraphqlEndpoint` | `string` | The GraphQL endpoint URL for the Portal API | [sdk/portal/src/utils/websocket-client.ts:10](https://github.com/settlemint/sdk/blob/v2.5.
|
|
922
|
+
| <a id="accesstoken-1"></a> `accessToken?` | `string` | The access token for authentication with the Portal API | [sdk/portal/src/utils/websocket-client.ts:14](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/utils/websocket-client.ts#L14) |
|
|
923
|
+
| <a id="portalgraphqlendpoint-1"></a> `portalGraphqlEndpoint` | `string` | The GraphQL endpoint URL for the Portal API | [sdk/portal/src/utils/websocket-client.ts:10](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/utils/websocket-client.ts#L10) |
|
|
924
924
|
|
|
925
925
|
### Type Aliases
|
|
926
926
|
|
|
@@ -928,7 +928,7 @@ Options for the GraphQL WebSocket client
|
|
|
928
928
|
|
|
929
929
|
> **ClientOptions** = `object`
|
|
930
930
|
|
|
931
|
-
Defined in: [sdk/portal/src/portal.ts:25](https://github.com/settlemint/sdk/blob/v2.5.
|
|
931
|
+
Defined in: [sdk/portal/src/portal.ts:25](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/portal.ts#L25)
|
|
932
932
|
|
|
933
933
|
Type representing the validated client options.
|
|
934
934
|
|
|
@@ -936,9 +936,9 @@ Type representing the validated client options.
|
|
|
936
936
|
|
|
937
937
|
| Name | Type | Default value | Defined in |
|
|
938
938
|
| ------ | ------ | ------ | ------ |
|
|
939
|
-
| <a id="accesstoken-2"></a> `accessToken?` | `string` | - | [sdk/portal/src/portal.ts:18](https://github.com/settlemint/sdk/blob/v2.5.
|
|
940
|
-
| <a id="cache"></a> `cache?` | `"default"` \| `"force-cache"` \| `"no-cache"` \| `"no-store"` \| `"only-if-cached"` \| `"reload"` | - | [sdk/portal/src/portal.ts:19](https://github.com/settlemint/sdk/blob/v2.5.
|
|
941
|
-
| <a id="instance"></a> `instance` | `string` | `UrlOrPathSchema` | [sdk/portal/src/portal.ts:17](https://github.com/settlemint/sdk/blob/v2.5.
|
|
939
|
+
| <a id="accesstoken-2"></a> `accessToken?` | `string` | - | [sdk/portal/src/portal.ts:18](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/portal.ts#L18) |
|
|
940
|
+
| <a id="cache"></a> `cache?` | `"default"` \| `"force-cache"` \| `"no-cache"` \| `"no-store"` \| `"only-if-cached"` \| `"reload"` | - | [sdk/portal/src/portal.ts:19](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/portal.ts#L19) |
|
|
941
|
+
| <a id="instance"></a> `instance` | `string` | `UrlOrPathSchema` | [sdk/portal/src/portal.ts:17](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/portal.ts#L17) |
|
|
942
942
|
|
|
943
943
|
***
|
|
944
944
|
|
|
@@ -946,7 +946,7 @@ Type representing the validated client options.
|
|
|
946
946
|
|
|
947
947
|
> **RequestConfig** = `ConstructorParameters`\<*typeof* `GraphQLClient`\>\[`1`\]
|
|
948
948
|
|
|
949
|
-
Defined in: [sdk/portal/src/portal.ts:11](https://github.com/settlemint/sdk/blob/v2.5.
|
|
949
|
+
Defined in: [sdk/portal/src/portal.ts:11](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/portal.ts#L11)
|
|
950
950
|
|
|
951
951
|
Configuration options for the GraphQL client, excluding 'url' and 'exchanges'.
|
|
952
952
|
|
|
@@ -956,7 +956,7 @@ Configuration options for the GraphQL client, excluding 'url' and 'exchanges'.
|
|
|
956
956
|
|
|
957
957
|
> `const` **ClientOptionsSchema**: `ZodObject`\<[`ClientOptions`](#clientoptions)\>
|
|
958
958
|
|
|
959
|
-
Defined in: [sdk/portal/src/portal.ts:16](https://github.com/settlemint/sdk/blob/v2.5.
|
|
959
|
+
Defined in: [sdk/portal/src/portal.ts:16](https://github.com/settlemint/sdk/blob/v2.5.6/sdk/portal/src/portal.ts#L16)
|
|
960
960
|
|
|
961
961
|
Schema for validating Portal client configuration options.
|
|
962
962
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"portal.js","names":["url: URL","transactionHash: string","options: WaitForTransactionReceiptOptions","timeout: number","subscription: AsyncIterableIterator<FormattedExecutionResult<GetTransactionResponse, unknown>>","message: string","code: string","pincode: string","salt: string","challenge: string","options: ClientOptions","clientOptions?: RequestConfig"],"sources":["../../src/utils/websocket-client.ts","../../src/utils/wait-for-transaction-receipt.ts","../../src/utils/wallet-verification-challenge.ts","../../src/portal.ts"],"sourcesContent":["import { createClient } from \"graphql-ws\";\n\n/**\n * Options for the GraphQL WebSocket client\n */\nexport interface WebsocketClientOptions {\n /**\n * The GraphQL endpoint URL for the Portal API\n */\n portalGraphqlEndpoint: string;\n /**\n * The access token for authentication with the Portal API\n */\n accessToken?: string;\n}\n\n/**\n * Creates a GraphQL WebSocket client for the Portal API\n *\n * @param {WebsocketClientOptions} options - The options for the client\n * @returns {Client} The GraphQL WebSocket client\n * @example\n * import { getWebsocketClient } from \"@settlemint/sdk-portal\";\n *\n * const client = getWebsocketClient({\n * portalGraphqlEndpoint: \"https://portal.settlemint.com/graphql\",\n * accessToken: \"your-access-token\",\n * });\n */\nexport function getWebsocketClient({ portalGraphqlEndpoint, accessToken }: WebsocketClientOptions) {\n if (!portalGraphqlEndpoint) {\n throw new Error(\"portalGraphqlEndpoint is required\");\n }\n const graphqlEndpoint = setWsProtocol(new URL(portalGraphqlEndpoint));\n return createClient({\n url: accessToken\n ? `${graphqlEndpoint.protocol}//${graphqlEndpoint.host}/${accessToken}${graphqlEndpoint.pathname}${graphqlEndpoint.search}`\n : graphqlEndpoint.toString(),\n });\n}\n\nfunction setWsProtocol(url: URL) {\n if (url.protocol === \"ws:\" || url.protocol === \"wss:\") {\n return url;\n }\n if (url.protocol === \"http:\") {\n url.protocol = \"ws:\";\n } else {\n url.protocol = \"wss:\";\n }\n return url;\n}\n","import type { FormattedExecutionResult } from \"graphql-ws\";\nimport type { Address, Hex, TransactionReceipt as TransactionReceiptViem } from \"viem\";\nimport { type WebsocketClientOptions, getWebsocketClient } from \"./websocket-client.js\";\n\n/**\n * Represents an event emitted during a transaction execution\n */\nexport interface TransactionEvent {\n /** The name of the event that was emitted */\n eventName: string;\n /** The arguments emitted by the event */\n args: Record<string, unknown>;\n /** Indexed event parameters used for filtering and searching */\n topics: Hex[];\n}\n\n/**\n * Represents the structure of a blockchain transaction receipt\n */\nexport interface TransactionReceipt extends TransactionReceiptViem<string, number, \"Success\" | \"Reverted\"> {\n /** The raw reason for transaction reversion, if applicable */\n revertReason: string;\n /** Human-readable version of the revert reason */\n revertReasonDecoded: string;\n /** Array of events emitted during the transaction */\n events: TransactionEvent[];\n /** The address of the contract deployed in the transaction */\n contractAddress: Address;\n}\n\n/**\n * Represents the structure of a blockchain transaction with its receipt\n */\nexport interface Transaction {\n receipt: TransactionReceipt;\n /** The hash of the transaction (duplicate of receipt.transactionHash) */\n transactionHash: string;\n /** The sender address (duplicate of receipt.from) */\n from: string;\n /** Timestamp when the transaction was created */\n createdAt: string;\n /** The contract address involved in the transaction */\n address: string;\n /** The name of the function called in the transaction */\n functionName: string;\n /** Whether the transaction is a contract deployment */\n isContract: boolean;\n}\n\ninterface GetTransactionResponse {\n getTransaction: Transaction;\n}\n\n/**\n * Options for waiting for a transaction receipt\n */\nexport interface WaitForTransactionReceiptOptions extends WebsocketClientOptions {\n /** Optional timeout in milliseconds before the operation fails */\n timeout?: number;\n}\n\n/**\n * Waits for a blockchain transaction receipt by subscribing to transaction updates via GraphQL.\n * This function polls until the transaction is confirmed or the timeout is reached.\n *\n * @param transactionHash - The hash of the transaction to wait for\n * @param options - Configuration options for the waiting process\n * @returns The transaction details including receipt information when the transaction is confirmed\n * @throws Error if the transaction receipt cannot be retrieved within the specified timeout\n *\n * @example\n * import { waitForTransactionReceipt } from \"@settlemint/sdk-portal\";\n *\n * const transaction = await waitForTransactionReceipt(\"0x123...\", {\n * portalGraphqlEndpoint: \"https://example.settlemint.com/graphql\",\n * accessToken: \"your-access-token\",\n * timeout: 30000 // 30 seconds timeout\n * });\n */\nexport async function waitForTransactionReceipt(transactionHash: string, options: WaitForTransactionReceiptOptions) {\n const wsClient = getWebsocketClient(options);\n const subscription = wsClient.iterate<GetTransactionResponse>({\n query: `subscription getTransaction($transactionHash: String!) {\n getTransaction(transactionHash: $transactionHash) {\n receipt {\n transactionHash\n to\n status\n from\n type\n revertReason\n revertReasonDecoded\n logs\n events\n contractAddress\n }\n transactionHash\n from\n createdAt\n address\n functionName\n isContract\n }\n }`,\n variables: { transactionHash },\n });\n const promises = [getTransactionFromSubscription(subscription)];\n if (options.timeout) {\n promises.push(createTimeoutPromise(options.timeout));\n }\n\n return Promise.race(promises);\n}\n\nfunction createTimeoutPromise(timeout: number): Promise<never> {\n return new Promise((_, reject) => {\n setTimeout(() => reject(new Error(\"Transaction receipt not found\")), timeout);\n });\n}\n\nasync function getTransactionFromSubscription(\n subscription: AsyncIterableIterator<FormattedExecutionResult<GetTransactionResponse, unknown>>,\n): Promise<Transaction> {\n for await (const result of subscription) {\n if (result?.data?.getTransaction?.receipt) {\n return result.data.getTransaction;\n }\n }\n throw new Error(\"No transaction found\");\n}\n","import { createHash } from \"node:crypto\";\nimport type { AbstractSetupSchema, initGraphQLTada } from \"gql.tada\";\nimport type { GraphQLClient } from \"graphql-request\";\nimport type { Address } from \"viem\";\n\n/**\n * Custom error class for challenge-related errors\n */\nexport class ChallengeError extends Error {\n readonly code: string;\n\n constructor(message: string, code: string) {\n super(message);\n this.name = \"ChallengeError\";\n this.code = code;\n }\n}\n\n/**\n * Represents the structure of a wallet verification challenge\n */\ninterface WalletVerificationChallenge {\n challenge: {\n secret: string;\n salt: string;\n };\n id: string;\n name: string;\n verificationType: string;\n}\n\n/**\n * Response type for the CreateWalletVerificationChallenges mutation\n */\ninterface CreateWalletVerificationChallengesResponse {\n createWalletVerificationChallenges: WalletVerificationChallenge[];\n}\n\n/**\n * Hashes a pincode with a salt using SHA-256\n * @param pincode - The pincode to hash\n * @param salt - The salt to use in hashing\n * @returns The hashed pincode as a hex string\n */\nfunction hashPincode(pincode: string, salt: string): string {\n return createHash(\"sha256\").update(`${salt}${pincode}`).digest(\"hex\");\n}\n\n/**\n * Generates a challenge response by combining a hashed pincode with a challenge\n * @param pincode - The user's pincode\n * @param salt - The salt provided in the challenge\n * @param challenge - The challenge secret\n * @returns The challenge response as a hex string\n */\nfunction generateResponse(pincode: string, salt: string, challenge: string): string {\n const hashedPincode = hashPincode(pincode, salt);\n return createHash(\"sha256\").update(`${hashedPincode}_${challenge}`).digest(\"hex\");\n}\n\n/**\n * Options for handling a wallet verification challenge\n */\nexport interface HandleWalletVerificationChallengeOptions<Setup extends AbstractSetupSchema> {\n /** The portal client instance */\n portalClient: GraphQLClient;\n /** The GraphQL query builder */\n portalGraphql: initGraphQLTada<Setup>;\n /** The ID of the verification challenge */\n verificationId: string;\n /** The wallet address to verify */\n userWalletAddress: Address;\n /** The verification code provided by the user */\n code: string | number;\n /** The type of verification being performed */\n verificationType: \"otp\" | \"secret-code\" | \"pincode\";\n}\n\n/**\n * Handles a wallet verification challenge by generating an appropriate response\n *\n * @param options - The options for handling the wallet verification challenge\n * @returns Promise resolving to an object containing the challenge response and optionally the verification ID\n * @throws {ChallengeError} If the challenge cannot be created or is invalid\n * @example\n * import { createPortalClient } from \"@settlemint/sdk-portal\";\n * import { handleWalletVerificationChallenge } from \"@settlemint/sdk-portal\";\n *\n * const { client, graphql } = createPortalClient({\n * instance: \"https://portal.example.com/graphql\",\n * accessToken: \"your-access-token\"\n * });\n *\n * const result = await handleWalletVerificationChallenge({\n * portalClient: client,\n * portalGraphql: graphql,\n * verificationId: \"verification-123\",\n * userWalletAddress: \"0x123...\",\n * code: \"123456\",\n * verificationType: \"otp\"\n * });\n */\nexport async function handleWalletVerificationChallenge<const Setup extends AbstractSetupSchema>({\n portalClient,\n portalGraphql,\n verificationId,\n userWalletAddress,\n code,\n verificationType,\n}: HandleWalletVerificationChallengeOptions<Setup>): Promise<{\n challengeResponse: string;\n verificationId?: string;\n}> {\n try {\n if (verificationType === \"otp\") {\n return {\n challengeResponse: code.toString(),\n verificationId,\n };\n }\n\n if (verificationType === \"secret-code\") {\n // Add - separator to the code\n const formattedCode = code.toString().replace(/(.{5})(?=.)/, \"$1-\");\n return {\n challengeResponse: formattedCode,\n verificationId,\n };\n }\n\n const verificationChallenges = await portalClient.request<CreateWalletVerificationChallengesResponse>(\n portalGraphql(`\n mutation CreateWalletVerificationChallenges($userWalletAddress: String!, $verificationId: String!) {\n createWalletVerificationChallenges(userWalletAddress: $userWalletAddress, verificationId: $verificationId) {\n challenge\n id\n name\n verificationType\n }\n }\n `),\n {\n userWalletAddress,\n verificationId,\n },\n );\n\n if (!verificationChallenges.createWalletVerificationChallenges?.length) {\n throw new ChallengeError(\"No verification challenges received\", \"NO_CHALLENGES\");\n }\n\n const walletVerificationChallenge = verificationChallenges.createWalletVerificationChallenges.find(\n (challenge) => challenge.id === verificationId,\n );\n\n if (!walletVerificationChallenge?.challenge?.secret || !walletVerificationChallenge?.challenge?.salt) {\n throw new ChallengeError(\"Invalid challenge format\", \"INVALID_CHALLENGE\");\n }\n\n const { secret, salt } = walletVerificationChallenge.challenge;\n const challengeResponse = generateResponse(code.toString(), salt, secret);\n return {\n challengeResponse,\n verificationId,\n };\n } catch (error) {\n if (error instanceof ChallengeError) {\n throw error;\n }\n throw new ChallengeError(\"Failed to process wallet verification challenge\", \"CHALLENGE_PROCESSING_ERROR\");\n }\n}\n","import { appendHeaders } from \"@settlemint/sdk-utils/http\";\nimport { ensureServer } from \"@settlemint/sdk-utils/runtime\";\nimport { ApplicationAccessTokenSchema, UrlOrPathSchema, validate } from \"@settlemint/sdk-utils/validation\";\nimport { type AbstractSetupSchema, initGraphQLTada } from \"gql.tada\";\nimport { GraphQLClient } from \"graphql-request\";\nimport { z } from \"zod\";\n\n/**\n * Configuration options for the GraphQL client, excluding 'url' and 'exchanges'.\n */\nexport type RequestConfig = ConstructorParameters<typeof GraphQLClient>[1];\n\n/**\n * Schema for validating Portal client configuration options.\n */\nexport const ClientOptionsSchema = z.object({\n instance: UrlOrPathSchema,\n accessToken: ApplicationAccessTokenSchema.optional(),\n cache: z.enum([\"default\", \"force-cache\", \"no-cache\", \"no-store\", \"only-if-cached\", \"reload\"]).optional(),\n});\n\n/**\n * Type representing the validated client options.\n */\nexport type ClientOptions = z.infer<typeof ClientOptionsSchema>;\n\n/**\n * Creates a Portal GraphQL client with the provided configuration.\n *\n * @param options - Configuration options for the Portal client\n * @param clientOptions - Additional GraphQL client configuration options\n * @returns An object containing the configured GraphQL client and graphql helper function\n * @throws If the provided options fail validation\n *\n * @example\n * import { createPortalClient } from \"@settlemint/sdk-portal\";\n * import { loadEnv } from \"@settlemint/sdk-utils/environment\";\n * import { createLogger, requestLogger } from \"@settlemint/sdk-utils/logging\";\n * import type { introspection } from \"@schemas/portal-env\";\n *\n * const env = await loadEnv(false, false);\n * const logger = createLogger();\n *\n * const { client: portalClient, graphql: portalGraphql } = createPortalClient<{\n * introspection: introspection;\n * disableMasking: true;\n * scalars: {\n * // Change unknown to the type you are using to store metadata\n * JSON: unknown;\n * };\n * }>(\n * {\n * instance: env.SETTLEMINT_PORTAL_GRAPHQL_ENDPOINT!,\n * accessToken: env.SETTLEMINT_ACCESS_TOKEN!,\n * },\n * {\n * fetch: requestLogger(logger, \"portal\", fetch) as typeof fetch,\n * },\n * );\n *\n * // Making GraphQL queries\n * const query = portalGraphql(`\n * query GetPendingTransactions {\n * getPendingTransactions {\n * count\n * }\n * }\n * `);\n *\n * const result = await portalClient.request(query);\n */\nexport function createPortalClient<const Setup extends AbstractSetupSchema>(\n options: ClientOptions,\n clientOptions?: RequestConfig,\n): {\n client: GraphQLClient;\n graphql: initGraphQLTada<Setup>;\n} {\n ensureServer();\n const validatedOptions = validate(ClientOptionsSchema, options);\n const graphql = initGraphQLTada<Setup>();\n const fullUrl = new URL(validatedOptions.instance).toString();\n\n return {\n client: new GraphQLClient(fullUrl, {\n ...clientOptions,\n headers: appendHeaders(clientOptions?.headers, { \"x-auth-token\": validatedOptions.accessToken }),\n }),\n graphql,\n };\n}\n\nexport type { FragmentOf, ResultOf, VariablesOf } from \"gql.tada\";\nexport { readFragment } from \"gql.tada\";\nexport {\n type Transaction,\n type TransactionEvent,\n type TransactionReceipt,\n type WaitForTransactionReceiptOptions,\n waitForTransactionReceipt,\n} from \"./utils/wait-for-transaction-receipt.js\";\nexport {\n type HandleWalletVerificationChallengeOptions,\n handleWalletVerificationChallenge,\n} from \"./utils/wallet-verification-challenge.js\";\nexport { getWebsocketClient, type WebsocketClientOptions } from \"./utils/websocket-client.js\";\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"portal.js","names":["url: URL","transactionHash: string","options: WaitForTransactionReceiptOptions","timeout: number","subscription: AsyncIterableIterator<FormattedExecutionResult<GetTransactionResponse, unknown>>","message: string","code: string","pincode: string","salt: string","challenge: string","options: ClientOptions","clientOptions?: RequestConfig"],"sources":["../../src/utils/websocket-client.ts","../../src/utils/wait-for-transaction-receipt.ts","../../src/utils/wallet-verification-challenge.ts","../../src/portal.ts"],"sourcesContent":["import { createClient } from \"graphql-ws\";\n\n/**\n * Options for the GraphQL WebSocket client\n */\nexport interface WebsocketClientOptions {\n /**\n * The GraphQL endpoint URL for the Portal API\n */\n portalGraphqlEndpoint: string;\n /**\n * The access token for authentication with the Portal API\n */\n accessToken?: string;\n}\n\n/**\n * Creates a GraphQL WebSocket client for the Portal API\n *\n * @param {WebsocketClientOptions} options - The options for the client\n * @returns {Client} The GraphQL WebSocket client\n * @example\n * import { getWebsocketClient } from \"@settlemint/sdk-portal\";\n *\n * const client = getWebsocketClient({\n * portalGraphqlEndpoint: \"https://portal.settlemint.com/graphql\",\n * accessToken: \"your-access-token\",\n * });\n */\nexport function getWebsocketClient({ portalGraphqlEndpoint, accessToken }: WebsocketClientOptions) {\n if (!portalGraphqlEndpoint) {\n throw new Error(\"portalGraphqlEndpoint is required\");\n }\n const graphqlEndpoint = setWsProtocol(new URL(portalGraphqlEndpoint));\n return createClient({\n url: accessToken\n ? `${graphqlEndpoint.protocol}//${graphqlEndpoint.host}/${accessToken}${graphqlEndpoint.pathname}${graphqlEndpoint.search}`\n : graphqlEndpoint.toString(),\n });\n}\n\nfunction setWsProtocol(url: URL) {\n if (url.protocol === \"ws:\" || url.protocol === \"wss:\") {\n return url;\n }\n if (url.protocol === \"http:\") {\n url.protocol = \"ws:\";\n } else {\n url.protocol = \"wss:\";\n }\n return url;\n}\n","import type { FormattedExecutionResult } from \"graphql-ws\";\nimport type { Address, Hex, TransactionReceipt as TransactionReceiptViem } from \"viem\";\nimport { type WebsocketClientOptions, getWebsocketClient } from \"./websocket-client.js\";\n\n/**\n * Represents an event emitted during a transaction execution\n */\nexport interface TransactionEvent {\n /** The name of the event that was emitted */\n eventName: string;\n /** The arguments emitted by the event */\n args: Record<string, unknown>;\n /** Indexed event parameters used for filtering and searching */\n topics: Hex[];\n}\n\n/**\n * Represents the structure of a blockchain transaction receipt\n */\nexport interface TransactionReceipt extends TransactionReceiptViem<string, number, \"Success\" | \"Reverted\"> {\n /** The raw reason for transaction reversion, if applicable */\n revertReason: string;\n /** Human-readable version of the revert reason */\n revertReasonDecoded: string;\n /** Array of events emitted during the transaction */\n events: TransactionEvent[];\n /** The address of the contract deployed in the transaction */\n contractAddress: Address;\n}\n\n/**\n * Represents the structure of a blockchain transaction with its receipt\n */\nexport interface Transaction {\n receipt: TransactionReceipt;\n /** The hash of the transaction (duplicate of receipt.transactionHash) */\n transactionHash: string;\n /** The sender address (duplicate of receipt.from) */\n from: string;\n /** Timestamp when the transaction was created */\n createdAt: string;\n /** The contract address involved in the transaction */\n address: string;\n /** The name of the function called in the transaction */\n functionName: string;\n /** Whether the transaction is a contract deployment */\n isContract: boolean;\n}\n\ninterface GetTransactionResponse {\n getTransaction: Transaction;\n}\n\n/**\n * Options for waiting for a transaction receipt\n */\nexport interface WaitForTransactionReceiptOptions extends WebsocketClientOptions {\n /** Optional timeout in milliseconds before the operation fails */\n timeout?: number;\n}\n\n/**\n * Waits for a blockchain transaction receipt by subscribing to transaction updates via GraphQL.\n * This function polls until the transaction is confirmed or the timeout is reached.\n *\n * @param transactionHash - The hash of the transaction to wait for\n * @param options - Configuration options for the waiting process\n * @returns The transaction details including receipt information when the transaction is confirmed\n * @throws Error if the transaction receipt cannot be retrieved within the specified timeout\n *\n * @example\n * import { waitForTransactionReceipt } from \"@settlemint/sdk-portal\";\n *\n * const transaction = await waitForTransactionReceipt(\"0x123...\", {\n * portalGraphqlEndpoint: \"https://example.settlemint.com/graphql\",\n * accessToken: \"your-access-token\",\n * timeout: 30000 // 30 seconds timeout\n * });\n */\nexport async function waitForTransactionReceipt(transactionHash: string, options: WaitForTransactionReceiptOptions) {\n const wsClient = getWebsocketClient(options);\n const subscription = wsClient.iterate<GetTransactionResponse>({\n query: `subscription getTransaction($transactionHash: String!) {\n getTransaction(transactionHash: $transactionHash) {\n receipt {\n transactionHash\n to\n status\n from\n type\n revertReason\n revertReasonDecoded\n logs\n events\n contractAddress\n }\n transactionHash\n from\n createdAt\n address\n functionName\n isContract\n }\n }`,\n variables: { transactionHash },\n });\n const promises = [getTransactionFromSubscription(subscription)];\n if (options.timeout) {\n promises.push(createTimeoutPromise(options.timeout));\n }\n\n return Promise.race(promises);\n}\n\nfunction createTimeoutPromise(timeout: number): Promise<never> {\n return new Promise((_, reject) => {\n setTimeout(() => reject(new Error(\"Transaction receipt not found\")), timeout);\n });\n}\n\nasync function getTransactionFromSubscription(\n subscription: AsyncIterableIterator<FormattedExecutionResult<GetTransactionResponse, unknown>>,\n): Promise<Transaction> {\n for await (const result of subscription) {\n if (result?.data?.getTransaction?.receipt) {\n return result.data.getTransaction;\n }\n }\n throw new Error(\"No transaction found\");\n}\n","import { createHash } from \"node:crypto\";\nimport type { AbstractSetupSchema, initGraphQLTada } from \"gql.tada\";\nimport type { GraphQLClient } from \"graphql-request\";\nimport type { Address } from \"viem\";\n\n/**\n * Custom error class for challenge-related errors\n */\nexport class ChallengeError extends Error {\n readonly code: string;\n\n constructor(message: string, code: string) {\n super(message);\n this.name = \"ChallengeError\";\n this.code = code;\n }\n}\n\n/**\n * Represents the structure of a wallet verification challenge\n */\ninterface WalletVerificationChallenge {\n challenge: {\n secret: string;\n salt: string;\n };\n id: string;\n name: string;\n verificationType: string;\n}\n\n/**\n * Response type for the CreateWalletVerificationChallenges mutation\n */\ninterface CreateWalletVerificationChallengesResponse {\n createWalletVerificationChallenges: WalletVerificationChallenge[];\n}\n\n/**\n * Hashes a pincode with a salt using SHA-256\n * @param pincode - The pincode to hash\n * @param salt - The salt to use in hashing\n * @returns The hashed pincode as a hex string\n */\nfunction hashPincode(pincode: string, salt: string): string {\n return createHash(\"sha256\").update(`${salt}${pincode}`).digest(\"hex\");\n}\n\n/**\n * Generates a challenge response by combining a hashed pincode with a challenge\n * @param pincode - The user's pincode\n * @param salt - The salt provided in the challenge\n * @param challenge - The challenge secret\n * @returns The challenge response as a hex string\n */\nfunction generateResponse(pincode: string, salt: string, challenge: string): string {\n const hashedPincode = hashPincode(pincode, salt);\n return createHash(\"sha256\").update(`${hashedPincode}_${challenge}`).digest(\"hex\");\n}\n\n/**\n * Options for handling a wallet verification challenge\n */\nexport interface HandleWalletVerificationChallengeOptions<Setup extends AbstractSetupSchema> {\n /** The portal client instance */\n portalClient: GraphQLClient;\n /** The GraphQL query builder */\n portalGraphql: initGraphQLTada<Setup>;\n /** The ID of the verification challenge */\n verificationId: string;\n /** The wallet address to verify */\n userWalletAddress: Address;\n /** The verification code provided by the user */\n code: string | number;\n /** The type of verification being performed */\n verificationType: \"otp\" | \"secret-code\" | \"pincode\";\n}\n\n/**\n * Handles a wallet verification challenge by generating an appropriate response\n *\n * @param options - The options for handling the wallet verification challenge\n * @returns Promise resolving to an object containing the challenge response and optionally the verification ID\n * @throws {ChallengeError} If the challenge cannot be created or is invalid\n * @example\n * import { createPortalClient } from \"@settlemint/sdk-portal\";\n * import { handleWalletVerificationChallenge } from \"@settlemint/sdk-portal\";\n *\n * const { client, graphql } = createPortalClient({\n * instance: \"https://portal.example.com/graphql\",\n * accessToken: \"your-access-token\"\n * });\n *\n * const result = await handleWalletVerificationChallenge({\n * portalClient: client,\n * portalGraphql: graphql,\n * verificationId: \"verification-123\",\n * userWalletAddress: \"0x123...\",\n * code: \"123456\",\n * verificationType: \"otp\"\n * });\n */\nexport async function handleWalletVerificationChallenge<const Setup extends AbstractSetupSchema>({\n portalClient,\n portalGraphql,\n verificationId,\n userWalletAddress,\n code,\n verificationType,\n}: HandleWalletVerificationChallengeOptions<Setup>): Promise<{\n challengeResponse: string;\n verificationId?: string;\n}> {\n try {\n if (verificationType === \"otp\") {\n return {\n challengeResponse: code.toString(),\n verificationId,\n };\n }\n\n if (verificationType === \"secret-code\") {\n // Add - separator to the code\n const formattedCode = code.toString().replace(/(.{5})(?=.)/, \"$1-\");\n return {\n challengeResponse: formattedCode,\n verificationId,\n };\n }\n\n const verificationChallenges = await portalClient.request<CreateWalletVerificationChallengesResponse>(\n portalGraphql(`\n mutation CreateWalletVerificationChallenges($userWalletAddress: String!, $verificationId: String!) {\n createWalletVerificationChallenges(userWalletAddress: $userWalletAddress, verificationId: $verificationId) {\n challenge\n id\n name\n verificationType\n }\n }\n `),\n {\n userWalletAddress,\n verificationId,\n },\n );\n\n if (!verificationChallenges.createWalletVerificationChallenges?.length) {\n throw new ChallengeError(\"No verification challenges received\", \"NO_CHALLENGES\");\n }\n\n const walletVerificationChallenge = verificationChallenges.createWalletVerificationChallenges.find(\n (challenge) => challenge.id === verificationId,\n );\n\n if (!walletVerificationChallenge?.challenge?.secret || !walletVerificationChallenge?.challenge?.salt) {\n throw new ChallengeError(\"Invalid challenge format\", \"INVALID_CHALLENGE\");\n }\n\n const { secret, salt } = walletVerificationChallenge.challenge;\n const challengeResponse = generateResponse(code.toString(), salt, secret);\n return {\n challengeResponse,\n verificationId,\n };\n } catch (error) {\n if (error instanceof ChallengeError) {\n throw error;\n }\n throw new ChallengeError(\"Failed to process wallet verification challenge\", \"CHALLENGE_PROCESSING_ERROR\");\n }\n}\n","import { appendHeaders } from \"@settlemint/sdk-utils/http\";\nimport { ensureServer } from \"@settlemint/sdk-utils/runtime\";\nimport { ApplicationAccessTokenSchema, UrlOrPathSchema, validate } from \"@settlemint/sdk-utils/validation\";\nimport { type AbstractSetupSchema, initGraphQLTada } from \"gql.tada\";\nimport { GraphQLClient } from \"graphql-request\";\nimport { z } from \"zod\";\n\n/**\n * Configuration options for the GraphQL client, excluding 'url' and 'exchanges'.\n */\nexport type RequestConfig = ConstructorParameters<typeof GraphQLClient>[1];\n\n/**\n * Schema for validating Portal client configuration options.\n */\nexport const ClientOptionsSchema = z.object({\n instance: UrlOrPathSchema,\n accessToken: ApplicationAccessTokenSchema.optional(),\n cache: z.enum([\"default\", \"force-cache\", \"no-cache\", \"no-store\", \"only-if-cached\", \"reload\"]).optional(),\n});\n\n/**\n * Type representing the validated client options.\n */\nexport type ClientOptions = z.infer<typeof ClientOptionsSchema>;\n\n/**\n * Creates a Portal GraphQL client with the provided configuration.\n *\n * @param options - Configuration options for the Portal client\n * @param clientOptions - Additional GraphQL client configuration options\n * @returns An object containing the configured GraphQL client and graphql helper function\n * @throws If the provided options fail validation\n *\n * @example\n * import { createPortalClient } from \"@settlemint/sdk-portal\";\n * import { loadEnv } from \"@settlemint/sdk-utils/environment\";\n * import { createLogger, requestLogger } from \"@settlemint/sdk-utils/logging\";\n * import type { introspection } from \"@schemas/portal-env\";\n *\n * const env = await loadEnv(false, false);\n * const logger = createLogger();\n *\n * const { client: portalClient, graphql: portalGraphql } = createPortalClient<{\n * introspection: introspection;\n * disableMasking: true;\n * scalars: {\n * // Change unknown to the type you are using to store metadata\n * JSON: unknown;\n * };\n * }>(\n * {\n * instance: env.SETTLEMINT_PORTAL_GRAPHQL_ENDPOINT!,\n * accessToken: env.SETTLEMINT_ACCESS_TOKEN!,\n * },\n * {\n * fetch: requestLogger(logger, \"portal\", fetch) as typeof fetch,\n * },\n * );\n *\n * // Making GraphQL queries\n * const query = portalGraphql(`\n * query GetPendingTransactions {\n * getPendingTransactions {\n * count\n * }\n * }\n * `);\n *\n * const result = await portalClient.request(query);\n */\nexport function createPortalClient<const Setup extends AbstractSetupSchema>(\n options: ClientOptions,\n clientOptions?: RequestConfig,\n): {\n client: GraphQLClient;\n graphql: initGraphQLTada<Setup>;\n} {\n ensureServer();\n const validatedOptions = validate(ClientOptionsSchema, options);\n const graphql = initGraphQLTada<Setup>();\n const fullUrl = new URL(validatedOptions.instance).toString();\n\n return {\n client: new GraphQLClient(fullUrl, {\n ...clientOptions,\n headers: appendHeaders(clientOptions?.headers, { \"x-auth-token\": validatedOptions.accessToken }),\n }),\n graphql,\n };\n}\n\nexport type { FragmentOf, ResultOf, VariablesOf } from \"gql.tada\";\nexport { readFragment } from \"gql.tada\";\nexport {\n type Transaction,\n type TransactionEvent,\n type TransactionReceipt,\n type WaitForTransactionReceiptOptions,\n waitForTransactionReceipt,\n} from \"./utils/wait-for-transaction-receipt.js\";\nexport {\n type HandleWalletVerificationChallengeOptions,\n handleWalletVerificationChallenge,\n} from \"./utils/wallet-verification-challenge.js\";\nexport { getWebsocketClient, type WebsocketClientOptions } from \"./utils/websocket-client.js\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AA6BA,SAAgB,mBAAmB,EAAE,uBAAuB,aAAqC,EAAE;AACjG,KAAI,CAAC,uBAAuB;AAC1B,QAAM,IAAI,MAAM;CACjB;CACD,MAAM,kBAAkB,cAAc,IAAI,IAAI,uBAAuB;AACrE,QAAO,aAAa,EAClB,KAAK,cACD,GAAG,gBAAgB,SAAS,EAAE,EAAE,gBAAgB,KAAK,CAAC,EAAE,cAAc,gBAAgB,WAAW,gBAAgB,QAAQ,GACzH,gBAAgB,UAAU,CAC/B,EAAC;AACH;AAED,SAAS,cAAcA,KAAU;AAC/B,KAAI,IAAI,aAAa,SAAS,IAAI,aAAa,QAAQ;AACrD,SAAO;CACR;AACD,KAAI,IAAI,aAAa,SAAS;EAC5B,IAAI,WAAW;CAChB,OAAM;EACL,IAAI,WAAW;CAChB;AACD,QAAO;AACR;;;;;;;;;;;;;;;;;;;;;;AC4BD,eAAsB,0BAA0BC,iBAAyBC,SAA2C;CAClH,MAAM,WAAW,mBAAmB,QAAQ;CAC5C,MAAM,eAAe,SAAS,QAAgC;EAC5D,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;OAqBL,CAAC;EACJ,WAAW,EAAE,gBAAiB;CAC/B,EAAC;CACF,MAAM,WAAW,CAAC,+BAA+B,aAAa,AAAC;AAC/D,KAAI,QAAQ,SAAS;EACnB,SAAS,KAAK,qBAAqB,QAAQ,QAAQ,CAAC;CACrD;AAED,QAAO,QAAQ,KAAK,SAAS;AAC9B;AAED,SAAS,qBAAqBC,SAAiC;AAC7D,QAAO,IAAI,QAAQ,CAAC,GAAG,WAAW;EAChC,WAAW,MAAM,OAAO,IAAI,MAAM,iCAAiC,EAAE,QAAQ;CAC9E;AACF;AAED,eAAe,+BACbC,cACsB;AACtB,YAAW,MAAM,UAAU,cAAc;AACvC,MAAI,QAAQ,MAAM,gBAAgB,SAAS;AACzC,UAAO,OAAO,KAAK;EACpB;CACF;AACD,OAAM,IAAI,MAAM;AACjB;;;;;;;ACzHD,IAAa,iBAAb,cAAoC,MAAM;CACxC,AAAS;CAET,YAAYC,SAAiBC,MAAc;EACzC,MAAM,QAAQ;EACd,KAAK,OAAO;EACZ,KAAK,OAAO;CACb;AACF;;;;;;;AA4BD,SAAS,YAAYC,SAAiBC,MAAsB;AAC1D,QAAO,WAAW,SAAS,CAAC,OAAO,GAAG,OAAO,SAAS,CAAC,CAAC,OAAO,MAAM;AACtE;;;;;;;;AASD,SAAS,iBAAiBD,SAAiBC,MAAcC,WAA2B;CAClF,MAAM,gBAAgB,YAAY,SAAS,KAAK;AAChD,QAAO,WAAW,SAAS,CAAC,OAAO,GAAG,cAAc,CAAC,EAAE,WAAW,CAAC,CAAC,OAAO,MAAM;AAClF;;;;;;;;;;;;;;;;;;;;;;;;;AA4CD,eAAsB,kCAA2E,EAC/F,cACA,eACA,gBACA,mBACA,MACA,kBACgD,EAG/C;AACD,KAAI;AACF,MAAI,qBAAqB,OAAO;AAC9B,UAAO;IACL,mBAAmB,KAAK,UAAU;IAClC;GACD;EACF;AAED,MAAI,qBAAqB,eAAe;GAEtC,MAAM,gBAAgB,KAAK,UAAU,CAAC,QAAQ,eAAe,MAAM;AACnE,UAAO;IACL,mBAAmB;IACnB;GACD;EACF;EAED,MAAM,yBAAyB,MAAM,aAAa,QAChD,cAAc,CAAC;;;;;;;;;MASf,CAAC,CAAC,EACF;GACE;GACA;EACD,EACF;AAED,MAAI,CAAC,uBAAuB,oCAAoC,QAAQ;AACtE,SAAM,IAAI,eAAe,uCAAuC;EACjE;EAED,MAAM,8BAA8B,uBAAuB,mCAAmC,KAC5F,CAAC,cAAc,UAAU,OAAO,eACjC;AAED,MAAI,CAAC,6BAA6B,WAAW,UAAU,CAAC,6BAA6B,WAAW,MAAM;AACpG,SAAM,IAAI,eAAe,4BAA4B;EACtD;EAED,MAAM,EAAE,QAAQ,MAAM,GAAG,4BAA4B;EACrD,MAAM,oBAAoB,iBAAiB,KAAK,UAAU,EAAE,MAAM,OAAO;AACzE,SAAO;GACL;GACA;EACD;CACF,SAAQ,OAAO;AACd,MAAI,iBAAiB,gBAAgB;AACnC,SAAM;EACP;AACD,QAAM,IAAI,eAAe,mDAAmD;CAC7E;AACF;;;;;;;AC5JD,MAAa,sBAAsB,EAAE,OAAO;CAC1C,UAAU;CACV,aAAa,6BAA6B,UAAU;CACpD,OAAO,EAAE,KAAK;EAAC;EAAW;EAAe;EAAY;EAAY;EAAkB;CAAS,EAAC,CAAC,UAAU;AACzG,EAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoDF,SAAgB,mBACdC,SACAC,eAIA;CACA,cAAc;CACd,MAAM,mBAAmB,SAAS,qBAAqB,QAAQ;CAC/D,MAAM,UAAU,iBAAwB;CACxC,MAAM,UAAU,IAAI,IAAI,iBAAiB,UAAU,UAAU;AAE7D,QAAO;EACL,QAAQ,IAAI,cAAc,SAAS;GACjC,GAAG;GACH,SAAS,cAAc,eAAe,SAAS,EAAE,gBAAgB,iBAAiB,YAAa,EAAC;EACjG;EACD;CACD;AACF"}
|
package/dist/portal.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"portal.cjs","names":["url: URL","transactionHash: string","options: WaitForTransactionReceiptOptions","timeout: number","subscription: AsyncIterableIterator<FormattedExecutionResult<GetTransactionResponse, unknown>>","message: string","code: string","pincode: string","salt: string","challenge: string","UrlOrPathSchema","options: ClientOptions","clientOptions?: RequestConfig","GraphQLClient"],"sources":["../src/utils/websocket-client.ts","../src/utils/wait-for-transaction-receipt.ts","../src/utils/wallet-verification-challenge.ts","../src/portal.ts"],"sourcesContent":["import { createClient } from \"graphql-ws\";\n\n/**\n * Options for the GraphQL WebSocket client\n */\nexport interface WebsocketClientOptions {\n /**\n * The GraphQL endpoint URL for the Portal API\n */\n portalGraphqlEndpoint: string;\n /**\n * The access token for authentication with the Portal API\n */\n accessToken?: string;\n}\n\n/**\n * Creates a GraphQL WebSocket client for the Portal API\n *\n * @param {WebsocketClientOptions} options - The options for the client\n * @returns {Client} The GraphQL WebSocket client\n * @example\n * import { getWebsocketClient } from \"@settlemint/sdk-portal\";\n *\n * const client = getWebsocketClient({\n * portalGraphqlEndpoint: \"https://portal.settlemint.com/graphql\",\n * accessToken: \"your-access-token\",\n * });\n */\nexport function getWebsocketClient({ portalGraphqlEndpoint, accessToken }: WebsocketClientOptions) {\n if (!portalGraphqlEndpoint) {\n throw new Error(\"portalGraphqlEndpoint is required\");\n }\n const graphqlEndpoint = setWsProtocol(new URL(portalGraphqlEndpoint));\n return createClient({\n url: accessToken\n ? `${graphqlEndpoint.protocol}//${graphqlEndpoint.host}/${accessToken}${graphqlEndpoint.pathname}${graphqlEndpoint.search}`\n : graphqlEndpoint.toString(),\n });\n}\n\nfunction setWsProtocol(url: URL) {\n if (url.protocol === \"ws:\" || url.protocol === \"wss:\") {\n return url;\n }\n if (url.protocol === \"http:\") {\n url.protocol = \"ws:\";\n } else {\n url.protocol = \"wss:\";\n }\n return url;\n}\n","import type { FormattedExecutionResult } from \"graphql-ws\";\nimport type { Address, Hex, TransactionReceipt as TransactionReceiptViem } from \"viem\";\nimport { type WebsocketClientOptions, getWebsocketClient } from \"./websocket-client.js\";\n\n/**\n * Represents an event emitted during a transaction execution\n */\nexport interface TransactionEvent {\n /** The name of the event that was emitted */\n eventName: string;\n /** The arguments emitted by the event */\n args: Record<string, unknown>;\n /** Indexed event parameters used for filtering and searching */\n topics: Hex[];\n}\n\n/**\n * Represents the structure of a blockchain transaction receipt\n */\nexport interface TransactionReceipt extends TransactionReceiptViem<string, number, \"Success\" | \"Reverted\"> {\n /** The raw reason for transaction reversion, if applicable */\n revertReason: string;\n /** Human-readable version of the revert reason */\n revertReasonDecoded: string;\n /** Array of events emitted during the transaction */\n events: TransactionEvent[];\n /** The address of the contract deployed in the transaction */\n contractAddress: Address;\n}\n\n/**\n * Represents the structure of a blockchain transaction with its receipt\n */\nexport interface Transaction {\n receipt: TransactionReceipt;\n /** The hash of the transaction (duplicate of receipt.transactionHash) */\n transactionHash: string;\n /** The sender address (duplicate of receipt.from) */\n from: string;\n /** Timestamp when the transaction was created */\n createdAt: string;\n /** The contract address involved in the transaction */\n address: string;\n /** The name of the function called in the transaction */\n functionName: string;\n /** Whether the transaction is a contract deployment */\n isContract: boolean;\n}\n\ninterface GetTransactionResponse {\n getTransaction: Transaction;\n}\n\n/**\n * Options for waiting for a transaction receipt\n */\nexport interface WaitForTransactionReceiptOptions extends WebsocketClientOptions {\n /** Optional timeout in milliseconds before the operation fails */\n timeout?: number;\n}\n\n/**\n * Waits for a blockchain transaction receipt by subscribing to transaction updates via GraphQL.\n * This function polls until the transaction is confirmed or the timeout is reached.\n *\n * @param transactionHash - The hash of the transaction to wait for\n * @param options - Configuration options for the waiting process\n * @returns The transaction details including receipt information when the transaction is confirmed\n * @throws Error if the transaction receipt cannot be retrieved within the specified timeout\n *\n * @example\n * import { waitForTransactionReceipt } from \"@settlemint/sdk-portal\";\n *\n * const transaction = await waitForTransactionReceipt(\"0x123...\", {\n * portalGraphqlEndpoint: \"https://example.settlemint.com/graphql\",\n * accessToken: \"your-access-token\",\n * timeout: 30000 // 30 seconds timeout\n * });\n */\nexport async function waitForTransactionReceipt(transactionHash: string, options: WaitForTransactionReceiptOptions) {\n const wsClient = getWebsocketClient(options);\n const subscription = wsClient.iterate<GetTransactionResponse>({\n query: `subscription getTransaction($transactionHash: String!) {\n getTransaction(transactionHash: $transactionHash) {\n receipt {\n transactionHash\n to\n status\n from\n type\n revertReason\n revertReasonDecoded\n logs\n events\n contractAddress\n }\n transactionHash\n from\n createdAt\n address\n functionName\n isContract\n }\n }`,\n variables: { transactionHash },\n });\n const promises = [getTransactionFromSubscription(subscription)];\n if (options.timeout) {\n promises.push(createTimeoutPromise(options.timeout));\n }\n\n return Promise.race(promises);\n}\n\nfunction createTimeoutPromise(timeout: number): Promise<never> {\n return new Promise((_, reject) => {\n setTimeout(() => reject(new Error(\"Transaction receipt not found\")), timeout);\n });\n}\n\nasync function getTransactionFromSubscription(\n subscription: AsyncIterableIterator<FormattedExecutionResult<GetTransactionResponse, unknown>>,\n): Promise<Transaction> {\n for await (const result of subscription) {\n if (result?.data?.getTransaction?.receipt) {\n return result.data.getTransaction;\n }\n }\n throw new Error(\"No transaction found\");\n}\n","import { createHash } from \"node:crypto\";\nimport type { AbstractSetupSchema, initGraphQLTada } from \"gql.tada\";\nimport type { GraphQLClient } from \"graphql-request\";\nimport type { Address } from \"viem\";\n\n/**\n * Custom error class for challenge-related errors\n */\nexport class ChallengeError extends Error {\n readonly code: string;\n\n constructor(message: string, code: string) {\n super(message);\n this.name = \"ChallengeError\";\n this.code = code;\n }\n}\n\n/**\n * Represents the structure of a wallet verification challenge\n */\ninterface WalletVerificationChallenge {\n challenge: {\n secret: string;\n salt: string;\n };\n id: string;\n name: string;\n verificationType: string;\n}\n\n/**\n * Response type for the CreateWalletVerificationChallenges mutation\n */\ninterface CreateWalletVerificationChallengesResponse {\n createWalletVerificationChallenges: WalletVerificationChallenge[];\n}\n\n/**\n * Hashes a pincode with a salt using SHA-256\n * @param pincode - The pincode to hash\n * @param salt - The salt to use in hashing\n * @returns The hashed pincode as a hex string\n */\nfunction hashPincode(pincode: string, salt: string): string {\n return createHash(\"sha256\").update(`${salt}${pincode}`).digest(\"hex\");\n}\n\n/**\n * Generates a challenge response by combining a hashed pincode with a challenge\n * @param pincode - The user's pincode\n * @param salt - The salt provided in the challenge\n * @param challenge - The challenge secret\n * @returns The challenge response as a hex string\n */\nfunction generateResponse(pincode: string, salt: string, challenge: string): string {\n const hashedPincode = hashPincode(pincode, salt);\n return createHash(\"sha256\").update(`${hashedPincode}_${challenge}`).digest(\"hex\");\n}\n\n/**\n * Options for handling a wallet verification challenge\n */\nexport interface HandleWalletVerificationChallengeOptions<Setup extends AbstractSetupSchema> {\n /** The portal client instance */\n portalClient: GraphQLClient;\n /** The GraphQL query builder */\n portalGraphql: initGraphQLTada<Setup>;\n /** The ID of the verification challenge */\n verificationId: string;\n /** The wallet address to verify */\n userWalletAddress: Address;\n /** The verification code provided by the user */\n code: string | number;\n /** The type of verification being performed */\n verificationType: \"otp\" | \"secret-code\" | \"pincode\";\n}\n\n/**\n * Handles a wallet verification challenge by generating an appropriate response\n *\n * @param options - The options for handling the wallet verification challenge\n * @returns Promise resolving to an object containing the challenge response and optionally the verification ID\n * @throws {ChallengeError} If the challenge cannot be created or is invalid\n * @example\n * import { createPortalClient } from \"@settlemint/sdk-portal\";\n * import { handleWalletVerificationChallenge } from \"@settlemint/sdk-portal\";\n *\n * const { client, graphql } = createPortalClient({\n * instance: \"https://portal.example.com/graphql\",\n * accessToken: \"your-access-token\"\n * });\n *\n * const result = await handleWalletVerificationChallenge({\n * portalClient: client,\n * portalGraphql: graphql,\n * verificationId: \"verification-123\",\n * userWalletAddress: \"0x123...\",\n * code: \"123456\",\n * verificationType: \"otp\"\n * });\n */\nexport async function handleWalletVerificationChallenge<const Setup extends AbstractSetupSchema>({\n portalClient,\n portalGraphql,\n verificationId,\n userWalletAddress,\n code,\n verificationType,\n}: HandleWalletVerificationChallengeOptions<Setup>): Promise<{\n challengeResponse: string;\n verificationId?: string;\n}> {\n try {\n if (verificationType === \"otp\") {\n return {\n challengeResponse: code.toString(),\n verificationId,\n };\n }\n\n if (verificationType === \"secret-code\") {\n // Add - separator to the code\n const formattedCode = code.toString().replace(/(.{5})(?=.)/, \"$1-\");\n return {\n challengeResponse: formattedCode,\n verificationId,\n };\n }\n\n const verificationChallenges = await portalClient.request<CreateWalletVerificationChallengesResponse>(\n portalGraphql(`\n mutation CreateWalletVerificationChallenges($userWalletAddress: String!, $verificationId: String!) {\n createWalletVerificationChallenges(userWalletAddress: $userWalletAddress, verificationId: $verificationId) {\n challenge\n id\n name\n verificationType\n }\n }\n `),\n {\n userWalletAddress,\n verificationId,\n },\n );\n\n if (!verificationChallenges.createWalletVerificationChallenges?.length) {\n throw new ChallengeError(\"No verification challenges received\", \"NO_CHALLENGES\");\n }\n\n const walletVerificationChallenge = verificationChallenges.createWalletVerificationChallenges.find(\n (challenge) => challenge.id === verificationId,\n );\n\n if (!walletVerificationChallenge?.challenge?.secret || !walletVerificationChallenge?.challenge?.salt) {\n throw new ChallengeError(\"Invalid challenge format\", \"INVALID_CHALLENGE\");\n }\n\n const { secret, salt } = walletVerificationChallenge.challenge;\n const challengeResponse = generateResponse(code.toString(), salt, secret);\n return {\n challengeResponse,\n verificationId,\n };\n } catch (error) {\n if (error instanceof ChallengeError) {\n throw error;\n }\n throw new ChallengeError(\"Failed to process wallet verification challenge\", \"CHALLENGE_PROCESSING_ERROR\");\n }\n}\n","import { appendHeaders } from \"@settlemint/sdk-utils/http\";\nimport { ensureServer } from \"@settlemint/sdk-utils/runtime\";\nimport { ApplicationAccessTokenSchema, UrlOrPathSchema, validate } from \"@settlemint/sdk-utils/validation\";\nimport { type AbstractSetupSchema, initGraphQLTada } from \"gql.tada\";\nimport { GraphQLClient } from \"graphql-request\";\nimport { z } from \"zod\";\n\n/**\n * Configuration options for the GraphQL client, excluding 'url' and 'exchanges'.\n */\nexport type RequestConfig = ConstructorParameters<typeof GraphQLClient>[1];\n\n/**\n * Schema for validating Portal client configuration options.\n */\nexport const ClientOptionsSchema = z.object({\n instance: UrlOrPathSchema,\n accessToken: ApplicationAccessTokenSchema.optional(),\n cache: z.enum([\"default\", \"force-cache\", \"no-cache\", \"no-store\", \"only-if-cached\", \"reload\"]).optional(),\n});\n\n/**\n * Type representing the validated client options.\n */\nexport type ClientOptions = z.infer<typeof ClientOptionsSchema>;\n\n/**\n * Creates a Portal GraphQL client with the provided configuration.\n *\n * @param options - Configuration options for the Portal client\n * @param clientOptions - Additional GraphQL client configuration options\n * @returns An object containing the configured GraphQL client and graphql helper function\n * @throws If the provided options fail validation\n *\n * @example\n * import { createPortalClient } from \"@settlemint/sdk-portal\";\n * import { loadEnv } from \"@settlemint/sdk-utils/environment\";\n * import { createLogger, requestLogger } from \"@settlemint/sdk-utils/logging\";\n * import type { introspection } from \"@schemas/portal-env\";\n *\n * const env = await loadEnv(false, false);\n * const logger = createLogger();\n *\n * const { client: portalClient, graphql: portalGraphql } = createPortalClient<{\n * introspection: introspection;\n * disableMasking: true;\n * scalars: {\n * // Change unknown to the type you are using to store metadata\n * JSON: unknown;\n * };\n * }>(\n * {\n * instance: env.SETTLEMINT_PORTAL_GRAPHQL_ENDPOINT!,\n * accessToken: env.SETTLEMINT_ACCESS_TOKEN!,\n * },\n * {\n * fetch: requestLogger(logger, \"portal\", fetch) as typeof fetch,\n * },\n * );\n *\n * // Making GraphQL queries\n * const query = portalGraphql(`\n * query GetPendingTransactions {\n * getPendingTransactions {\n * count\n * }\n * }\n * `);\n *\n * const result = await portalClient.request(query);\n */\nexport function createPortalClient<const Setup extends AbstractSetupSchema>(\n options: ClientOptions,\n clientOptions?: RequestConfig,\n): {\n client: GraphQLClient;\n graphql: initGraphQLTada<Setup>;\n} {\n ensureServer();\n const validatedOptions = validate(ClientOptionsSchema, options);\n const graphql = initGraphQLTada<Setup>();\n const fullUrl = new URL(validatedOptions.instance).toString();\n\n return {\n client: new GraphQLClient(fullUrl, {\n ...clientOptions,\n headers: appendHeaders(clientOptions?.headers, { \"x-auth-token\": validatedOptions.accessToken }),\n }),\n graphql,\n };\n}\n\nexport type { FragmentOf, ResultOf, VariablesOf } from \"gql.tada\";\nexport { readFragment } from \"gql.tada\";\nexport {\n type Transaction,\n type TransactionEvent,\n type TransactionReceipt,\n type WaitForTransactionReceiptOptions,\n waitForTransactionReceipt,\n} from \"./utils/wait-for-transaction-receipt.js\";\nexport {\n type HandleWalletVerificationChallengeOptions,\n handleWalletVerificationChallenge,\n} from \"./utils/wallet-verification-challenge.js\";\nexport { getWebsocketClient, type WebsocketClientOptions } from \"./utils/websocket-client.js\";\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"portal.cjs","names":["url: URL","transactionHash: string","options: WaitForTransactionReceiptOptions","timeout: number","subscription: AsyncIterableIterator<FormattedExecutionResult<GetTransactionResponse, unknown>>","message: string","code: string","pincode: string","salt: string","challenge: string","z","UrlOrPathSchema","ApplicationAccessTokenSchema","options: ClientOptions","clientOptions?: RequestConfig","GraphQLClient"],"sources":["../src/utils/websocket-client.ts","../src/utils/wait-for-transaction-receipt.ts","../src/utils/wallet-verification-challenge.ts","../src/portal.ts"],"sourcesContent":["import { createClient } from \"graphql-ws\";\n\n/**\n * Options for the GraphQL WebSocket client\n */\nexport interface WebsocketClientOptions {\n /**\n * The GraphQL endpoint URL for the Portal API\n */\n portalGraphqlEndpoint: string;\n /**\n * The access token for authentication with the Portal API\n */\n accessToken?: string;\n}\n\n/**\n * Creates a GraphQL WebSocket client for the Portal API\n *\n * @param {WebsocketClientOptions} options - The options for the client\n * @returns {Client} The GraphQL WebSocket client\n * @example\n * import { getWebsocketClient } from \"@settlemint/sdk-portal\";\n *\n * const client = getWebsocketClient({\n * portalGraphqlEndpoint: \"https://portal.settlemint.com/graphql\",\n * accessToken: \"your-access-token\",\n * });\n */\nexport function getWebsocketClient({ portalGraphqlEndpoint, accessToken }: WebsocketClientOptions) {\n if (!portalGraphqlEndpoint) {\n throw new Error(\"portalGraphqlEndpoint is required\");\n }\n const graphqlEndpoint = setWsProtocol(new URL(portalGraphqlEndpoint));\n return createClient({\n url: accessToken\n ? `${graphqlEndpoint.protocol}//${graphqlEndpoint.host}/${accessToken}${graphqlEndpoint.pathname}${graphqlEndpoint.search}`\n : graphqlEndpoint.toString(),\n });\n}\n\nfunction setWsProtocol(url: URL) {\n if (url.protocol === \"ws:\" || url.protocol === \"wss:\") {\n return url;\n }\n if (url.protocol === \"http:\") {\n url.protocol = \"ws:\";\n } else {\n url.protocol = \"wss:\";\n }\n return url;\n}\n","import type { FormattedExecutionResult } from \"graphql-ws\";\nimport type { Address, Hex, TransactionReceipt as TransactionReceiptViem } from \"viem\";\nimport { type WebsocketClientOptions, getWebsocketClient } from \"./websocket-client.js\";\n\n/**\n * Represents an event emitted during a transaction execution\n */\nexport interface TransactionEvent {\n /** The name of the event that was emitted */\n eventName: string;\n /** The arguments emitted by the event */\n args: Record<string, unknown>;\n /** Indexed event parameters used for filtering and searching */\n topics: Hex[];\n}\n\n/**\n * Represents the structure of a blockchain transaction receipt\n */\nexport interface TransactionReceipt extends TransactionReceiptViem<string, number, \"Success\" | \"Reverted\"> {\n /** The raw reason for transaction reversion, if applicable */\n revertReason: string;\n /** Human-readable version of the revert reason */\n revertReasonDecoded: string;\n /** Array of events emitted during the transaction */\n events: TransactionEvent[];\n /** The address of the contract deployed in the transaction */\n contractAddress: Address;\n}\n\n/**\n * Represents the structure of a blockchain transaction with its receipt\n */\nexport interface Transaction {\n receipt: TransactionReceipt;\n /** The hash of the transaction (duplicate of receipt.transactionHash) */\n transactionHash: string;\n /** The sender address (duplicate of receipt.from) */\n from: string;\n /** Timestamp when the transaction was created */\n createdAt: string;\n /** The contract address involved in the transaction */\n address: string;\n /** The name of the function called in the transaction */\n functionName: string;\n /** Whether the transaction is a contract deployment */\n isContract: boolean;\n}\n\ninterface GetTransactionResponse {\n getTransaction: Transaction;\n}\n\n/**\n * Options for waiting for a transaction receipt\n */\nexport interface WaitForTransactionReceiptOptions extends WebsocketClientOptions {\n /** Optional timeout in milliseconds before the operation fails */\n timeout?: number;\n}\n\n/**\n * Waits for a blockchain transaction receipt by subscribing to transaction updates via GraphQL.\n * This function polls until the transaction is confirmed or the timeout is reached.\n *\n * @param transactionHash - The hash of the transaction to wait for\n * @param options - Configuration options for the waiting process\n * @returns The transaction details including receipt information when the transaction is confirmed\n * @throws Error if the transaction receipt cannot be retrieved within the specified timeout\n *\n * @example\n * import { waitForTransactionReceipt } from \"@settlemint/sdk-portal\";\n *\n * const transaction = await waitForTransactionReceipt(\"0x123...\", {\n * portalGraphqlEndpoint: \"https://example.settlemint.com/graphql\",\n * accessToken: \"your-access-token\",\n * timeout: 30000 // 30 seconds timeout\n * });\n */\nexport async function waitForTransactionReceipt(transactionHash: string, options: WaitForTransactionReceiptOptions) {\n const wsClient = getWebsocketClient(options);\n const subscription = wsClient.iterate<GetTransactionResponse>({\n query: `subscription getTransaction($transactionHash: String!) {\n getTransaction(transactionHash: $transactionHash) {\n receipt {\n transactionHash\n to\n status\n from\n type\n revertReason\n revertReasonDecoded\n logs\n events\n contractAddress\n }\n transactionHash\n from\n createdAt\n address\n functionName\n isContract\n }\n }`,\n variables: { transactionHash },\n });\n const promises = [getTransactionFromSubscription(subscription)];\n if (options.timeout) {\n promises.push(createTimeoutPromise(options.timeout));\n }\n\n return Promise.race(promises);\n}\n\nfunction createTimeoutPromise(timeout: number): Promise<never> {\n return new Promise((_, reject) => {\n setTimeout(() => reject(new Error(\"Transaction receipt not found\")), timeout);\n });\n}\n\nasync function getTransactionFromSubscription(\n subscription: AsyncIterableIterator<FormattedExecutionResult<GetTransactionResponse, unknown>>,\n): Promise<Transaction> {\n for await (const result of subscription) {\n if (result?.data?.getTransaction?.receipt) {\n return result.data.getTransaction;\n }\n }\n throw new Error(\"No transaction found\");\n}\n","import { createHash } from \"node:crypto\";\nimport type { AbstractSetupSchema, initGraphQLTada } from \"gql.tada\";\nimport type { GraphQLClient } from \"graphql-request\";\nimport type { Address } from \"viem\";\n\n/**\n * Custom error class for challenge-related errors\n */\nexport class ChallengeError extends Error {\n readonly code: string;\n\n constructor(message: string, code: string) {\n super(message);\n this.name = \"ChallengeError\";\n this.code = code;\n }\n}\n\n/**\n * Represents the structure of a wallet verification challenge\n */\ninterface WalletVerificationChallenge {\n challenge: {\n secret: string;\n salt: string;\n };\n id: string;\n name: string;\n verificationType: string;\n}\n\n/**\n * Response type for the CreateWalletVerificationChallenges mutation\n */\ninterface CreateWalletVerificationChallengesResponse {\n createWalletVerificationChallenges: WalletVerificationChallenge[];\n}\n\n/**\n * Hashes a pincode with a salt using SHA-256\n * @param pincode - The pincode to hash\n * @param salt - The salt to use in hashing\n * @returns The hashed pincode as a hex string\n */\nfunction hashPincode(pincode: string, salt: string): string {\n return createHash(\"sha256\").update(`${salt}${pincode}`).digest(\"hex\");\n}\n\n/**\n * Generates a challenge response by combining a hashed pincode with a challenge\n * @param pincode - The user's pincode\n * @param salt - The salt provided in the challenge\n * @param challenge - The challenge secret\n * @returns The challenge response as a hex string\n */\nfunction generateResponse(pincode: string, salt: string, challenge: string): string {\n const hashedPincode = hashPincode(pincode, salt);\n return createHash(\"sha256\").update(`${hashedPincode}_${challenge}`).digest(\"hex\");\n}\n\n/**\n * Options for handling a wallet verification challenge\n */\nexport interface HandleWalletVerificationChallengeOptions<Setup extends AbstractSetupSchema> {\n /** The portal client instance */\n portalClient: GraphQLClient;\n /** The GraphQL query builder */\n portalGraphql: initGraphQLTada<Setup>;\n /** The ID of the verification challenge */\n verificationId: string;\n /** The wallet address to verify */\n userWalletAddress: Address;\n /** The verification code provided by the user */\n code: string | number;\n /** The type of verification being performed */\n verificationType: \"otp\" | \"secret-code\" | \"pincode\";\n}\n\n/**\n * Handles a wallet verification challenge by generating an appropriate response\n *\n * @param options - The options for handling the wallet verification challenge\n * @returns Promise resolving to an object containing the challenge response and optionally the verification ID\n * @throws {ChallengeError} If the challenge cannot be created or is invalid\n * @example\n * import { createPortalClient } from \"@settlemint/sdk-portal\";\n * import { handleWalletVerificationChallenge } from \"@settlemint/sdk-portal\";\n *\n * const { client, graphql } = createPortalClient({\n * instance: \"https://portal.example.com/graphql\",\n * accessToken: \"your-access-token\"\n * });\n *\n * const result = await handleWalletVerificationChallenge({\n * portalClient: client,\n * portalGraphql: graphql,\n * verificationId: \"verification-123\",\n * userWalletAddress: \"0x123...\",\n * code: \"123456\",\n * verificationType: \"otp\"\n * });\n */\nexport async function handleWalletVerificationChallenge<const Setup extends AbstractSetupSchema>({\n portalClient,\n portalGraphql,\n verificationId,\n userWalletAddress,\n code,\n verificationType,\n}: HandleWalletVerificationChallengeOptions<Setup>): Promise<{\n challengeResponse: string;\n verificationId?: string;\n}> {\n try {\n if (verificationType === \"otp\") {\n return {\n challengeResponse: code.toString(),\n verificationId,\n };\n }\n\n if (verificationType === \"secret-code\") {\n // Add - separator to the code\n const formattedCode = code.toString().replace(/(.{5})(?=.)/, \"$1-\");\n return {\n challengeResponse: formattedCode,\n verificationId,\n };\n }\n\n const verificationChallenges = await portalClient.request<CreateWalletVerificationChallengesResponse>(\n portalGraphql(`\n mutation CreateWalletVerificationChallenges($userWalletAddress: String!, $verificationId: String!) {\n createWalletVerificationChallenges(userWalletAddress: $userWalletAddress, verificationId: $verificationId) {\n challenge\n id\n name\n verificationType\n }\n }\n `),\n {\n userWalletAddress,\n verificationId,\n },\n );\n\n if (!verificationChallenges.createWalletVerificationChallenges?.length) {\n throw new ChallengeError(\"No verification challenges received\", \"NO_CHALLENGES\");\n }\n\n const walletVerificationChallenge = verificationChallenges.createWalletVerificationChallenges.find(\n (challenge) => challenge.id === verificationId,\n );\n\n if (!walletVerificationChallenge?.challenge?.secret || !walletVerificationChallenge?.challenge?.salt) {\n throw new ChallengeError(\"Invalid challenge format\", \"INVALID_CHALLENGE\");\n }\n\n const { secret, salt } = walletVerificationChallenge.challenge;\n const challengeResponse = generateResponse(code.toString(), salt, secret);\n return {\n challengeResponse,\n verificationId,\n };\n } catch (error) {\n if (error instanceof ChallengeError) {\n throw error;\n }\n throw new ChallengeError(\"Failed to process wallet verification challenge\", \"CHALLENGE_PROCESSING_ERROR\");\n }\n}\n","import { appendHeaders } from \"@settlemint/sdk-utils/http\";\nimport { ensureServer } from \"@settlemint/sdk-utils/runtime\";\nimport { ApplicationAccessTokenSchema, UrlOrPathSchema, validate } from \"@settlemint/sdk-utils/validation\";\nimport { type AbstractSetupSchema, initGraphQLTada } from \"gql.tada\";\nimport { GraphQLClient } from \"graphql-request\";\nimport { z } from \"zod\";\n\n/**\n * Configuration options for the GraphQL client, excluding 'url' and 'exchanges'.\n */\nexport type RequestConfig = ConstructorParameters<typeof GraphQLClient>[1];\n\n/**\n * Schema for validating Portal client configuration options.\n */\nexport const ClientOptionsSchema = z.object({\n instance: UrlOrPathSchema,\n accessToken: ApplicationAccessTokenSchema.optional(),\n cache: z.enum([\"default\", \"force-cache\", \"no-cache\", \"no-store\", \"only-if-cached\", \"reload\"]).optional(),\n});\n\n/**\n * Type representing the validated client options.\n */\nexport type ClientOptions = z.infer<typeof ClientOptionsSchema>;\n\n/**\n * Creates a Portal GraphQL client with the provided configuration.\n *\n * @param options - Configuration options for the Portal client\n * @param clientOptions - Additional GraphQL client configuration options\n * @returns An object containing the configured GraphQL client and graphql helper function\n * @throws If the provided options fail validation\n *\n * @example\n * import { createPortalClient } from \"@settlemint/sdk-portal\";\n * import { loadEnv } from \"@settlemint/sdk-utils/environment\";\n * import { createLogger, requestLogger } from \"@settlemint/sdk-utils/logging\";\n * import type { introspection } from \"@schemas/portal-env\";\n *\n * const env = await loadEnv(false, false);\n * const logger = createLogger();\n *\n * const { client: portalClient, graphql: portalGraphql } = createPortalClient<{\n * introspection: introspection;\n * disableMasking: true;\n * scalars: {\n * // Change unknown to the type you are using to store metadata\n * JSON: unknown;\n * };\n * }>(\n * {\n * instance: env.SETTLEMINT_PORTAL_GRAPHQL_ENDPOINT!,\n * accessToken: env.SETTLEMINT_ACCESS_TOKEN!,\n * },\n * {\n * fetch: requestLogger(logger, \"portal\", fetch) as typeof fetch,\n * },\n * );\n *\n * // Making GraphQL queries\n * const query = portalGraphql(`\n * query GetPendingTransactions {\n * getPendingTransactions {\n * count\n * }\n * }\n * `);\n *\n * const result = await portalClient.request(query);\n */\nexport function createPortalClient<const Setup extends AbstractSetupSchema>(\n options: ClientOptions,\n clientOptions?: RequestConfig,\n): {\n client: GraphQLClient;\n graphql: initGraphQLTada<Setup>;\n} {\n ensureServer();\n const validatedOptions = validate(ClientOptionsSchema, options);\n const graphql = initGraphQLTada<Setup>();\n const fullUrl = new URL(validatedOptions.instance).toString();\n\n return {\n client: new GraphQLClient(fullUrl, {\n ...clientOptions,\n headers: appendHeaders(clientOptions?.headers, { \"x-auth-token\": validatedOptions.accessToken }),\n }),\n graphql,\n };\n}\n\nexport type { FragmentOf, ResultOf, VariablesOf } from \"gql.tada\";\nexport { readFragment } from \"gql.tada\";\nexport {\n type Transaction,\n type TransactionEvent,\n type TransactionReceipt,\n type WaitForTransactionReceiptOptions,\n waitForTransactionReceipt,\n} from \"./utils/wait-for-transaction-receipt.js\";\nexport {\n type HandleWalletVerificationChallengeOptions,\n handleWalletVerificationChallenge,\n} from \"./utils/wallet-verification-challenge.js\";\nexport { getWebsocketClient, type WebsocketClientOptions } from \"./utils/websocket-client.js\";\n"],"mappings":"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"}
|
package/dist/portal.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"portal.js","names":["url: URL","transactionHash: string","options: WaitForTransactionReceiptOptions","timeout: number","subscription: AsyncIterableIterator<FormattedExecutionResult<GetTransactionResponse, unknown>>","message: string","code: string","pincode: string","salt: string","challenge: string","options: ClientOptions","clientOptions?: RequestConfig"],"sources":["../src/utils/websocket-client.ts","../src/utils/wait-for-transaction-receipt.ts","../src/utils/wallet-verification-challenge.ts","../src/portal.ts"],"sourcesContent":["import { createClient } from \"graphql-ws\";\n\n/**\n * Options for the GraphQL WebSocket client\n */\nexport interface WebsocketClientOptions {\n /**\n * The GraphQL endpoint URL for the Portal API\n */\n portalGraphqlEndpoint: string;\n /**\n * The access token for authentication with the Portal API\n */\n accessToken?: string;\n}\n\n/**\n * Creates a GraphQL WebSocket client for the Portal API\n *\n * @param {WebsocketClientOptions} options - The options for the client\n * @returns {Client} The GraphQL WebSocket client\n * @example\n * import { getWebsocketClient } from \"@settlemint/sdk-portal\";\n *\n * const client = getWebsocketClient({\n * portalGraphqlEndpoint: \"https://portal.settlemint.com/graphql\",\n * accessToken: \"your-access-token\",\n * });\n */\nexport function getWebsocketClient({ portalGraphqlEndpoint, accessToken }: WebsocketClientOptions) {\n if (!portalGraphqlEndpoint) {\n throw new Error(\"portalGraphqlEndpoint is required\");\n }\n const graphqlEndpoint = setWsProtocol(new URL(portalGraphqlEndpoint));\n return createClient({\n url: accessToken\n ? `${graphqlEndpoint.protocol}//${graphqlEndpoint.host}/${accessToken}${graphqlEndpoint.pathname}${graphqlEndpoint.search}`\n : graphqlEndpoint.toString(),\n });\n}\n\nfunction setWsProtocol(url: URL) {\n if (url.protocol === \"ws:\" || url.protocol === \"wss:\") {\n return url;\n }\n if (url.protocol === \"http:\") {\n url.protocol = \"ws:\";\n } else {\n url.protocol = \"wss:\";\n }\n return url;\n}\n","import type { FormattedExecutionResult } from \"graphql-ws\";\nimport type { Address, Hex, TransactionReceipt as TransactionReceiptViem } from \"viem\";\nimport { type WebsocketClientOptions, getWebsocketClient } from \"./websocket-client.js\";\n\n/**\n * Represents an event emitted during a transaction execution\n */\nexport interface TransactionEvent {\n /** The name of the event that was emitted */\n eventName: string;\n /** The arguments emitted by the event */\n args: Record<string, unknown>;\n /** Indexed event parameters used for filtering and searching */\n topics: Hex[];\n}\n\n/**\n * Represents the structure of a blockchain transaction receipt\n */\nexport interface TransactionReceipt extends TransactionReceiptViem<string, number, \"Success\" | \"Reverted\"> {\n /** The raw reason for transaction reversion, if applicable */\n revertReason: string;\n /** Human-readable version of the revert reason */\n revertReasonDecoded: string;\n /** Array of events emitted during the transaction */\n events: TransactionEvent[];\n /** The address of the contract deployed in the transaction */\n contractAddress: Address;\n}\n\n/**\n * Represents the structure of a blockchain transaction with its receipt\n */\nexport interface Transaction {\n receipt: TransactionReceipt;\n /** The hash of the transaction (duplicate of receipt.transactionHash) */\n transactionHash: string;\n /** The sender address (duplicate of receipt.from) */\n from: string;\n /** Timestamp when the transaction was created */\n createdAt: string;\n /** The contract address involved in the transaction */\n address: string;\n /** The name of the function called in the transaction */\n functionName: string;\n /** Whether the transaction is a contract deployment */\n isContract: boolean;\n}\n\ninterface GetTransactionResponse {\n getTransaction: Transaction;\n}\n\n/**\n * Options for waiting for a transaction receipt\n */\nexport interface WaitForTransactionReceiptOptions extends WebsocketClientOptions {\n /** Optional timeout in milliseconds before the operation fails */\n timeout?: number;\n}\n\n/**\n * Waits for a blockchain transaction receipt by subscribing to transaction updates via GraphQL.\n * This function polls until the transaction is confirmed or the timeout is reached.\n *\n * @param transactionHash - The hash of the transaction to wait for\n * @param options - Configuration options for the waiting process\n * @returns The transaction details including receipt information when the transaction is confirmed\n * @throws Error if the transaction receipt cannot be retrieved within the specified timeout\n *\n * @example\n * import { waitForTransactionReceipt } from \"@settlemint/sdk-portal\";\n *\n * const transaction = await waitForTransactionReceipt(\"0x123...\", {\n * portalGraphqlEndpoint: \"https://example.settlemint.com/graphql\",\n * accessToken: \"your-access-token\",\n * timeout: 30000 // 30 seconds timeout\n * });\n */\nexport async function waitForTransactionReceipt(transactionHash: string, options: WaitForTransactionReceiptOptions) {\n const wsClient = getWebsocketClient(options);\n const subscription = wsClient.iterate<GetTransactionResponse>({\n query: `subscription getTransaction($transactionHash: String!) {\n getTransaction(transactionHash: $transactionHash) {\n receipt {\n transactionHash\n to\n status\n from\n type\n revertReason\n revertReasonDecoded\n logs\n events\n contractAddress\n }\n transactionHash\n from\n createdAt\n address\n functionName\n isContract\n }\n }`,\n variables: { transactionHash },\n });\n const promises = [getTransactionFromSubscription(subscription)];\n if (options.timeout) {\n promises.push(createTimeoutPromise(options.timeout));\n }\n\n return Promise.race(promises);\n}\n\nfunction createTimeoutPromise(timeout: number): Promise<never> {\n return new Promise((_, reject) => {\n setTimeout(() => reject(new Error(\"Transaction receipt not found\")), timeout);\n });\n}\n\nasync function getTransactionFromSubscription(\n subscription: AsyncIterableIterator<FormattedExecutionResult<GetTransactionResponse, unknown>>,\n): Promise<Transaction> {\n for await (const result of subscription) {\n if (result?.data?.getTransaction?.receipt) {\n return result.data.getTransaction;\n }\n }\n throw new Error(\"No transaction found\");\n}\n","import { createHash } from \"node:crypto\";\nimport type { AbstractSetupSchema, initGraphQLTada } from \"gql.tada\";\nimport type { GraphQLClient } from \"graphql-request\";\nimport type { Address } from \"viem\";\n\n/**\n * Custom error class for challenge-related errors\n */\nexport class ChallengeError extends Error {\n readonly code: string;\n\n constructor(message: string, code: string) {\n super(message);\n this.name = \"ChallengeError\";\n this.code = code;\n }\n}\n\n/**\n * Represents the structure of a wallet verification challenge\n */\ninterface WalletVerificationChallenge {\n challenge: {\n secret: string;\n salt: string;\n };\n id: string;\n name: string;\n verificationType: string;\n}\n\n/**\n * Response type for the CreateWalletVerificationChallenges mutation\n */\ninterface CreateWalletVerificationChallengesResponse {\n createWalletVerificationChallenges: WalletVerificationChallenge[];\n}\n\n/**\n * Hashes a pincode with a salt using SHA-256\n * @param pincode - The pincode to hash\n * @param salt - The salt to use in hashing\n * @returns The hashed pincode as a hex string\n */\nfunction hashPincode(pincode: string, salt: string): string {\n return createHash(\"sha256\").update(`${salt}${pincode}`).digest(\"hex\");\n}\n\n/**\n * Generates a challenge response by combining a hashed pincode with a challenge\n * @param pincode - The user's pincode\n * @param salt - The salt provided in the challenge\n * @param challenge - The challenge secret\n * @returns The challenge response as a hex string\n */\nfunction generateResponse(pincode: string, salt: string, challenge: string): string {\n const hashedPincode = hashPincode(pincode, salt);\n return createHash(\"sha256\").update(`${hashedPincode}_${challenge}`).digest(\"hex\");\n}\n\n/**\n * Options for handling a wallet verification challenge\n */\nexport interface HandleWalletVerificationChallengeOptions<Setup extends AbstractSetupSchema> {\n /** The portal client instance */\n portalClient: GraphQLClient;\n /** The GraphQL query builder */\n portalGraphql: initGraphQLTada<Setup>;\n /** The ID of the verification challenge */\n verificationId: string;\n /** The wallet address to verify */\n userWalletAddress: Address;\n /** The verification code provided by the user */\n code: string | number;\n /** The type of verification being performed */\n verificationType: \"otp\" | \"secret-code\" | \"pincode\";\n}\n\n/**\n * Handles a wallet verification challenge by generating an appropriate response\n *\n * @param options - The options for handling the wallet verification challenge\n * @returns Promise resolving to an object containing the challenge response and optionally the verification ID\n * @throws {ChallengeError} If the challenge cannot be created or is invalid\n * @example\n * import { createPortalClient } from \"@settlemint/sdk-portal\";\n * import { handleWalletVerificationChallenge } from \"@settlemint/sdk-portal\";\n *\n * const { client, graphql } = createPortalClient({\n * instance: \"https://portal.example.com/graphql\",\n * accessToken: \"your-access-token\"\n * });\n *\n * const result = await handleWalletVerificationChallenge({\n * portalClient: client,\n * portalGraphql: graphql,\n * verificationId: \"verification-123\",\n * userWalletAddress: \"0x123...\",\n * code: \"123456\",\n * verificationType: \"otp\"\n * });\n */\nexport async function handleWalletVerificationChallenge<const Setup extends AbstractSetupSchema>({\n portalClient,\n portalGraphql,\n verificationId,\n userWalletAddress,\n code,\n verificationType,\n}: HandleWalletVerificationChallengeOptions<Setup>): Promise<{\n challengeResponse: string;\n verificationId?: string;\n}> {\n try {\n if (verificationType === \"otp\") {\n return {\n challengeResponse: code.toString(),\n verificationId,\n };\n }\n\n if (verificationType === \"secret-code\") {\n // Add - separator to the code\n const formattedCode = code.toString().replace(/(.{5})(?=.)/, \"$1-\");\n return {\n challengeResponse: formattedCode,\n verificationId,\n };\n }\n\n const verificationChallenges = await portalClient.request<CreateWalletVerificationChallengesResponse>(\n portalGraphql(`\n mutation CreateWalletVerificationChallenges($userWalletAddress: String!, $verificationId: String!) {\n createWalletVerificationChallenges(userWalletAddress: $userWalletAddress, verificationId: $verificationId) {\n challenge\n id\n name\n verificationType\n }\n }\n `),\n {\n userWalletAddress,\n verificationId,\n },\n );\n\n if (!verificationChallenges.createWalletVerificationChallenges?.length) {\n throw new ChallengeError(\"No verification challenges received\", \"NO_CHALLENGES\");\n }\n\n const walletVerificationChallenge = verificationChallenges.createWalletVerificationChallenges.find(\n (challenge) => challenge.id === verificationId,\n );\n\n if (!walletVerificationChallenge?.challenge?.secret || !walletVerificationChallenge?.challenge?.salt) {\n throw new ChallengeError(\"Invalid challenge format\", \"INVALID_CHALLENGE\");\n }\n\n const { secret, salt } = walletVerificationChallenge.challenge;\n const challengeResponse = generateResponse(code.toString(), salt, secret);\n return {\n challengeResponse,\n verificationId,\n };\n } catch (error) {\n if (error instanceof ChallengeError) {\n throw error;\n }\n throw new ChallengeError(\"Failed to process wallet verification challenge\", \"CHALLENGE_PROCESSING_ERROR\");\n }\n}\n","import { appendHeaders } from \"@settlemint/sdk-utils/http\";\nimport { ensureServer } from \"@settlemint/sdk-utils/runtime\";\nimport { ApplicationAccessTokenSchema, UrlOrPathSchema, validate } from \"@settlemint/sdk-utils/validation\";\nimport { type AbstractSetupSchema, initGraphQLTada } from \"gql.tada\";\nimport { GraphQLClient } from \"graphql-request\";\nimport { z } from \"zod\";\n\n/**\n * Configuration options for the GraphQL client, excluding 'url' and 'exchanges'.\n */\nexport type RequestConfig = ConstructorParameters<typeof GraphQLClient>[1];\n\n/**\n * Schema for validating Portal client configuration options.\n */\nexport const ClientOptionsSchema = z.object({\n instance: UrlOrPathSchema,\n accessToken: ApplicationAccessTokenSchema.optional(),\n cache: z.enum([\"default\", \"force-cache\", \"no-cache\", \"no-store\", \"only-if-cached\", \"reload\"]).optional(),\n});\n\n/**\n * Type representing the validated client options.\n */\nexport type ClientOptions = z.infer<typeof ClientOptionsSchema>;\n\n/**\n * Creates a Portal GraphQL client with the provided configuration.\n *\n * @param options - Configuration options for the Portal client\n * @param clientOptions - Additional GraphQL client configuration options\n * @returns An object containing the configured GraphQL client and graphql helper function\n * @throws If the provided options fail validation\n *\n * @example\n * import { createPortalClient } from \"@settlemint/sdk-portal\";\n * import { loadEnv } from \"@settlemint/sdk-utils/environment\";\n * import { createLogger, requestLogger } from \"@settlemint/sdk-utils/logging\";\n * import type { introspection } from \"@schemas/portal-env\";\n *\n * const env = await loadEnv(false, false);\n * const logger = createLogger();\n *\n * const { client: portalClient, graphql: portalGraphql } = createPortalClient<{\n * introspection: introspection;\n * disableMasking: true;\n * scalars: {\n * // Change unknown to the type you are using to store metadata\n * JSON: unknown;\n * };\n * }>(\n * {\n * instance: env.SETTLEMINT_PORTAL_GRAPHQL_ENDPOINT!,\n * accessToken: env.SETTLEMINT_ACCESS_TOKEN!,\n * },\n * {\n * fetch: requestLogger(logger, \"portal\", fetch) as typeof fetch,\n * },\n * );\n *\n * // Making GraphQL queries\n * const query = portalGraphql(`\n * query GetPendingTransactions {\n * getPendingTransactions {\n * count\n * }\n * }\n * `);\n *\n * const result = await portalClient.request(query);\n */\nexport function createPortalClient<const Setup extends AbstractSetupSchema>(\n options: ClientOptions,\n clientOptions?: RequestConfig,\n): {\n client: GraphQLClient;\n graphql: initGraphQLTada<Setup>;\n} {\n ensureServer();\n const validatedOptions = validate(ClientOptionsSchema, options);\n const graphql = initGraphQLTada<Setup>();\n const fullUrl = new URL(validatedOptions.instance).toString();\n\n return {\n client: new GraphQLClient(fullUrl, {\n ...clientOptions,\n headers: appendHeaders(clientOptions?.headers, { \"x-auth-token\": validatedOptions.accessToken }),\n }),\n graphql,\n };\n}\n\nexport type { FragmentOf, ResultOf, VariablesOf } from \"gql.tada\";\nexport { readFragment } from \"gql.tada\";\nexport {\n type Transaction,\n type TransactionEvent,\n type TransactionReceipt,\n type WaitForTransactionReceiptOptions,\n waitForTransactionReceipt,\n} from \"./utils/wait-for-transaction-receipt.js\";\nexport {\n type HandleWalletVerificationChallengeOptions,\n handleWalletVerificationChallenge,\n} from \"./utils/wallet-verification-challenge.js\";\nexport { getWebsocketClient, type WebsocketClientOptions } from \"./utils/websocket-client.js\";\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"portal.js","names":["url: URL","transactionHash: string","options: WaitForTransactionReceiptOptions","timeout: number","subscription: AsyncIterableIterator<FormattedExecutionResult<GetTransactionResponse, unknown>>","message: string","code: string","pincode: string","salt: string","challenge: string","options: ClientOptions","clientOptions?: RequestConfig"],"sources":["../src/utils/websocket-client.ts","../src/utils/wait-for-transaction-receipt.ts","../src/utils/wallet-verification-challenge.ts","../src/portal.ts"],"sourcesContent":["import { createClient } from \"graphql-ws\";\n\n/**\n * Options for the GraphQL WebSocket client\n */\nexport interface WebsocketClientOptions {\n /**\n * The GraphQL endpoint URL for the Portal API\n */\n portalGraphqlEndpoint: string;\n /**\n * The access token for authentication with the Portal API\n */\n accessToken?: string;\n}\n\n/**\n * Creates a GraphQL WebSocket client for the Portal API\n *\n * @param {WebsocketClientOptions} options - The options for the client\n * @returns {Client} The GraphQL WebSocket client\n * @example\n * import { getWebsocketClient } from \"@settlemint/sdk-portal\";\n *\n * const client = getWebsocketClient({\n * portalGraphqlEndpoint: \"https://portal.settlemint.com/graphql\",\n * accessToken: \"your-access-token\",\n * });\n */\nexport function getWebsocketClient({ portalGraphqlEndpoint, accessToken }: WebsocketClientOptions) {\n if (!portalGraphqlEndpoint) {\n throw new Error(\"portalGraphqlEndpoint is required\");\n }\n const graphqlEndpoint = setWsProtocol(new URL(portalGraphqlEndpoint));\n return createClient({\n url: accessToken\n ? `${graphqlEndpoint.protocol}//${graphqlEndpoint.host}/${accessToken}${graphqlEndpoint.pathname}${graphqlEndpoint.search}`\n : graphqlEndpoint.toString(),\n });\n}\n\nfunction setWsProtocol(url: URL) {\n if (url.protocol === \"ws:\" || url.protocol === \"wss:\") {\n return url;\n }\n if (url.protocol === \"http:\") {\n url.protocol = \"ws:\";\n } else {\n url.protocol = \"wss:\";\n }\n return url;\n}\n","import type { FormattedExecutionResult } from \"graphql-ws\";\nimport type { Address, Hex, TransactionReceipt as TransactionReceiptViem } from \"viem\";\nimport { type WebsocketClientOptions, getWebsocketClient } from \"./websocket-client.js\";\n\n/**\n * Represents an event emitted during a transaction execution\n */\nexport interface TransactionEvent {\n /** The name of the event that was emitted */\n eventName: string;\n /** The arguments emitted by the event */\n args: Record<string, unknown>;\n /** Indexed event parameters used for filtering and searching */\n topics: Hex[];\n}\n\n/**\n * Represents the structure of a blockchain transaction receipt\n */\nexport interface TransactionReceipt extends TransactionReceiptViem<string, number, \"Success\" | \"Reverted\"> {\n /** The raw reason for transaction reversion, if applicable */\n revertReason: string;\n /** Human-readable version of the revert reason */\n revertReasonDecoded: string;\n /** Array of events emitted during the transaction */\n events: TransactionEvent[];\n /** The address of the contract deployed in the transaction */\n contractAddress: Address;\n}\n\n/**\n * Represents the structure of a blockchain transaction with its receipt\n */\nexport interface Transaction {\n receipt: TransactionReceipt;\n /** The hash of the transaction (duplicate of receipt.transactionHash) */\n transactionHash: string;\n /** The sender address (duplicate of receipt.from) */\n from: string;\n /** Timestamp when the transaction was created */\n createdAt: string;\n /** The contract address involved in the transaction */\n address: string;\n /** The name of the function called in the transaction */\n functionName: string;\n /** Whether the transaction is a contract deployment */\n isContract: boolean;\n}\n\ninterface GetTransactionResponse {\n getTransaction: Transaction;\n}\n\n/**\n * Options for waiting for a transaction receipt\n */\nexport interface WaitForTransactionReceiptOptions extends WebsocketClientOptions {\n /** Optional timeout in milliseconds before the operation fails */\n timeout?: number;\n}\n\n/**\n * Waits for a blockchain transaction receipt by subscribing to transaction updates via GraphQL.\n * This function polls until the transaction is confirmed or the timeout is reached.\n *\n * @param transactionHash - The hash of the transaction to wait for\n * @param options - Configuration options for the waiting process\n * @returns The transaction details including receipt information when the transaction is confirmed\n * @throws Error if the transaction receipt cannot be retrieved within the specified timeout\n *\n * @example\n * import { waitForTransactionReceipt } from \"@settlemint/sdk-portal\";\n *\n * const transaction = await waitForTransactionReceipt(\"0x123...\", {\n * portalGraphqlEndpoint: \"https://example.settlemint.com/graphql\",\n * accessToken: \"your-access-token\",\n * timeout: 30000 // 30 seconds timeout\n * });\n */\nexport async function waitForTransactionReceipt(transactionHash: string, options: WaitForTransactionReceiptOptions) {\n const wsClient = getWebsocketClient(options);\n const subscription = wsClient.iterate<GetTransactionResponse>({\n query: `subscription getTransaction($transactionHash: String!) {\n getTransaction(transactionHash: $transactionHash) {\n receipt {\n transactionHash\n to\n status\n from\n type\n revertReason\n revertReasonDecoded\n logs\n events\n contractAddress\n }\n transactionHash\n from\n createdAt\n address\n functionName\n isContract\n }\n }`,\n variables: { transactionHash },\n });\n const promises = [getTransactionFromSubscription(subscription)];\n if (options.timeout) {\n promises.push(createTimeoutPromise(options.timeout));\n }\n\n return Promise.race(promises);\n}\n\nfunction createTimeoutPromise(timeout: number): Promise<never> {\n return new Promise((_, reject) => {\n setTimeout(() => reject(new Error(\"Transaction receipt not found\")), timeout);\n });\n}\n\nasync function getTransactionFromSubscription(\n subscription: AsyncIterableIterator<FormattedExecutionResult<GetTransactionResponse, unknown>>,\n): Promise<Transaction> {\n for await (const result of subscription) {\n if (result?.data?.getTransaction?.receipt) {\n return result.data.getTransaction;\n }\n }\n throw new Error(\"No transaction found\");\n}\n","import { createHash } from \"node:crypto\";\nimport type { AbstractSetupSchema, initGraphQLTada } from \"gql.tada\";\nimport type { GraphQLClient } from \"graphql-request\";\nimport type { Address } from \"viem\";\n\n/**\n * Custom error class for challenge-related errors\n */\nexport class ChallengeError extends Error {\n readonly code: string;\n\n constructor(message: string, code: string) {\n super(message);\n this.name = \"ChallengeError\";\n this.code = code;\n }\n}\n\n/**\n * Represents the structure of a wallet verification challenge\n */\ninterface WalletVerificationChallenge {\n challenge: {\n secret: string;\n salt: string;\n };\n id: string;\n name: string;\n verificationType: string;\n}\n\n/**\n * Response type for the CreateWalletVerificationChallenges mutation\n */\ninterface CreateWalletVerificationChallengesResponse {\n createWalletVerificationChallenges: WalletVerificationChallenge[];\n}\n\n/**\n * Hashes a pincode with a salt using SHA-256\n * @param pincode - The pincode to hash\n * @param salt - The salt to use in hashing\n * @returns The hashed pincode as a hex string\n */\nfunction hashPincode(pincode: string, salt: string): string {\n return createHash(\"sha256\").update(`${salt}${pincode}`).digest(\"hex\");\n}\n\n/**\n * Generates a challenge response by combining a hashed pincode with a challenge\n * @param pincode - The user's pincode\n * @param salt - The salt provided in the challenge\n * @param challenge - The challenge secret\n * @returns The challenge response as a hex string\n */\nfunction generateResponse(pincode: string, salt: string, challenge: string): string {\n const hashedPincode = hashPincode(pincode, salt);\n return createHash(\"sha256\").update(`${hashedPincode}_${challenge}`).digest(\"hex\");\n}\n\n/**\n * Options for handling a wallet verification challenge\n */\nexport interface HandleWalletVerificationChallengeOptions<Setup extends AbstractSetupSchema> {\n /** The portal client instance */\n portalClient: GraphQLClient;\n /** The GraphQL query builder */\n portalGraphql: initGraphQLTada<Setup>;\n /** The ID of the verification challenge */\n verificationId: string;\n /** The wallet address to verify */\n userWalletAddress: Address;\n /** The verification code provided by the user */\n code: string | number;\n /** The type of verification being performed */\n verificationType: \"otp\" | \"secret-code\" | \"pincode\";\n}\n\n/**\n * Handles a wallet verification challenge by generating an appropriate response\n *\n * @param options - The options for handling the wallet verification challenge\n * @returns Promise resolving to an object containing the challenge response and optionally the verification ID\n * @throws {ChallengeError} If the challenge cannot be created or is invalid\n * @example\n * import { createPortalClient } from \"@settlemint/sdk-portal\";\n * import { handleWalletVerificationChallenge } from \"@settlemint/sdk-portal\";\n *\n * const { client, graphql } = createPortalClient({\n * instance: \"https://portal.example.com/graphql\",\n * accessToken: \"your-access-token\"\n * });\n *\n * const result = await handleWalletVerificationChallenge({\n * portalClient: client,\n * portalGraphql: graphql,\n * verificationId: \"verification-123\",\n * userWalletAddress: \"0x123...\",\n * code: \"123456\",\n * verificationType: \"otp\"\n * });\n */\nexport async function handleWalletVerificationChallenge<const Setup extends AbstractSetupSchema>({\n portalClient,\n portalGraphql,\n verificationId,\n userWalletAddress,\n code,\n verificationType,\n}: HandleWalletVerificationChallengeOptions<Setup>): Promise<{\n challengeResponse: string;\n verificationId?: string;\n}> {\n try {\n if (verificationType === \"otp\") {\n return {\n challengeResponse: code.toString(),\n verificationId,\n };\n }\n\n if (verificationType === \"secret-code\") {\n // Add - separator to the code\n const formattedCode = code.toString().replace(/(.{5})(?=.)/, \"$1-\");\n return {\n challengeResponse: formattedCode,\n verificationId,\n };\n }\n\n const verificationChallenges = await portalClient.request<CreateWalletVerificationChallengesResponse>(\n portalGraphql(`\n mutation CreateWalletVerificationChallenges($userWalletAddress: String!, $verificationId: String!) {\n createWalletVerificationChallenges(userWalletAddress: $userWalletAddress, verificationId: $verificationId) {\n challenge\n id\n name\n verificationType\n }\n }\n `),\n {\n userWalletAddress,\n verificationId,\n },\n );\n\n if (!verificationChallenges.createWalletVerificationChallenges?.length) {\n throw new ChallengeError(\"No verification challenges received\", \"NO_CHALLENGES\");\n }\n\n const walletVerificationChallenge = verificationChallenges.createWalletVerificationChallenges.find(\n (challenge) => challenge.id === verificationId,\n );\n\n if (!walletVerificationChallenge?.challenge?.secret || !walletVerificationChallenge?.challenge?.salt) {\n throw new ChallengeError(\"Invalid challenge format\", \"INVALID_CHALLENGE\");\n }\n\n const { secret, salt } = walletVerificationChallenge.challenge;\n const challengeResponse = generateResponse(code.toString(), salt, secret);\n return {\n challengeResponse,\n verificationId,\n };\n } catch (error) {\n if (error instanceof ChallengeError) {\n throw error;\n }\n throw new ChallengeError(\"Failed to process wallet verification challenge\", \"CHALLENGE_PROCESSING_ERROR\");\n }\n}\n","import { appendHeaders } from \"@settlemint/sdk-utils/http\";\nimport { ensureServer } from \"@settlemint/sdk-utils/runtime\";\nimport { ApplicationAccessTokenSchema, UrlOrPathSchema, validate } from \"@settlemint/sdk-utils/validation\";\nimport { type AbstractSetupSchema, initGraphQLTada } from \"gql.tada\";\nimport { GraphQLClient } from \"graphql-request\";\nimport { z } from \"zod\";\n\n/**\n * Configuration options for the GraphQL client, excluding 'url' and 'exchanges'.\n */\nexport type RequestConfig = ConstructorParameters<typeof GraphQLClient>[1];\n\n/**\n * Schema for validating Portal client configuration options.\n */\nexport const ClientOptionsSchema = z.object({\n instance: UrlOrPathSchema,\n accessToken: ApplicationAccessTokenSchema.optional(),\n cache: z.enum([\"default\", \"force-cache\", \"no-cache\", \"no-store\", \"only-if-cached\", \"reload\"]).optional(),\n});\n\n/**\n * Type representing the validated client options.\n */\nexport type ClientOptions = z.infer<typeof ClientOptionsSchema>;\n\n/**\n * Creates a Portal GraphQL client with the provided configuration.\n *\n * @param options - Configuration options for the Portal client\n * @param clientOptions - Additional GraphQL client configuration options\n * @returns An object containing the configured GraphQL client and graphql helper function\n * @throws If the provided options fail validation\n *\n * @example\n * import { createPortalClient } from \"@settlemint/sdk-portal\";\n * import { loadEnv } from \"@settlemint/sdk-utils/environment\";\n * import { createLogger, requestLogger } from \"@settlemint/sdk-utils/logging\";\n * import type { introspection } from \"@schemas/portal-env\";\n *\n * const env = await loadEnv(false, false);\n * const logger = createLogger();\n *\n * const { client: portalClient, graphql: portalGraphql } = createPortalClient<{\n * introspection: introspection;\n * disableMasking: true;\n * scalars: {\n * // Change unknown to the type you are using to store metadata\n * JSON: unknown;\n * };\n * }>(\n * {\n * instance: env.SETTLEMINT_PORTAL_GRAPHQL_ENDPOINT!,\n * accessToken: env.SETTLEMINT_ACCESS_TOKEN!,\n * },\n * {\n * fetch: requestLogger(logger, \"portal\", fetch) as typeof fetch,\n * },\n * );\n *\n * // Making GraphQL queries\n * const query = portalGraphql(`\n * query GetPendingTransactions {\n * getPendingTransactions {\n * count\n * }\n * }\n * `);\n *\n * const result = await portalClient.request(query);\n */\nexport function createPortalClient<const Setup extends AbstractSetupSchema>(\n options: ClientOptions,\n clientOptions?: RequestConfig,\n): {\n client: GraphQLClient;\n graphql: initGraphQLTada<Setup>;\n} {\n ensureServer();\n const validatedOptions = validate(ClientOptionsSchema, options);\n const graphql = initGraphQLTada<Setup>();\n const fullUrl = new URL(validatedOptions.instance).toString();\n\n return {\n client: new GraphQLClient(fullUrl, {\n ...clientOptions,\n headers: appendHeaders(clientOptions?.headers, { \"x-auth-token\": validatedOptions.accessToken }),\n }),\n graphql,\n };\n}\n\nexport type { FragmentOf, ResultOf, VariablesOf } from \"gql.tada\";\nexport { readFragment } from \"gql.tada\";\nexport {\n type Transaction,\n type TransactionEvent,\n type TransactionReceipt,\n type WaitForTransactionReceiptOptions,\n waitForTransactionReceipt,\n} from \"./utils/wait-for-transaction-receipt.js\";\nexport {\n type HandleWalletVerificationChallengeOptions,\n handleWalletVerificationChallenge,\n} from \"./utils/wallet-verification-challenge.js\";\nexport { getWebsocketClient, type WebsocketClientOptions } from \"./utils/websocket-client.js\";\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@settlemint/sdk-portal",
|
|
3
3
|
"description": "Portal API client module for SettleMint SDK, providing access to smart contract portal services and APIs",
|
|
4
|
-
"version": "2.5.
|
|
4
|
+
"version": "2.5.6",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"private": false,
|
|
7
7
|
"license": "FSL-1.1-MIT",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"dependencies": {
|
|
60
60
|
"gql.tada": "^1",
|
|
61
61
|
"graphql-ws": "^6",
|
|
62
|
-
"@settlemint/sdk-utils": "2.5.
|
|
62
|
+
"@settlemint/sdk-utils": "2.5.6",
|
|
63
63
|
"graphql-request": "^7",
|
|
64
64
|
"zod": "^4"
|
|
65
65
|
},
|