@settlemint/sdk-portal 2.3.2-prac7a46f0 → 2.3.2-prb1129dad
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 +98 -20
- package/dist/portal.cjs +72 -72
- package/dist/portal.cjs.map +1 -1
- package/dist/portal.d.cts +85 -90
- package/dist/portal.d.ts +85 -90
- package/dist/portal.mjs +72 -72
- package/dist/portal.mjs.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
- [HandleWalletVerificationChallengeOptions\<Setup\>](#handlewalletverificationchallengeoptionssetup)
|
|
43
43
|
- [Transaction](#transaction)
|
|
44
44
|
- [TransactionEvent](#transactionevent)
|
|
45
|
+
- [TransactionReceipt](#transactionreceipt)
|
|
45
46
|
- [WaitForTransactionReceiptOptions](#waitfortransactionreceiptoptions)
|
|
46
47
|
- [WebsocketClientOptions](#websocketclientoptions)
|
|
47
48
|
- [Type Aliases](#type-aliases)
|
|
@@ -600,7 +601,7 @@ console.log("Transaction hash:", result.StableCoinFactoryCreate?.transactionHash
|
|
|
600
601
|
|
|
601
602
|
> **createPortalClient**\<`Setup`\>(`options`, `clientOptions?`): `object`
|
|
602
603
|
|
|
603
|
-
Defined in: [sdk/portal/src/portal.ts:
|
|
604
|
+
Defined in: [sdk/portal/src/portal.ts:72](https://github.com/settlemint/sdk/blob/v2.3.2/sdk/portal/src/portal.ts#L72)
|
|
604
605
|
|
|
605
606
|
Creates a Portal GraphQL client with the provided configuration.
|
|
606
607
|
|
|
@@ -614,8 +615,8 @@ Creates a Portal GraphQL client with the provided configuration.
|
|
|
614
615
|
|
|
615
616
|
| Parameter | Type | Description |
|
|
616
617
|
| ------ | ------ | ------ |
|
|
617
|
-
| `options` | \{ `accessToken
|
|
618
|
-
| `options.accessToken
|
|
618
|
+
| `options` | \{ `accessToken?`: `string`; `cache?`: `"default"` \| `"force-cache"` \| `"no-cache"` \| `"no-store"` \| `"only-if-cached"` \| `"reload"`; `instance`: `string`; \} | Configuration options for the Portal client |
|
|
619
|
+
| `options.accessToken?` | `string` | - |
|
|
619
620
|
| `options.cache?` | `"default"` \| `"force-cache"` \| `"no-cache"` \| `"no-store"` \| `"only-if-cached"` \| `"reload"` | - |
|
|
620
621
|
| `options.instance?` | `string` | - |
|
|
621
622
|
| `clientOptions?` | `RequestConfig` | Additional GraphQL client configuration options |
|
|
@@ -628,8 +629,8 @@ An object containing the configured GraphQL client and graphql helper function
|
|
|
628
629
|
|
|
629
630
|
| Name | Type | Defined in |
|
|
630
631
|
| ------ | ------ | ------ |
|
|
631
|
-
| `client` | `GraphQLClient` | [sdk/portal/src/portal.ts:
|
|
632
|
-
| `graphql` | `initGraphQLTada`\<`Setup`\> | [sdk/portal/src/portal.ts:
|
|
632
|
+
| `client` | `GraphQLClient` | [sdk/portal/src/portal.ts:76](https://github.com/settlemint/sdk/blob/v2.3.2/sdk/portal/src/portal.ts#L76) |
|
|
633
|
+
| `graphql` | `initGraphQLTada`\<`Setup`\> | [sdk/portal/src/portal.ts:77](https://github.com/settlemint/sdk/blob/v2.3.2/sdk/portal/src/portal.ts#L77) |
|
|
633
634
|
|
|
634
635
|
##### Throws
|
|
635
636
|
|
|
@@ -681,7 +682,7 @@ const result = await portalClient.request(query);
|
|
|
681
682
|
|
|
682
683
|
> **getWebsocketClient**(`options`): `Client`
|
|
683
684
|
|
|
684
|
-
Defined in: [sdk/portal/src/utils/websocket-client.ts:
|
|
685
|
+
Defined in: [sdk/portal/src/utils/websocket-client.ts:30](https://github.com/settlemint/sdk/blob/v2.3.2/sdk/portal/src/utils/websocket-client.ts#L30)
|
|
685
686
|
|
|
686
687
|
Creates a GraphQL WebSocket client for the Portal API
|
|
687
688
|
|
|
@@ -697,13 +698,24 @@ Creates a GraphQL WebSocket client for the Portal API
|
|
|
697
698
|
|
|
698
699
|
The GraphQL WebSocket client
|
|
699
700
|
|
|
701
|
+
##### Example
|
|
702
|
+
|
|
703
|
+
```ts
|
|
704
|
+
import { getWebsocketClient } from "@settlemint/sdk-portal";
|
|
705
|
+
|
|
706
|
+
const client = getWebsocketClient({
|
|
707
|
+
portalGraphqlEndpoint: "https://portal.settlemint.com/graphql",
|
|
708
|
+
accessToken: "your-access-token",
|
|
709
|
+
});
|
|
710
|
+
```
|
|
711
|
+
|
|
700
712
|
***
|
|
701
713
|
|
|
702
714
|
#### handleWalletVerificationChallenge()
|
|
703
715
|
|
|
704
716
|
> **handleWalletVerificationChallenge**\<`Setup`\>(`options`): `Promise`\<\{ `challengeResponse`: `string`; `verificationId?`: `string`; \}\>
|
|
705
717
|
|
|
706
|
-
Defined in: [sdk/portal/src/utils/wallet-verification-challenge.ts:
|
|
718
|
+
Defined in: [sdk/portal/src/utils/wallet-verification-challenge.ts:103](https://github.com/settlemint/sdk/blob/v2.3.2/sdk/portal/src/utils/wallet-verification-challenge.ts#L103)
|
|
707
719
|
|
|
708
720
|
Handles a wallet verification challenge by generating an appropriate response
|
|
709
721
|
|
|
@@ -756,7 +768,7 @@ const result = await handleWalletVerificationChallenge({
|
|
|
756
768
|
|
|
757
769
|
> **waitForTransactionReceipt**(`transactionHash`, `options`): `Promise`\<[`Transaction`](#transaction)\>
|
|
758
770
|
|
|
759
|
-
Defined in: [sdk/portal/src/utils/wait-for-transaction-receipt.ts:
|
|
771
|
+
Defined in: [sdk/portal/src/utils/wait-for-transaction-receipt.ts:80](https://github.com/settlemint/sdk/blob/v2.3.2/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L80)
|
|
760
772
|
|
|
761
773
|
Waits for a blockchain transaction receipt by subscribing to transaction updates via GraphQL.
|
|
762
774
|
This function polls until the transaction is confirmed or the timeout is reached.
|
|
@@ -794,37 +806,88 @@ const transaction = await waitForTransactionReceipt("0x123...", {
|
|
|
794
806
|
|
|
795
807
|
#### HandleWalletVerificationChallengeOptions\<Setup\>
|
|
796
808
|
|
|
797
|
-
Defined in: [sdk/portal/src/utils/wallet-verification-challenge.ts:
|
|
809
|
+
Defined in: [sdk/portal/src/utils/wallet-verification-challenge.ts:64](https://github.com/settlemint/sdk/blob/v2.3.2/sdk/portal/src/utils/wallet-verification-challenge.ts#L64)
|
|
798
810
|
|
|
799
811
|
Options for handling a wallet verification challenge
|
|
800
812
|
|
|
801
813
|
##### Type Parameters
|
|
802
814
|
|
|
803
|
-
| Type Parameter |
|
|
804
|
-
| ------ |
|
|
805
|
-
| `Setup` *extends* `AbstractSetupSchema` |
|
|
815
|
+
| Type Parameter |
|
|
816
|
+
| ------ |
|
|
817
|
+
| `Setup` *extends* `AbstractSetupSchema` |
|
|
818
|
+
|
|
819
|
+
##### Properties
|
|
820
|
+
|
|
821
|
+
| Property | Type | Description | Defined in |
|
|
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.3.2/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.3.2/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.3.2/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.3.2/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.3.2/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.3.2/sdk/portal/src/utils/wallet-verification-challenge.ts#L76) |
|
|
806
829
|
|
|
807
830
|
***
|
|
808
831
|
|
|
809
832
|
#### Transaction
|
|
810
833
|
|
|
811
|
-
Defined in: [sdk/portal/src/utils/wait-for-transaction-receipt.ts:
|
|
834
|
+
Defined in: [sdk/portal/src/utils/wait-for-transaction-receipt.ts:34](https://github.com/settlemint/sdk/blob/v2.3.2/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L34)
|
|
812
835
|
|
|
813
836
|
Represents the structure of a blockchain transaction with its receipt
|
|
814
837
|
|
|
838
|
+
##### Properties
|
|
839
|
+
|
|
840
|
+
| Property | Type | Description | Defined in |
|
|
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.3.2/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.3.2/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.3.2/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.3.2/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.3.2/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.3.2/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L37) |
|
|
848
|
+
|
|
815
849
|
***
|
|
816
850
|
|
|
817
851
|
#### TransactionEvent
|
|
818
852
|
|
|
819
|
-
Defined in: [sdk/portal/src/utils/wait-for-transaction-receipt.ts:
|
|
853
|
+
Defined in: [sdk/portal/src/utils/wait-for-transaction-receipt.ts:8](https://github.com/settlemint/sdk/blob/v2.3.2/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L8)
|
|
820
854
|
|
|
821
855
|
Represents an event emitted during a transaction execution
|
|
822
856
|
|
|
857
|
+
##### Properties
|
|
858
|
+
|
|
859
|
+
| Property | Type | Description | Defined in |
|
|
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.3.2/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.3.2/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.3.2/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L14) |
|
|
864
|
+
|
|
865
|
+
***
|
|
866
|
+
|
|
867
|
+
#### TransactionReceipt
|
|
868
|
+
|
|
869
|
+
Defined in: [sdk/portal/src/utils/wait-for-transaction-receipt.ts:20](https://github.com/settlemint/sdk/blob/v2.3.2/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L20)
|
|
870
|
+
|
|
871
|
+
Represents the structure of a blockchain transaction receipt
|
|
872
|
+
|
|
873
|
+
##### Extends
|
|
874
|
+
|
|
875
|
+
- `TransactionReceipt`\<`string`, `number`, `"Success"` \| `"Reverted"`\>
|
|
876
|
+
|
|
877
|
+
##### Properties
|
|
878
|
+
|
|
879
|
+
| Property | Type | Description | Overrides | Defined in |
|
|
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.3.2/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.3.2/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.3.2/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.3.2/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L24) |
|
|
885
|
+
|
|
823
886
|
***
|
|
824
887
|
|
|
825
888
|
#### WaitForTransactionReceiptOptions
|
|
826
889
|
|
|
827
|
-
Defined in: [sdk/portal/src/utils/wait-for-transaction-receipt.ts:
|
|
890
|
+
Defined in: [sdk/portal/src/utils/wait-for-transaction-receipt.ts:57](https://github.com/settlemint/sdk/blob/v2.3.2/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L57)
|
|
828
891
|
|
|
829
892
|
Options for waiting for a transaction receipt
|
|
830
893
|
|
|
@@ -832,11 +895,19 @@ Options for waiting for a transaction receipt
|
|
|
832
895
|
|
|
833
896
|
- [`WebsocketClientOptions`](#websocketclientoptions)
|
|
834
897
|
|
|
898
|
+
##### Properties
|
|
899
|
+
|
|
900
|
+
| Property | Type | Description | Inherited from | Defined in |
|
|
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.3.2/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.3.2/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.3.2/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L59) |
|
|
905
|
+
|
|
835
906
|
***
|
|
836
907
|
|
|
837
908
|
#### WebsocketClientOptions
|
|
838
909
|
|
|
839
|
-
Defined in: [sdk/portal/src/utils/websocket-client.ts:
|
|
910
|
+
Defined in: [sdk/portal/src/utils/websocket-client.ts:6](https://github.com/settlemint/sdk/blob/v2.3.2/sdk/portal/src/utils/websocket-client.ts#L6)
|
|
840
911
|
|
|
841
912
|
Options for the GraphQL WebSocket client
|
|
842
913
|
|
|
@@ -844,13 +915,20 @@ Options for the GraphQL WebSocket client
|
|
|
844
915
|
|
|
845
916
|
- [`WaitForTransactionReceiptOptions`](#waitfortransactionreceiptoptions)
|
|
846
917
|
|
|
918
|
+
##### Properties
|
|
919
|
+
|
|
920
|
+
| Property | Type | Description | Defined in |
|
|
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.3.2/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.3.2/sdk/portal/src/utils/websocket-client.ts#L10) |
|
|
924
|
+
|
|
847
925
|
### Type Aliases
|
|
848
926
|
|
|
849
927
|
#### ClientOptions
|
|
850
928
|
|
|
851
929
|
> **ClientOptions** = `z.infer`\<*typeof* [`ClientOptionsSchema`](#clientoptionsschema)\>
|
|
852
930
|
|
|
853
|
-
Defined in: [sdk/portal/src/portal.ts:
|
|
931
|
+
Defined in: [sdk/portal/src/portal.ts:25](https://github.com/settlemint/sdk/blob/v2.3.2/sdk/portal/src/portal.ts#L25)
|
|
854
932
|
|
|
855
933
|
Type representing the validated client options.
|
|
856
934
|
|
|
@@ -860,7 +938,7 @@ Type representing the validated client options.
|
|
|
860
938
|
|
|
861
939
|
> **RequestConfig** = `ConstructorParameters`\<*typeof* `GraphQLClient`\>\[`1`\]
|
|
862
940
|
|
|
863
|
-
Defined in: [sdk/portal/src/portal.ts:
|
|
941
|
+
Defined in: [sdk/portal/src/portal.ts:11](https://github.com/settlemint/sdk/blob/v2.3.2/sdk/portal/src/portal.ts#L11)
|
|
864
942
|
|
|
865
943
|
Configuration options for the GraphQL client, excluding 'url' and 'exchanges'.
|
|
866
944
|
|
|
@@ -868,9 +946,9 @@ Configuration options for the GraphQL client, excluding 'url' and 'exchanges'.
|
|
|
868
946
|
|
|
869
947
|
#### ClientOptionsSchema
|
|
870
948
|
|
|
871
|
-
> `const` **ClientOptionsSchema**: `ZodObject`\<\{ `accessToken`: `ZodString
|
|
949
|
+
> `const` **ClientOptionsSchema**: `ZodObject`\<\{ `accessToken`: `ZodOptional`\<`ZodString`\>; `cache`: `ZodOptional`\<`ZodEnum`\<\{ `default`: `"default"`; `force-cache`: `"force-cache"`; `no-cache`: `"no-cache"`; `no-store`: `"no-store"`; `only-if-cached`: `"only-if-cached"`; `reload`: `"reload"`; \}\>\>; `instance`: `ZodUnion`\<readonly \[`ZodString`, `ZodString`\]\>; \}, `$strip`\>
|
|
872
950
|
|
|
873
|
-
Defined in: [sdk/portal/src/portal.ts:
|
|
951
|
+
Defined in: [sdk/portal/src/portal.ts:16](https://github.com/settlemint/sdk/blob/v2.3.2/sdk/portal/src/portal.ts#L16)
|
|
874
952
|
|
|
875
953
|
Schema for validating Portal client configuration options.
|
|
876
954
|
|
package/dist/portal.cjs
CHANGED
|
@@ -34,6 +34,78 @@ var import_validation = require("@settlemint/sdk-utils/validation");
|
|
|
34
34
|
var import_gql = require("gql.tada");
|
|
35
35
|
var import_graphql_request = require("graphql-request");
|
|
36
36
|
var import_v4 = require("zod/v4");
|
|
37
|
+
var import_gql2 = require("gql.tada");
|
|
38
|
+
|
|
39
|
+
// src/utils/websocket-client.ts
|
|
40
|
+
var import_graphql_ws = require("graphql-ws");
|
|
41
|
+
function getWebsocketClient({ portalGraphqlEndpoint, accessToken }) {
|
|
42
|
+
if (!portalGraphqlEndpoint) {
|
|
43
|
+
throw new Error("portalGraphqlEndpoint is required");
|
|
44
|
+
}
|
|
45
|
+
const graphqlEndpoint = setWsProtocol(new URL(portalGraphqlEndpoint));
|
|
46
|
+
return (0, import_graphql_ws.createClient)({
|
|
47
|
+
url: `${graphqlEndpoint.protocol}//${graphqlEndpoint.host}/${accessToken}${graphqlEndpoint.pathname}${graphqlEndpoint.search}`
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
function setWsProtocol(url) {
|
|
51
|
+
if (url.protocol === "ws:" || url.protocol === "wss:") {
|
|
52
|
+
return url;
|
|
53
|
+
}
|
|
54
|
+
if (url.protocol === "http:") {
|
|
55
|
+
url.protocol = "ws:";
|
|
56
|
+
} else {
|
|
57
|
+
url.protocol = "wss:";
|
|
58
|
+
}
|
|
59
|
+
return url;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// src/utils/wait-for-transaction-receipt.ts
|
|
63
|
+
async function waitForTransactionReceipt(transactionHash, options) {
|
|
64
|
+
const wsClient = getWebsocketClient(options);
|
|
65
|
+
const subscription = wsClient.iterate({
|
|
66
|
+
query: `subscription getTransaction($transactionHash: String!) {
|
|
67
|
+
getTransaction(transactionHash: $transactionHash) {
|
|
68
|
+
receipt {
|
|
69
|
+
transactionHash
|
|
70
|
+
to
|
|
71
|
+
status
|
|
72
|
+
from
|
|
73
|
+
type
|
|
74
|
+
revertReason
|
|
75
|
+
revertReasonDecoded
|
|
76
|
+
logs
|
|
77
|
+
events
|
|
78
|
+
contractAddress
|
|
79
|
+
}
|
|
80
|
+
transactionHash
|
|
81
|
+
from
|
|
82
|
+
createdAt
|
|
83
|
+
address
|
|
84
|
+
functionName
|
|
85
|
+
isContract
|
|
86
|
+
}
|
|
87
|
+
}`,
|
|
88
|
+
variables: { transactionHash }
|
|
89
|
+
});
|
|
90
|
+
const promises = [getTransactionFromSubscription(subscription)];
|
|
91
|
+
if (options.timeout) {
|
|
92
|
+
promises.push(createTimeoutPromise(options.timeout));
|
|
93
|
+
}
|
|
94
|
+
return Promise.race(promises);
|
|
95
|
+
}
|
|
96
|
+
function createTimeoutPromise(timeout) {
|
|
97
|
+
return new Promise((_, reject) => {
|
|
98
|
+
setTimeout(() => reject(new Error("Transaction receipt not found")), timeout);
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
async function getTransactionFromSubscription(subscription) {
|
|
102
|
+
for await (const result of subscription) {
|
|
103
|
+
if (result?.data?.getTransaction?.receipt) {
|
|
104
|
+
return result.data.getTransaction;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
throw new Error("No transaction found");
|
|
108
|
+
}
|
|
37
109
|
|
|
38
110
|
// src/utils/wallet-verification-challenge.ts
|
|
39
111
|
var import_node_crypto = require("crypto");
|
|
@@ -113,79 +185,7 @@ async function handleWalletVerificationChallenge({
|
|
|
113
185
|
}
|
|
114
186
|
}
|
|
115
187
|
|
|
116
|
-
// src/utils/websocket-client.ts
|
|
117
|
-
var import_graphql_ws = require("graphql-ws");
|
|
118
|
-
function getWebsocketClient({ portalGraphqlEndpoint, accessToken }) {
|
|
119
|
-
if (!portalGraphqlEndpoint) {
|
|
120
|
-
throw new Error("portalGraphqlEndpoint is required");
|
|
121
|
-
}
|
|
122
|
-
const graphqlEndpoint = setWsProtocol(new URL(portalGraphqlEndpoint));
|
|
123
|
-
return (0, import_graphql_ws.createClient)({
|
|
124
|
-
url: `${graphqlEndpoint.protocol}//${graphqlEndpoint.host}/${accessToken}${graphqlEndpoint.pathname}${graphqlEndpoint.search}`
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
function setWsProtocol(url) {
|
|
128
|
-
if (url.protocol === "ws:" || url.protocol === "wss:") {
|
|
129
|
-
return url;
|
|
130
|
-
}
|
|
131
|
-
if (url.protocol === "http:") {
|
|
132
|
-
url.protocol = "ws:";
|
|
133
|
-
} else {
|
|
134
|
-
url.protocol = "wss:";
|
|
135
|
-
}
|
|
136
|
-
return url;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// src/utils/wait-for-transaction-receipt.ts
|
|
140
|
-
async function waitForTransactionReceipt(transactionHash, options) {
|
|
141
|
-
const wsClient = getWebsocketClient(options);
|
|
142
|
-
const subscription = wsClient.iterate({
|
|
143
|
-
query: `subscription getTransaction($transactionHash: String!) {
|
|
144
|
-
getTransaction(transactionHash: $transactionHash) {
|
|
145
|
-
receipt {
|
|
146
|
-
transactionHash
|
|
147
|
-
to
|
|
148
|
-
status
|
|
149
|
-
from
|
|
150
|
-
type
|
|
151
|
-
revertReason
|
|
152
|
-
revertReasonDecoded
|
|
153
|
-
logs
|
|
154
|
-
events
|
|
155
|
-
contractAddress
|
|
156
|
-
}
|
|
157
|
-
transactionHash
|
|
158
|
-
from
|
|
159
|
-
createdAt
|
|
160
|
-
address
|
|
161
|
-
functionName
|
|
162
|
-
isContract
|
|
163
|
-
}
|
|
164
|
-
}`,
|
|
165
|
-
variables: { transactionHash }
|
|
166
|
-
});
|
|
167
|
-
const promises = [getTransactionFromSubscription(subscription)];
|
|
168
|
-
if (options.timeout) {
|
|
169
|
-
promises.push(createTimeoutPromise(options.timeout));
|
|
170
|
-
}
|
|
171
|
-
return Promise.race(promises);
|
|
172
|
-
}
|
|
173
|
-
function createTimeoutPromise(timeout) {
|
|
174
|
-
return new Promise((_, reject) => {
|
|
175
|
-
setTimeout(() => reject(new Error("Transaction receipt not found")), timeout);
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
async function getTransactionFromSubscription(subscription) {
|
|
179
|
-
for await (const result of subscription) {
|
|
180
|
-
if (result?.data?.getTransaction?.receipt) {
|
|
181
|
-
return result.data.getTransaction;
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
throw new Error("No transaction found");
|
|
185
|
-
}
|
|
186
|
-
|
|
187
188
|
// src/portal.ts
|
|
188
|
-
var import_gql2 = require("gql.tada");
|
|
189
189
|
var ClientOptionsSchema = import_v4.z.object({
|
|
190
190
|
instance: import_validation.UrlOrPathSchema,
|
|
191
191
|
accessToken: import_validation.ApplicationAccessTokenSchema.optional(),
|
package/dist/portal.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/portal.ts","../src/utils/wallet-verification-challenge.ts","../src/utils/websocket-client.ts","../src/utils/wait-for-transaction-receipt.ts"],"sourcesContent":["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/v4\";\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 {\n handleWalletVerificationChallenge,\n type HandleWalletVerificationChallengeOptions,\n} from \"./utils/wallet-verification-challenge.js\";\nexport {\n waitForTransactionReceipt,\n type WaitForTransactionReceiptOptions,\n type Transaction,\n type TransactionEvent,\n} from \"./utils/wait-for-transaction-receipt.js\";\nexport { getWebsocketClient, type WebsocketClientOptions } from \"./utils/websocket-client.js\";\nexport { readFragment } from \"gql.tada\";\nexport type { FragmentOf, ResultOf, VariablesOf } from \"gql.tada\";\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 *\n * @typedef {Object} HandleWalletVerificationChallengeOptions\n * @template {AbstractSetupSchema} Setup - The GraphQL schema setup type\n * @property {GraphQLClient} portalClient - The portal client instance\n * @property {initGraphQLTada<Setup>} portalGraphql - The GraphQL query builder\n * @property {string} verificationId - The ID of the verification challenge\n * @property {Address} userWalletAddress - The wallet address to verify\n * @property {string | number} code - The verification code provided by the user\n * @property {\"otp\" | \"secret-code\" | \"pincode\"} verificationType - The type of verification being performed\n */\nexport interface HandleWalletVerificationChallengeOptions<Setup extends AbstractSetupSchema> {\n portalClient: GraphQLClient;\n portalGraphql: initGraphQLTada<Setup>;\n verificationId: string;\n userWalletAddress: Address;\n code: string | number;\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 { createClient } from \"graphql-ws\";\n\n/**\n * Options for the GraphQL WebSocket client\n *\n * @typedef {Object} WebsocketClientOptions\n * @property {string} portalGraphqlEndpoint - The GraphQL endpoint URL for the Portal API\n * @property {string} accessToken - The access token for authentication with the Portal API\n */\nexport interface WebsocketClientOptions {\n portalGraphqlEndpoint: string;\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 * @param {string} options.portalGraphqlEndpoint - The GraphQL endpoint URL for the Portal API\n * @param {string} options.accessToken - The access token for authentication with the Portal API\n * @returns {Client} The GraphQL WebSocket client\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: `${graphqlEndpoint.protocol}//${graphqlEndpoint.host}/${accessToken}${graphqlEndpoint.pathname}${graphqlEndpoint.search}`,\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 WebsocketClientOptions, getWebsocketClient } from \"./websocket-client.js\";\n\nimport type { Hex, TransactionReceipt } from \"viem\";\n\n/**\n * Represents an event emitted during a transaction execution\n *\n * @typedef {Object} TransactionEvent\n * @property {string} eventName - The name of the event that was emitted\n * @property {Record<string, unknown>} args - The arguments emitted by the event\n * @property {Hex[]} topics - Indexed event parameters used for filtering and searching\n */\n\nexport interface TransactionEvent {\n eventName: string;\n args: Record<string, unknown>;\n topics: Hex[];\n}\n\n/**\n * Represents the structure of a blockchain transaction with its receipt\n *\n * @typedef {Object} Transaction\n * @property {Object} receipt - The transaction receipt details\n * @property {string} receipt.transactionHash - The hash of the transaction\n * @property {string} receipt.to - The recipient address of the transaction\n * @property {string} receipt.status - The status of the transaction (success/failure)\n * @property {string} receipt.from - The sender address of the transaction\n * @property {string} receipt.type - The type of the transaction\n * @property {string} receipt.revertReason - The reason for transaction reversion, if applicable\n * @property {string} receipt.revertReasonDecoded - Human-readable version of the revert reason\n * @property {string} receipt.contractAddress - The address of the contract deployed in the transaction\n * @property {string[]} receipt.logs - Array of log entries generated by the transaction\n * @property {TransactionEvent[]} receipt.events - Array of events emitted during the transaction\n * @property {string} transactionHash - The hash of the transaction (duplicate of receipt.transactionHash)\n * @property {string} from - The sender address (duplicate of receipt.from)\n * @property {string} createdAt - Timestamp when the transaction was created\n * @property {string} address - The contract address involved in the transaction\n * @property {string} functionName - The name of the function called in the transaction\n * @property {boolean} isContract - Whether the transaction is a contract deployment\n */\nexport interface Transaction {\n receipt: TransactionReceipt<string, number, \"Success\" | \"Reverted\"> & {\n revertReason: string;\n revertReasonDecoded: string;\n events: TransactionEvent[];\n contractAddress: string;\n };\n transactionHash: string;\n from: string;\n createdAt: string;\n address: string;\n functionName: string;\n isContract: boolean;\n}\n\ninterface GetTransactionResponse {\n getTransaction: Transaction;\n}\n\n/**\n * Options for waiting for a transaction receipt\n *\n * @typedef {Object} WaitForTransactionReceiptOptions\n * @property {number} [timeout] - Optional timeout in milliseconds before the operation fails\n */\nexport interface WaitForTransactionReceiptOptions extends WebsocketClientOptions {\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"],"mappings":"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","names":["import_gql"]}
|
|
1
|
+
{"version":3,"sources":["../src/portal.ts","../src/utils/websocket-client.ts","../src/utils/wait-for-transaction-receipt.ts","../src/utils/wallet-verification-challenge.ts"],"sourcesContent":["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/v4\";\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 { readFragment } from \"gql.tada\";\nexport type { FragmentOf, ResultOf, VariablesOf } from \"gql.tada\";\nexport {\n waitForTransactionReceipt,\n type Transaction,\n type TransactionEvent,\n type TransactionReceipt,\n type WaitForTransactionReceiptOptions,\n} from \"./utils/wait-for-transaction-receipt.js\";\nexport {\n handleWalletVerificationChallenge,\n type HandleWalletVerificationChallengeOptions,\n} from \"./utils/wallet-verification-challenge.js\";\nexport { getWebsocketClient, type WebsocketClientOptions } from \"./utils/websocket-client.js\";\n","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: `${graphqlEndpoint.protocol}//${graphqlEndpoint.host}/${accessToken}${graphqlEndpoint.pathname}${graphqlEndpoint.search}`,\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"],"mappings":"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","names":["import_gql"]}
|
package/dist/portal.d.cts
CHANGED
|
@@ -2,135 +2,84 @@ import { AbstractSetupSchema, initGraphQLTada } from 'gql.tada';
|
|
|
2
2
|
export { FragmentOf, ResultOf, VariablesOf, readFragment } from 'gql.tada';
|
|
3
3
|
import { GraphQLClient } from 'graphql-request';
|
|
4
4
|
import { z } from 'zod/v4';
|
|
5
|
-
import {
|
|
5
|
+
import { TransactionReceipt as TransactionReceipt$1, Hex, Address } from 'viem';
|
|
6
6
|
import * as graphql_ws from 'graphql-ws';
|
|
7
7
|
|
|
8
|
-
/**
|
|
9
|
-
* Options for handling a wallet verification challenge
|
|
10
|
-
*
|
|
11
|
-
* @typedef {Object} HandleWalletVerificationChallengeOptions
|
|
12
|
-
* @template {AbstractSetupSchema} Setup - The GraphQL schema setup type
|
|
13
|
-
* @property {GraphQLClient} portalClient - The portal client instance
|
|
14
|
-
* @property {initGraphQLTada<Setup>} portalGraphql - The GraphQL query builder
|
|
15
|
-
* @property {string} verificationId - The ID of the verification challenge
|
|
16
|
-
* @property {Address} userWalletAddress - The wallet address to verify
|
|
17
|
-
* @property {string | number} code - The verification code provided by the user
|
|
18
|
-
* @property {"otp" | "secret-code" | "pincode"} verificationType - The type of verification being performed
|
|
19
|
-
*/
|
|
20
|
-
interface HandleWalletVerificationChallengeOptions<Setup extends AbstractSetupSchema> {
|
|
21
|
-
portalClient: GraphQLClient;
|
|
22
|
-
portalGraphql: initGraphQLTada<Setup>;
|
|
23
|
-
verificationId: string;
|
|
24
|
-
userWalletAddress: Address;
|
|
25
|
-
code: string | number;
|
|
26
|
-
verificationType: "otp" | "secret-code" | "pincode";
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Handles a wallet verification challenge by generating an appropriate response
|
|
30
|
-
*
|
|
31
|
-
* @param options - The options for handling the wallet verification challenge
|
|
32
|
-
* @returns Promise resolving to an object containing the challenge response and optionally the verification ID
|
|
33
|
-
* @throws {ChallengeError} If the challenge cannot be created or is invalid
|
|
34
|
-
* @example
|
|
35
|
-
* import { createPortalClient } from "@settlemint/sdk-portal";
|
|
36
|
-
* import { handleWalletVerificationChallenge } from "@settlemint/sdk-portal";
|
|
37
|
-
*
|
|
38
|
-
* const { client, graphql } = createPortalClient({
|
|
39
|
-
* instance: "https://portal.example.com/graphql",
|
|
40
|
-
* accessToken: "your-access-token"
|
|
41
|
-
* });
|
|
42
|
-
*
|
|
43
|
-
* const result = await handleWalletVerificationChallenge({
|
|
44
|
-
* portalClient: client,
|
|
45
|
-
* portalGraphql: graphql,
|
|
46
|
-
* verificationId: "verification-123",
|
|
47
|
-
* userWalletAddress: "0x123...",
|
|
48
|
-
* code: "123456",
|
|
49
|
-
* verificationType: "otp"
|
|
50
|
-
* });
|
|
51
|
-
*/
|
|
52
|
-
declare function handleWalletVerificationChallenge<const Setup extends AbstractSetupSchema>({ portalClient, portalGraphql, verificationId, userWalletAddress, code, verificationType, }: HandleWalletVerificationChallengeOptions<Setup>): Promise<{
|
|
53
|
-
challengeResponse: string;
|
|
54
|
-
verificationId?: string;
|
|
55
|
-
}>;
|
|
56
|
-
|
|
57
8
|
/**
|
|
58
9
|
* Options for the GraphQL WebSocket client
|
|
59
|
-
*
|
|
60
|
-
* @typedef {Object} WebsocketClientOptions
|
|
61
|
-
* @property {string} portalGraphqlEndpoint - The GraphQL endpoint URL for the Portal API
|
|
62
|
-
* @property {string} accessToken - The access token for authentication with the Portal API
|
|
63
10
|
*/
|
|
64
11
|
interface WebsocketClientOptions {
|
|
12
|
+
/**
|
|
13
|
+
* The GraphQL endpoint URL for the Portal API
|
|
14
|
+
*/
|
|
65
15
|
portalGraphqlEndpoint: string;
|
|
16
|
+
/**
|
|
17
|
+
* The access token for authentication with the Portal API
|
|
18
|
+
*/
|
|
66
19
|
accessToken?: string;
|
|
67
20
|
}
|
|
68
21
|
/**
|
|
69
22
|
* Creates a GraphQL WebSocket client for the Portal API
|
|
70
23
|
*
|
|
71
24
|
* @param {WebsocketClientOptions} options - The options for the client
|
|
72
|
-
* @param {string} options.portalGraphqlEndpoint - The GraphQL endpoint URL for the Portal API
|
|
73
|
-
* @param {string} options.accessToken - The access token for authentication with the Portal API
|
|
74
25
|
* @returns {Client} The GraphQL WebSocket client
|
|
26
|
+
* @example
|
|
27
|
+
* import { getWebsocketClient } from "@settlemint/sdk-portal";
|
|
28
|
+
*
|
|
29
|
+
* const client = getWebsocketClient({
|
|
30
|
+
* portalGraphqlEndpoint: "https://portal.settlemint.com/graphql",
|
|
31
|
+
* accessToken: "your-access-token",
|
|
32
|
+
* });
|
|
75
33
|
*/
|
|
76
34
|
declare function getWebsocketClient({ portalGraphqlEndpoint, accessToken }: WebsocketClientOptions): graphql_ws.Client;
|
|
77
35
|
|
|
78
36
|
/**
|
|
79
37
|
* Represents an event emitted during a transaction execution
|
|
80
|
-
*
|
|
81
|
-
* @typedef {Object} TransactionEvent
|
|
82
|
-
* @property {string} eventName - The name of the event that was emitted
|
|
83
|
-
* @property {Record<string, unknown>} args - The arguments emitted by the event
|
|
84
|
-
* @property {Hex[]} topics - Indexed event parameters used for filtering and searching
|
|
85
38
|
*/
|
|
86
39
|
interface TransactionEvent {
|
|
40
|
+
/** The name of the event that was emitted */
|
|
87
41
|
eventName: string;
|
|
42
|
+
/** The arguments emitted by the event */
|
|
88
43
|
args: Record<string, unknown>;
|
|
44
|
+
/** Indexed event parameters used for filtering and searching */
|
|
89
45
|
topics: Hex[];
|
|
90
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Represents the structure of a blockchain transaction receipt
|
|
49
|
+
*/
|
|
50
|
+
interface TransactionReceipt extends TransactionReceipt$1<string, number, "Success" | "Reverted"> {
|
|
51
|
+
/** The raw reason for transaction reversion, if applicable */
|
|
52
|
+
revertReason: string;
|
|
53
|
+
/** Human-readable version of the revert reason */
|
|
54
|
+
revertReasonDecoded: string;
|
|
55
|
+
/** Array of events emitted during the transaction */
|
|
56
|
+
events: TransactionEvent[];
|
|
57
|
+
/** The address of the contract deployed in the transaction */
|
|
58
|
+
contractAddress: Address;
|
|
59
|
+
}
|
|
91
60
|
/**
|
|
92
61
|
* Represents the structure of a blockchain transaction with its receipt
|
|
93
|
-
*
|
|
94
|
-
* @typedef {Object} Transaction
|
|
95
|
-
* @property {Object} receipt - The transaction receipt details
|
|
96
|
-
* @property {string} receipt.transactionHash - The hash of the transaction
|
|
97
|
-
* @property {string} receipt.to - The recipient address of the transaction
|
|
98
|
-
* @property {string} receipt.status - The status of the transaction (success/failure)
|
|
99
|
-
* @property {string} receipt.from - The sender address of the transaction
|
|
100
|
-
* @property {string} receipt.type - The type of the transaction
|
|
101
|
-
* @property {string} receipt.revertReason - The reason for transaction reversion, if applicable
|
|
102
|
-
* @property {string} receipt.revertReasonDecoded - Human-readable version of the revert reason
|
|
103
|
-
* @property {string} receipt.contractAddress - The address of the contract deployed in the transaction
|
|
104
|
-
* @property {string[]} receipt.logs - Array of log entries generated by the transaction
|
|
105
|
-
* @property {TransactionEvent[]} receipt.events - Array of events emitted during the transaction
|
|
106
|
-
* @property {string} transactionHash - The hash of the transaction (duplicate of receipt.transactionHash)
|
|
107
|
-
* @property {string} from - The sender address (duplicate of receipt.from)
|
|
108
|
-
* @property {string} createdAt - Timestamp when the transaction was created
|
|
109
|
-
* @property {string} address - The contract address involved in the transaction
|
|
110
|
-
* @property {string} functionName - The name of the function called in the transaction
|
|
111
|
-
* @property {boolean} isContract - Whether the transaction is a contract deployment
|
|
112
62
|
*/
|
|
113
63
|
interface Transaction {
|
|
114
|
-
receipt: TransactionReceipt
|
|
115
|
-
|
|
116
|
-
revertReasonDecoded: string;
|
|
117
|
-
events: TransactionEvent[];
|
|
118
|
-
contractAddress: string;
|
|
119
|
-
};
|
|
64
|
+
receipt: TransactionReceipt;
|
|
65
|
+
/** The hash of the transaction (duplicate of receipt.transactionHash) */
|
|
120
66
|
transactionHash: string;
|
|
67
|
+
/** The sender address (duplicate of receipt.from) */
|
|
121
68
|
from: string;
|
|
69
|
+
/** Timestamp when the transaction was created */
|
|
122
70
|
createdAt: string;
|
|
71
|
+
/** The contract address involved in the transaction */
|
|
123
72
|
address: string;
|
|
73
|
+
/** The name of the function called in the transaction */
|
|
124
74
|
functionName: string;
|
|
75
|
+
/** Whether the transaction is a contract deployment */
|
|
125
76
|
isContract: boolean;
|
|
126
77
|
}
|
|
127
78
|
/**
|
|
128
79
|
* Options for waiting for a transaction receipt
|
|
129
|
-
*
|
|
130
|
-
* @typedef {Object} WaitForTransactionReceiptOptions
|
|
131
|
-
* @property {number} [timeout] - Optional timeout in milliseconds before the operation fails
|
|
132
80
|
*/
|
|
133
81
|
interface WaitForTransactionReceiptOptions extends WebsocketClientOptions {
|
|
82
|
+
/** Optional timeout in milliseconds before the operation fails */
|
|
134
83
|
timeout?: number;
|
|
135
84
|
}
|
|
136
85
|
/**
|
|
@@ -153,6 +102,52 @@ interface WaitForTransactionReceiptOptions extends WebsocketClientOptions {
|
|
|
153
102
|
*/
|
|
154
103
|
declare function waitForTransactionReceipt(transactionHash: string, options: WaitForTransactionReceiptOptions): Promise<Transaction>;
|
|
155
104
|
|
|
105
|
+
/**
|
|
106
|
+
* Options for handling a wallet verification challenge
|
|
107
|
+
*/
|
|
108
|
+
interface HandleWalletVerificationChallengeOptions<Setup extends AbstractSetupSchema> {
|
|
109
|
+
/** The portal client instance */
|
|
110
|
+
portalClient: GraphQLClient;
|
|
111
|
+
/** The GraphQL query builder */
|
|
112
|
+
portalGraphql: initGraphQLTada<Setup>;
|
|
113
|
+
/** The ID of the verification challenge */
|
|
114
|
+
verificationId: string;
|
|
115
|
+
/** The wallet address to verify */
|
|
116
|
+
userWalletAddress: Address;
|
|
117
|
+
/** The verification code provided by the user */
|
|
118
|
+
code: string | number;
|
|
119
|
+
/** The type of verification being performed */
|
|
120
|
+
verificationType: "otp" | "secret-code" | "pincode";
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Handles a wallet verification challenge by generating an appropriate response
|
|
124
|
+
*
|
|
125
|
+
* @param options - The options for handling the wallet verification challenge
|
|
126
|
+
* @returns Promise resolving to an object containing the challenge response and optionally the verification ID
|
|
127
|
+
* @throws {ChallengeError} If the challenge cannot be created or is invalid
|
|
128
|
+
* @example
|
|
129
|
+
* import { createPortalClient } from "@settlemint/sdk-portal";
|
|
130
|
+
* import { handleWalletVerificationChallenge } from "@settlemint/sdk-portal";
|
|
131
|
+
*
|
|
132
|
+
* const { client, graphql } = createPortalClient({
|
|
133
|
+
* instance: "https://portal.example.com/graphql",
|
|
134
|
+
* accessToken: "your-access-token"
|
|
135
|
+
* });
|
|
136
|
+
*
|
|
137
|
+
* const result = await handleWalletVerificationChallenge({
|
|
138
|
+
* portalClient: client,
|
|
139
|
+
* portalGraphql: graphql,
|
|
140
|
+
* verificationId: "verification-123",
|
|
141
|
+
* userWalletAddress: "0x123...",
|
|
142
|
+
* code: "123456",
|
|
143
|
+
* verificationType: "otp"
|
|
144
|
+
* });
|
|
145
|
+
*/
|
|
146
|
+
declare function handleWalletVerificationChallenge<const Setup extends AbstractSetupSchema>({ portalClient, portalGraphql, verificationId, userWalletAddress, code, verificationType, }: HandleWalletVerificationChallengeOptions<Setup>): Promise<{
|
|
147
|
+
challengeResponse: string;
|
|
148
|
+
verificationId?: string;
|
|
149
|
+
}>;
|
|
150
|
+
|
|
156
151
|
/**
|
|
157
152
|
* Configuration options for the GraphQL client, excluding 'url' and 'exchanges'.
|
|
158
153
|
*/
|
|
@@ -226,4 +221,4 @@ declare function createPortalClient<const Setup extends AbstractSetupSchema>(opt
|
|
|
226
221
|
graphql: initGraphQLTada<Setup>;
|
|
227
222
|
};
|
|
228
223
|
|
|
229
|
-
export { type ClientOptions, ClientOptionsSchema, type HandleWalletVerificationChallengeOptions, type RequestConfig, type Transaction, type TransactionEvent, type WaitForTransactionReceiptOptions, type WebsocketClientOptions, createPortalClient, getWebsocketClient, handleWalletVerificationChallenge, waitForTransactionReceipt };
|
|
224
|
+
export { type ClientOptions, ClientOptionsSchema, type HandleWalletVerificationChallengeOptions, type RequestConfig, type Transaction, type TransactionEvent, type TransactionReceipt, type WaitForTransactionReceiptOptions, type WebsocketClientOptions, createPortalClient, getWebsocketClient, handleWalletVerificationChallenge, waitForTransactionReceipt };
|
package/dist/portal.d.ts
CHANGED
|
@@ -2,135 +2,84 @@ import { AbstractSetupSchema, initGraphQLTada } from 'gql.tada';
|
|
|
2
2
|
export { FragmentOf, ResultOf, VariablesOf, readFragment } from 'gql.tada';
|
|
3
3
|
import { GraphQLClient } from 'graphql-request';
|
|
4
4
|
import { z } from 'zod/v4';
|
|
5
|
-
import {
|
|
5
|
+
import { TransactionReceipt as TransactionReceipt$1, Hex, Address } from 'viem';
|
|
6
6
|
import * as graphql_ws from 'graphql-ws';
|
|
7
7
|
|
|
8
|
-
/**
|
|
9
|
-
* Options for handling a wallet verification challenge
|
|
10
|
-
*
|
|
11
|
-
* @typedef {Object} HandleWalletVerificationChallengeOptions
|
|
12
|
-
* @template {AbstractSetupSchema} Setup - The GraphQL schema setup type
|
|
13
|
-
* @property {GraphQLClient} portalClient - The portal client instance
|
|
14
|
-
* @property {initGraphQLTada<Setup>} portalGraphql - The GraphQL query builder
|
|
15
|
-
* @property {string} verificationId - The ID of the verification challenge
|
|
16
|
-
* @property {Address} userWalletAddress - The wallet address to verify
|
|
17
|
-
* @property {string | number} code - The verification code provided by the user
|
|
18
|
-
* @property {"otp" | "secret-code" | "pincode"} verificationType - The type of verification being performed
|
|
19
|
-
*/
|
|
20
|
-
interface HandleWalletVerificationChallengeOptions<Setup extends AbstractSetupSchema> {
|
|
21
|
-
portalClient: GraphQLClient;
|
|
22
|
-
portalGraphql: initGraphQLTada<Setup>;
|
|
23
|
-
verificationId: string;
|
|
24
|
-
userWalletAddress: Address;
|
|
25
|
-
code: string | number;
|
|
26
|
-
verificationType: "otp" | "secret-code" | "pincode";
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Handles a wallet verification challenge by generating an appropriate response
|
|
30
|
-
*
|
|
31
|
-
* @param options - The options for handling the wallet verification challenge
|
|
32
|
-
* @returns Promise resolving to an object containing the challenge response and optionally the verification ID
|
|
33
|
-
* @throws {ChallengeError} If the challenge cannot be created or is invalid
|
|
34
|
-
* @example
|
|
35
|
-
* import { createPortalClient } from "@settlemint/sdk-portal";
|
|
36
|
-
* import { handleWalletVerificationChallenge } from "@settlemint/sdk-portal";
|
|
37
|
-
*
|
|
38
|
-
* const { client, graphql } = createPortalClient({
|
|
39
|
-
* instance: "https://portal.example.com/graphql",
|
|
40
|
-
* accessToken: "your-access-token"
|
|
41
|
-
* });
|
|
42
|
-
*
|
|
43
|
-
* const result = await handleWalletVerificationChallenge({
|
|
44
|
-
* portalClient: client,
|
|
45
|
-
* portalGraphql: graphql,
|
|
46
|
-
* verificationId: "verification-123",
|
|
47
|
-
* userWalletAddress: "0x123...",
|
|
48
|
-
* code: "123456",
|
|
49
|
-
* verificationType: "otp"
|
|
50
|
-
* });
|
|
51
|
-
*/
|
|
52
|
-
declare function handleWalletVerificationChallenge<const Setup extends AbstractSetupSchema>({ portalClient, portalGraphql, verificationId, userWalletAddress, code, verificationType, }: HandleWalletVerificationChallengeOptions<Setup>): Promise<{
|
|
53
|
-
challengeResponse: string;
|
|
54
|
-
verificationId?: string;
|
|
55
|
-
}>;
|
|
56
|
-
|
|
57
8
|
/**
|
|
58
9
|
* Options for the GraphQL WebSocket client
|
|
59
|
-
*
|
|
60
|
-
* @typedef {Object} WebsocketClientOptions
|
|
61
|
-
* @property {string} portalGraphqlEndpoint - The GraphQL endpoint URL for the Portal API
|
|
62
|
-
* @property {string} accessToken - The access token for authentication with the Portal API
|
|
63
10
|
*/
|
|
64
11
|
interface WebsocketClientOptions {
|
|
12
|
+
/**
|
|
13
|
+
* The GraphQL endpoint URL for the Portal API
|
|
14
|
+
*/
|
|
65
15
|
portalGraphqlEndpoint: string;
|
|
16
|
+
/**
|
|
17
|
+
* The access token for authentication with the Portal API
|
|
18
|
+
*/
|
|
66
19
|
accessToken?: string;
|
|
67
20
|
}
|
|
68
21
|
/**
|
|
69
22
|
* Creates a GraphQL WebSocket client for the Portal API
|
|
70
23
|
*
|
|
71
24
|
* @param {WebsocketClientOptions} options - The options for the client
|
|
72
|
-
* @param {string} options.portalGraphqlEndpoint - The GraphQL endpoint URL for the Portal API
|
|
73
|
-
* @param {string} options.accessToken - The access token for authentication with the Portal API
|
|
74
25
|
* @returns {Client} The GraphQL WebSocket client
|
|
26
|
+
* @example
|
|
27
|
+
* import { getWebsocketClient } from "@settlemint/sdk-portal";
|
|
28
|
+
*
|
|
29
|
+
* const client = getWebsocketClient({
|
|
30
|
+
* portalGraphqlEndpoint: "https://portal.settlemint.com/graphql",
|
|
31
|
+
* accessToken: "your-access-token",
|
|
32
|
+
* });
|
|
75
33
|
*/
|
|
76
34
|
declare function getWebsocketClient({ portalGraphqlEndpoint, accessToken }: WebsocketClientOptions): graphql_ws.Client;
|
|
77
35
|
|
|
78
36
|
/**
|
|
79
37
|
* Represents an event emitted during a transaction execution
|
|
80
|
-
*
|
|
81
|
-
* @typedef {Object} TransactionEvent
|
|
82
|
-
* @property {string} eventName - The name of the event that was emitted
|
|
83
|
-
* @property {Record<string, unknown>} args - The arguments emitted by the event
|
|
84
|
-
* @property {Hex[]} topics - Indexed event parameters used for filtering and searching
|
|
85
38
|
*/
|
|
86
39
|
interface TransactionEvent {
|
|
40
|
+
/** The name of the event that was emitted */
|
|
87
41
|
eventName: string;
|
|
42
|
+
/** The arguments emitted by the event */
|
|
88
43
|
args: Record<string, unknown>;
|
|
44
|
+
/** Indexed event parameters used for filtering and searching */
|
|
89
45
|
topics: Hex[];
|
|
90
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Represents the structure of a blockchain transaction receipt
|
|
49
|
+
*/
|
|
50
|
+
interface TransactionReceipt extends TransactionReceipt$1<string, number, "Success" | "Reverted"> {
|
|
51
|
+
/** The raw reason for transaction reversion, if applicable */
|
|
52
|
+
revertReason: string;
|
|
53
|
+
/** Human-readable version of the revert reason */
|
|
54
|
+
revertReasonDecoded: string;
|
|
55
|
+
/** Array of events emitted during the transaction */
|
|
56
|
+
events: TransactionEvent[];
|
|
57
|
+
/** The address of the contract deployed in the transaction */
|
|
58
|
+
contractAddress: Address;
|
|
59
|
+
}
|
|
91
60
|
/**
|
|
92
61
|
* Represents the structure of a blockchain transaction with its receipt
|
|
93
|
-
*
|
|
94
|
-
* @typedef {Object} Transaction
|
|
95
|
-
* @property {Object} receipt - The transaction receipt details
|
|
96
|
-
* @property {string} receipt.transactionHash - The hash of the transaction
|
|
97
|
-
* @property {string} receipt.to - The recipient address of the transaction
|
|
98
|
-
* @property {string} receipt.status - The status of the transaction (success/failure)
|
|
99
|
-
* @property {string} receipt.from - The sender address of the transaction
|
|
100
|
-
* @property {string} receipt.type - The type of the transaction
|
|
101
|
-
* @property {string} receipt.revertReason - The reason for transaction reversion, if applicable
|
|
102
|
-
* @property {string} receipt.revertReasonDecoded - Human-readable version of the revert reason
|
|
103
|
-
* @property {string} receipt.contractAddress - The address of the contract deployed in the transaction
|
|
104
|
-
* @property {string[]} receipt.logs - Array of log entries generated by the transaction
|
|
105
|
-
* @property {TransactionEvent[]} receipt.events - Array of events emitted during the transaction
|
|
106
|
-
* @property {string} transactionHash - The hash of the transaction (duplicate of receipt.transactionHash)
|
|
107
|
-
* @property {string} from - The sender address (duplicate of receipt.from)
|
|
108
|
-
* @property {string} createdAt - Timestamp when the transaction was created
|
|
109
|
-
* @property {string} address - The contract address involved in the transaction
|
|
110
|
-
* @property {string} functionName - The name of the function called in the transaction
|
|
111
|
-
* @property {boolean} isContract - Whether the transaction is a contract deployment
|
|
112
62
|
*/
|
|
113
63
|
interface Transaction {
|
|
114
|
-
receipt: TransactionReceipt
|
|
115
|
-
|
|
116
|
-
revertReasonDecoded: string;
|
|
117
|
-
events: TransactionEvent[];
|
|
118
|
-
contractAddress: string;
|
|
119
|
-
};
|
|
64
|
+
receipt: TransactionReceipt;
|
|
65
|
+
/** The hash of the transaction (duplicate of receipt.transactionHash) */
|
|
120
66
|
transactionHash: string;
|
|
67
|
+
/** The sender address (duplicate of receipt.from) */
|
|
121
68
|
from: string;
|
|
69
|
+
/** Timestamp when the transaction was created */
|
|
122
70
|
createdAt: string;
|
|
71
|
+
/** The contract address involved in the transaction */
|
|
123
72
|
address: string;
|
|
73
|
+
/** The name of the function called in the transaction */
|
|
124
74
|
functionName: string;
|
|
75
|
+
/** Whether the transaction is a contract deployment */
|
|
125
76
|
isContract: boolean;
|
|
126
77
|
}
|
|
127
78
|
/**
|
|
128
79
|
* Options for waiting for a transaction receipt
|
|
129
|
-
*
|
|
130
|
-
* @typedef {Object} WaitForTransactionReceiptOptions
|
|
131
|
-
* @property {number} [timeout] - Optional timeout in milliseconds before the operation fails
|
|
132
80
|
*/
|
|
133
81
|
interface WaitForTransactionReceiptOptions extends WebsocketClientOptions {
|
|
82
|
+
/** Optional timeout in milliseconds before the operation fails */
|
|
134
83
|
timeout?: number;
|
|
135
84
|
}
|
|
136
85
|
/**
|
|
@@ -153,6 +102,52 @@ interface WaitForTransactionReceiptOptions extends WebsocketClientOptions {
|
|
|
153
102
|
*/
|
|
154
103
|
declare function waitForTransactionReceipt(transactionHash: string, options: WaitForTransactionReceiptOptions): Promise<Transaction>;
|
|
155
104
|
|
|
105
|
+
/**
|
|
106
|
+
* Options for handling a wallet verification challenge
|
|
107
|
+
*/
|
|
108
|
+
interface HandleWalletVerificationChallengeOptions<Setup extends AbstractSetupSchema> {
|
|
109
|
+
/** The portal client instance */
|
|
110
|
+
portalClient: GraphQLClient;
|
|
111
|
+
/** The GraphQL query builder */
|
|
112
|
+
portalGraphql: initGraphQLTada<Setup>;
|
|
113
|
+
/** The ID of the verification challenge */
|
|
114
|
+
verificationId: string;
|
|
115
|
+
/** The wallet address to verify */
|
|
116
|
+
userWalletAddress: Address;
|
|
117
|
+
/** The verification code provided by the user */
|
|
118
|
+
code: string | number;
|
|
119
|
+
/** The type of verification being performed */
|
|
120
|
+
verificationType: "otp" | "secret-code" | "pincode";
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Handles a wallet verification challenge by generating an appropriate response
|
|
124
|
+
*
|
|
125
|
+
* @param options - The options for handling the wallet verification challenge
|
|
126
|
+
* @returns Promise resolving to an object containing the challenge response and optionally the verification ID
|
|
127
|
+
* @throws {ChallengeError} If the challenge cannot be created or is invalid
|
|
128
|
+
* @example
|
|
129
|
+
* import { createPortalClient } from "@settlemint/sdk-portal";
|
|
130
|
+
* import { handleWalletVerificationChallenge } from "@settlemint/sdk-portal";
|
|
131
|
+
*
|
|
132
|
+
* const { client, graphql } = createPortalClient({
|
|
133
|
+
* instance: "https://portal.example.com/graphql",
|
|
134
|
+
* accessToken: "your-access-token"
|
|
135
|
+
* });
|
|
136
|
+
*
|
|
137
|
+
* const result = await handleWalletVerificationChallenge({
|
|
138
|
+
* portalClient: client,
|
|
139
|
+
* portalGraphql: graphql,
|
|
140
|
+
* verificationId: "verification-123",
|
|
141
|
+
* userWalletAddress: "0x123...",
|
|
142
|
+
* code: "123456",
|
|
143
|
+
* verificationType: "otp"
|
|
144
|
+
* });
|
|
145
|
+
*/
|
|
146
|
+
declare function handleWalletVerificationChallenge<const Setup extends AbstractSetupSchema>({ portalClient, portalGraphql, verificationId, userWalletAddress, code, verificationType, }: HandleWalletVerificationChallengeOptions<Setup>): Promise<{
|
|
147
|
+
challengeResponse: string;
|
|
148
|
+
verificationId?: string;
|
|
149
|
+
}>;
|
|
150
|
+
|
|
156
151
|
/**
|
|
157
152
|
* Configuration options for the GraphQL client, excluding 'url' and 'exchanges'.
|
|
158
153
|
*/
|
|
@@ -226,4 +221,4 @@ declare function createPortalClient<const Setup extends AbstractSetupSchema>(opt
|
|
|
226
221
|
graphql: initGraphQLTada<Setup>;
|
|
227
222
|
};
|
|
228
223
|
|
|
229
|
-
export { type ClientOptions, ClientOptionsSchema, type HandleWalletVerificationChallengeOptions, type RequestConfig, type Transaction, type TransactionEvent, type WaitForTransactionReceiptOptions, type WebsocketClientOptions, createPortalClient, getWebsocketClient, handleWalletVerificationChallenge, waitForTransactionReceipt };
|
|
224
|
+
export { type ClientOptions, ClientOptionsSchema, type HandleWalletVerificationChallengeOptions, type RequestConfig, type Transaction, type TransactionEvent, type TransactionReceipt, type WaitForTransactionReceiptOptions, type WebsocketClientOptions, createPortalClient, getWebsocketClient, handleWalletVerificationChallenge, waitForTransactionReceipt };
|
package/dist/portal.mjs
CHANGED
|
@@ -5,6 +5,78 @@ import { ApplicationAccessTokenSchema, UrlOrPathSchema, validate } from "@settle
|
|
|
5
5
|
import { initGraphQLTada } from "gql.tada";
|
|
6
6
|
import { GraphQLClient } from "graphql-request";
|
|
7
7
|
import { z } from "zod/v4";
|
|
8
|
+
import { readFragment } from "gql.tada";
|
|
9
|
+
|
|
10
|
+
// src/utils/websocket-client.ts
|
|
11
|
+
import { createClient } from "graphql-ws";
|
|
12
|
+
function getWebsocketClient({ portalGraphqlEndpoint, accessToken }) {
|
|
13
|
+
if (!portalGraphqlEndpoint) {
|
|
14
|
+
throw new Error("portalGraphqlEndpoint is required");
|
|
15
|
+
}
|
|
16
|
+
const graphqlEndpoint = setWsProtocol(new URL(portalGraphqlEndpoint));
|
|
17
|
+
return createClient({
|
|
18
|
+
url: `${graphqlEndpoint.protocol}//${graphqlEndpoint.host}/${accessToken}${graphqlEndpoint.pathname}${graphqlEndpoint.search}`
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
function setWsProtocol(url) {
|
|
22
|
+
if (url.protocol === "ws:" || url.protocol === "wss:") {
|
|
23
|
+
return url;
|
|
24
|
+
}
|
|
25
|
+
if (url.protocol === "http:") {
|
|
26
|
+
url.protocol = "ws:";
|
|
27
|
+
} else {
|
|
28
|
+
url.protocol = "wss:";
|
|
29
|
+
}
|
|
30
|
+
return url;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// src/utils/wait-for-transaction-receipt.ts
|
|
34
|
+
async function waitForTransactionReceipt(transactionHash, options) {
|
|
35
|
+
const wsClient = getWebsocketClient(options);
|
|
36
|
+
const subscription = wsClient.iterate({
|
|
37
|
+
query: `subscription getTransaction($transactionHash: String!) {
|
|
38
|
+
getTransaction(transactionHash: $transactionHash) {
|
|
39
|
+
receipt {
|
|
40
|
+
transactionHash
|
|
41
|
+
to
|
|
42
|
+
status
|
|
43
|
+
from
|
|
44
|
+
type
|
|
45
|
+
revertReason
|
|
46
|
+
revertReasonDecoded
|
|
47
|
+
logs
|
|
48
|
+
events
|
|
49
|
+
contractAddress
|
|
50
|
+
}
|
|
51
|
+
transactionHash
|
|
52
|
+
from
|
|
53
|
+
createdAt
|
|
54
|
+
address
|
|
55
|
+
functionName
|
|
56
|
+
isContract
|
|
57
|
+
}
|
|
58
|
+
}`,
|
|
59
|
+
variables: { transactionHash }
|
|
60
|
+
});
|
|
61
|
+
const promises = [getTransactionFromSubscription(subscription)];
|
|
62
|
+
if (options.timeout) {
|
|
63
|
+
promises.push(createTimeoutPromise(options.timeout));
|
|
64
|
+
}
|
|
65
|
+
return Promise.race(promises);
|
|
66
|
+
}
|
|
67
|
+
function createTimeoutPromise(timeout) {
|
|
68
|
+
return new Promise((_, reject) => {
|
|
69
|
+
setTimeout(() => reject(new Error("Transaction receipt not found")), timeout);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
async function getTransactionFromSubscription(subscription) {
|
|
73
|
+
for await (const result of subscription) {
|
|
74
|
+
if (result?.data?.getTransaction?.receipt) {
|
|
75
|
+
return result.data.getTransaction;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
throw new Error("No transaction found");
|
|
79
|
+
}
|
|
8
80
|
|
|
9
81
|
// src/utils/wallet-verification-challenge.ts
|
|
10
82
|
import { createHash } from "crypto";
|
|
@@ -84,79 +156,7 @@ async function handleWalletVerificationChallenge({
|
|
|
84
156
|
}
|
|
85
157
|
}
|
|
86
158
|
|
|
87
|
-
// src/utils/websocket-client.ts
|
|
88
|
-
import { createClient } from "graphql-ws";
|
|
89
|
-
function getWebsocketClient({ portalGraphqlEndpoint, accessToken }) {
|
|
90
|
-
if (!portalGraphqlEndpoint) {
|
|
91
|
-
throw new Error("portalGraphqlEndpoint is required");
|
|
92
|
-
}
|
|
93
|
-
const graphqlEndpoint = setWsProtocol(new URL(portalGraphqlEndpoint));
|
|
94
|
-
return createClient({
|
|
95
|
-
url: `${graphqlEndpoint.protocol}//${graphqlEndpoint.host}/${accessToken}${graphqlEndpoint.pathname}${graphqlEndpoint.search}`
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
function setWsProtocol(url) {
|
|
99
|
-
if (url.protocol === "ws:" || url.protocol === "wss:") {
|
|
100
|
-
return url;
|
|
101
|
-
}
|
|
102
|
-
if (url.protocol === "http:") {
|
|
103
|
-
url.protocol = "ws:";
|
|
104
|
-
} else {
|
|
105
|
-
url.protocol = "wss:";
|
|
106
|
-
}
|
|
107
|
-
return url;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// src/utils/wait-for-transaction-receipt.ts
|
|
111
|
-
async function waitForTransactionReceipt(transactionHash, options) {
|
|
112
|
-
const wsClient = getWebsocketClient(options);
|
|
113
|
-
const subscription = wsClient.iterate({
|
|
114
|
-
query: `subscription getTransaction($transactionHash: String!) {
|
|
115
|
-
getTransaction(transactionHash: $transactionHash) {
|
|
116
|
-
receipt {
|
|
117
|
-
transactionHash
|
|
118
|
-
to
|
|
119
|
-
status
|
|
120
|
-
from
|
|
121
|
-
type
|
|
122
|
-
revertReason
|
|
123
|
-
revertReasonDecoded
|
|
124
|
-
logs
|
|
125
|
-
events
|
|
126
|
-
contractAddress
|
|
127
|
-
}
|
|
128
|
-
transactionHash
|
|
129
|
-
from
|
|
130
|
-
createdAt
|
|
131
|
-
address
|
|
132
|
-
functionName
|
|
133
|
-
isContract
|
|
134
|
-
}
|
|
135
|
-
}`,
|
|
136
|
-
variables: { transactionHash }
|
|
137
|
-
});
|
|
138
|
-
const promises = [getTransactionFromSubscription(subscription)];
|
|
139
|
-
if (options.timeout) {
|
|
140
|
-
promises.push(createTimeoutPromise(options.timeout));
|
|
141
|
-
}
|
|
142
|
-
return Promise.race(promises);
|
|
143
|
-
}
|
|
144
|
-
function createTimeoutPromise(timeout) {
|
|
145
|
-
return new Promise((_, reject) => {
|
|
146
|
-
setTimeout(() => reject(new Error("Transaction receipt not found")), timeout);
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
async function getTransactionFromSubscription(subscription) {
|
|
150
|
-
for await (const result of subscription) {
|
|
151
|
-
if (result?.data?.getTransaction?.receipt) {
|
|
152
|
-
return result.data.getTransaction;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
throw new Error("No transaction found");
|
|
156
|
-
}
|
|
157
|
-
|
|
158
159
|
// src/portal.ts
|
|
159
|
-
import { readFragment } from "gql.tada";
|
|
160
160
|
var ClientOptionsSchema = z.object({
|
|
161
161
|
instance: UrlOrPathSchema,
|
|
162
162
|
accessToken: ApplicationAccessTokenSchema.optional(),
|
package/dist/portal.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/portal.ts","../src/utils/wallet-verification-challenge.ts","../src/utils/websocket-client.ts","../src/utils/wait-for-transaction-receipt.ts"],"sourcesContent":["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/v4\";\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 {\n handleWalletVerificationChallenge,\n type HandleWalletVerificationChallengeOptions,\n} from \"./utils/wallet-verification-challenge.js\";\nexport {\n waitForTransactionReceipt,\n type WaitForTransactionReceiptOptions,\n type Transaction,\n type TransactionEvent,\n} from \"./utils/wait-for-transaction-receipt.js\";\nexport { getWebsocketClient, type WebsocketClientOptions } from \"./utils/websocket-client.js\";\nexport { readFragment } from \"gql.tada\";\nexport type { FragmentOf, ResultOf, VariablesOf } from \"gql.tada\";\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 *\n * @typedef {Object} HandleWalletVerificationChallengeOptions\n * @template {AbstractSetupSchema} Setup - The GraphQL schema setup type\n * @property {GraphQLClient} portalClient - The portal client instance\n * @property {initGraphQLTada<Setup>} portalGraphql - The GraphQL query builder\n * @property {string} verificationId - The ID of the verification challenge\n * @property {Address} userWalletAddress - The wallet address to verify\n * @property {string | number} code - The verification code provided by the user\n * @property {\"otp\" | \"secret-code\" | \"pincode\"} verificationType - The type of verification being performed\n */\nexport interface HandleWalletVerificationChallengeOptions<Setup extends AbstractSetupSchema> {\n portalClient: GraphQLClient;\n portalGraphql: initGraphQLTada<Setup>;\n verificationId: string;\n userWalletAddress: Address;\n code: string | number;\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 { createClient } from \"graphql-ws\";\n\n/**\n * Options for the GraphQL WebSocket client\n *\n * @typedef {Object} WebsocketClientOptions\n * @property {string} portalGraphqlEndpoint - The GraphQL endpoint URL for the Portal API\n * @property {string} accessToken - The access token for authentication with the Portal API\n */\nexport interface WebsocketClientOptions {\n portalGraphqlEndpoint: string;\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 * @param {string} options.portalGraphqlEndpoint - The GraphQL endpoint URL for the Portal API\n * @param {string} options.accessToken - The access token for authentication with the Portal API\n * @returns {Client} The GraphQL WebSocket client\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: `${graphqlEndpoint.protocol}//${graphqlEndpoint.host}/${accessToken}${graphqlEndpoint.pathname}${graphqlEndpoint.search}`,\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 WebsocketClientOptions, getWebsocketClient } from \"./websocket-client.js\";\n\nimport type { Hex, TransactionReceipt } from \"viem\";\n\n/**\n * Represents an event emitted during a transaction execution\n *\n * @typedef {Object} TransactionEvent\n * @property {string} eventName - The name of the event that was emitted\n * @property {Record<string, unknown>} args - The arguments emitted by the event\n * @property {Hex[]} topics - Indexed event parameters used for filtering and searching\n */\n\nexport interface TransactionEvent {\n eventName: string;\n args: Record<string, unknown>;\n topics: Hex[];\n}\n\n/**\n * Represents the structure of a blockchain transaction with its receipt\n *\n * @typedef {Object} Transaction\n * @property {Object} receipt - The transaction receipt details\n * @property {string} receipt.transactionHash - The hash of the transaction\n * @property {string} receipt.to - The recipient address of the transaction\n * @property {string} receipt.status - The status of the transaction (success/failure)\n * @property {string} receipt.from - The sender address of the transaction\n * @property {string} receipt.type - The type of the transaction\n * @property {string} receipt.revertReason - The reason for transaction reversion, if applicable\n * @property {string} receipt.revertReasonDecoded - Human-readable version of the revert reason\n * @property {string} receipt.contractAddress - The address of the contract deployed in the transaction\n * @property {string[]} receipt.logs - Array of log entries generated by the transaction\n * @property {TransactionEvent[]} receipt.events - Array of events emitted during the transaction\n * @property {string} transactionHash - The hash of the transaction (duplicate of receipt.transactionHash)\n * @property {string} from - The sender address (duplicate of receipt.from)\n * @property {string} createdAt - Timestamp when the transaction was created\n * @property {string} address - The contract address involved in the transaction\n * @property {string} functionName - The name of the function called in the transaction\n * @property {boolean} isContract - Whether the transaction is a contract deployment\n */\nexport interface Transaction {\n receipt: TransactionReceipt<string, number, \"Success\" | \"Reverted\"> & {\n revertReason: string;\n revertReasonDecoded: string;\n events: TransactionEvent[];\n contractAddress: string;\n };\n transactionHash: string;\n from: string;\n createdAt: string;\n address: string;\n functionName: string;\n isContract: boolean;\n}\n\ninterface GetTransactionResponse {\n getTransaction: Transaction;\n}\n\n/**\n * Options for waiting for a transaction receipt\n *\n * @typedef {Object} WaitForTransactionReceiptOptions\n * @property {number} [timeout] - Optional timeout in milliseconds before the operation fails\n */\nexport interface WaitForTransactionReceiptOptions extends WebsocketClientOptions {\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"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/portal.ts","../src/utils/websocket-client.ts","../src/utils/wait-for-transaction-receipt.ts","../src/utils/wallet-verification-challenge.ts"],"sourcesContent":["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/v4\";\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 { readFragment } from \"gql.tada\";\nexport type { FragmentOf, ResultOf, VariablesOf } from \"gql.tada\";\nexport {\n waitForTransactionReceipt,\n type Transaction,\n type TransactionEvent,\n type TransactionReceipt,\n type WaitForTransactionReceiptOptions,\n} from \"./utils/wait-for-transaction-receipt.js\";\nexport {\n handleWalletVerificationChallenge,\n type HandleWalletVerificationChallengeOptions,\n} from \"./utils/wallet-verification-challenge.js\";\nexport { getWebsocketClient, type WebsocketClientOptions } from \"./utils/websocket-client.js\";\n","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: `${graphqlEndpoint.protocol}//${graphqlEndpoint.host}/${accessToken}${graphqlEndpoint.pathname}${graphqlEndpoint.search}`,\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"],"mappings":"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","names":[]}
|
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.3.2-
|
|
4
|
+
"version": "2.3.2-prb1129dad",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"private": false,
|
|
7
7
|
"license": "FSL-1.1-MIT",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"dependencies": {
|
|
57
57
|
"gql.tada": "^1",
|
|
58
58
|
"graphql-ws": "^6",
|
|
59
|
-
"@settlemint/sdk-utils": "2.3.2-
|
|
59
|
+
"@settlemint/sdk-utils": "2.3.2-prb1129dad",
|
|
60
60
|
"graphql-request": "^7",
|
|
61
61
|
"zod": "^3.25.0"
|
|
62
62
|
},
|