@settlemint/sdk-portal 2.5.14-prf20e98df → 2.6.0
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 +108 -73
- package/dist/browser/portal.js.map +1 -1
- package/dist/portal.cjs.map +1 -1
- package/dist/portal.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -38,6 +38,8 @@
|
|
|
38
38
|
- [getWebsocketClient()](#getwebsocketclient)
|
|
39
39
|
- [handleWalletVerificationChallenge()](#handlewalletverificationchallenge)
|
|
40
40
|
- [waitForTransactionReceipt()](#waitfortransactionreceipt)
|
|
41
|
+
- [Classes](#classes)
|
|
42
|
+
- [WalletVerificationChallengeError](#walletverificationchallengeerror)
|
|
41
43
|
- [Interfaces](#interfaces)
|
|
42
44
|
- [HandleWalletVerificationChallengeOptions\<Setup\>](#handlewalletverificationchallengeoptionssetup)
|
|
43
45
|
- [Transaction](#transaction)
|
|
@@ -48,6 +50,7 @@
|
|
|
48
50
|
- [Type Aliases](#type-aliases)
|
|
49
51
|
- [ClientOptions](#clientoptions)
|
|
50
52
|
- [RequestConfig](#requestconfig)
|
|
53
|
+
- [WalletVerificationType](#walletverificationtype)
|
|
51
54
|
- [Variables](#variables)
|
|
52
55
|
- [ClientOptionsSchema](#clientoptionsschema)
|
|
53
56
|
- [Contributing](#contributing)
|
|
@@ -112,7 +115,7 @@ const FROM = getAddress("0x4B03331cF2db1497ec58CAa4AFD8b93611906960");
|
|
|
112
115
|
const deployForwarder = await portalClient.request(
|
|
113
116
|
portalGraphql(`
|
|
114
117
|
mutation DeployContractForwarder($from: String!) {
|
|
115
|
-
|
|
118
|
+
DeployContractATKForwarder(from: $from, gasLimit: "0x3d0900") {
|
|
116
119
|
transactionHash
|
|
117
120
|
}
|
|
118
121
|
}
|
|
@@ -125,18 +128,18 @@ const deployForwarder = await portalClient.request(
|
|
|
125
128
|
/**
|
|
126
129
|
* Wait for the forwarder contract deployment to be finalized
|
|
127
130
|
*/
|
|
128
|
-
const transaction = await waitForTransactionReceipt(deployForwarder.
|
|
131
|
+
const transaction = await waitForTransactionReceipt(deployForwarder.DeployContractATKForwarder?.transactionHash!, {
|
|
129
132
|
portalGraphqlEndpoint: env.SETTLEMINT_PORTAL_GRAPHQL_ENDPOINT!,
|
|
130
133
|
accessToken: env.SETTLEMINT_ACCESS_TOKEN!,
|
|
131
134
|
});
|
|
132
135
|
|
|
133
136
|
/**
|
|
134
|
-
* Deploy a stablecoin
|
|
137
|
+
* Deploy a stablecoin implementation contract
|
|
135
138
|
*/
|
|
136
|
-
const
|
|
139
|
+
const deployStableCoinImplementation = await portalClient.request(
|
|
137
140
|
portalGraphql(`
|
|
138
|
-
mutation DeployContractStableCoinFactory($from: String!, $constructorArguments:
|
|
139
|
-
|
|
141
|
+
mutation DeployContractStableCoinFactory($from: String!, $constructorArguments: DeployContractATKStableCoinImplementationInput!) {
|
|
142
|
+
DeployContractATKStableCoinImplementation(from: $from, constructorArguments: $constructorArguments, gasLimit: "0x3d0900") {
|
|
140
143
|
transactionHash
|
|
141
144
|
}
|
|
142
145
|
}
|
|
@@ -144,12 +147,12 @@ const deployStableCoinFactory = await portalClient.request(
|
|
|
144
147
|
{
|
|
145
148
|
from: FROM,
|
|
146
149
|
constructorArguments: {
|
|
147
|
-
|
|
150
|
+
forwarder_: getAddress(transaction?.receipt.contractAddress!),
|
|
148
151
|
},
|
|
149
152
|
},
|
|
150
153
|
);
|
|
151
154
|
|
|
152
|
-
console.log(
|
|
155
|
+
console.log(deployStableCoinImplementation?.DeployContractATKStableCoinImplementation?.transactionHash);
|
|
153
156
|
|
|
154
157
|
const contractAddresses = await portalClient.request(
|
|
155
158
|
portalGraphql(`
|
|
@@ -471,7 +474,7 @@ runMonitoringExample();
|
|
|
471
474
|
*/
|
|
472
475
|
import { loadEnv } from "@settlemint/sdk-utils/environment";
|
|
473
476
|
import { createLogger, requestLogger } from "@settlemint/sdk-utils/logging";
|
|
474
|
-
import
|
|
477
|
+
import { getAddress } from "viem";
|
|
475
478
|
import { createPortalClient } from "../portal.js"; // Replace this path with "@settlemint/sdk-portal"
|
|
476
479
|
import { handleWalletVerificationChallenge } from "../utils/wallet-verification-challenge.js"; // Replace this path with "@settlemint/sdk-portal"
|
|
477
480
|
import type { introspection } from "./schemas/portal-env.js"; // Replace this path with the generated introspection type
|
|
@@ -543,9 +546,9 @@ const challengeResponse = await handleWalletVerificationChallenge({
|
|
|
543
546
|
portalClient,
|
|
544
547
|
portalGraphql,
|
|
545
548
|
verificationId: pincodeVerification.createWalletVerification?.id!,
|
|
546
|
-
userWalletAddress: wallet.createWallet?.address!
|
|
549
|
+
userWalletAddress: getAddress(wallet.createWallet?.address!),
|
|
547
550
|
code: "123456",
|
|
548
|
-
verificationType: "
|
|
551
|
+
verificationType: "PINCODE",
|
|
549
552
|
});
|
|
550
553
|
|
|
551
554
|
/**
|
|
@@ -556,40 +559,49 @@ const challengeResponse = await handleWalletVerificationChallenge({
|
|
|
556
559
|
*/
|
|
557
560
|
const result = await portalClient.request(
|
|
558
561
|
portalGraphql(`
|
|
559
|
-
mutation
|
|
560
|
-
$challengeResponse: String!
|
|
561
|
-
$verificationId: String
|
|
562
|
+
mutation CreateStableCoinMutation(
|
|
562
563
|
$address: String!
|
|
563
564
|
$from: String!
|
|
564
|
-
$
|
|
565
|
+
$symbol: String!
|
|
566
|
+
$name: String!
|
|
567
|
+
$decimals: Int!
|
|
568
|
+
$initialModulePairs: [ATKStableCoinFactoryImplementationATKStableCoinFactoryImplementationCreateStableCoinInitialModulePairsInput!]!
|
|
569
|
+
$challengeId: String
|
|
570
|
+
$challengeResponse: String
|
|
571
|
+
$countryCode: Int!
|
|
565
572
|
) {
|
|
566
|
-
|
|
567
|
-
challengeResponse: $challengeResponse
|
|
568
|
-
verificationId: $verificationId
|
|
573
|
+
CreateStableCoin: ATKStableCoinFactoryImplementationCreateStableCoin(
|
|
569
574
|
address: $address
|
|
570
575
|
from: $from
|
|
571
|
-
input:
|
|
576
|
+
input: {
|
|
577
|
+
symbol_: $symbol
|
|
578
|
+
name_: $name
|
|
579
|
+
decimals_: $decimals
|
|
580
|
+
initialModulePairs_: $initialModulePairs
|
|
581
|
+
countryCode_: $countryCode
|
|
582
|
+
}
|
|
583
|
+
challengeId: $challengeId
|
|
584
|
+
challengeResponse: $challengeResponse
|
|
572
585
|
) {
|
|
573
586
|
transactionHash
|
|
574
587
|
}
|
|
575
588
|
}
|
|
576
589
|
`),
|
|
577
590
|
{
|
|
578
|
-
challengeResponse: challengeResponse.challengeResponse,
|
|
579
|
-
verificationId: pincodeVerification.createWalletVerification?.id!,
|
|
580
591
|
address: "0x5e771e1417100000000000000000000000000004",
|
|
581
592
|
from: wallet.createWallet?.address!,
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
593
|
+
symbol: "TEST",
|
|
594
|
+
name: "Test Coin",
|
|
595
|
+
decimals: 18,
|
|
596
|
+
initialModulePairs: [],
|
|
597
|
+
challengeResponse: challengeResponse.challengeResponse,
|
|
598
|
+
challengeId: challengeResponse.challengeId,
|
|
599
|
+
countryCode: 56, // Example country code for BE
|
|
588
600
|
},
|
|
589
601
|
);
|
|
590
602
|
|
|
591
603
|
// Log the transaction hash
|
|
592
|
-
console.log("Transaction hash:", result.
|
|
604
|
+
console.log("Transaction hash:", result.CreateStableCoin?.transactionHash);
|
|
593
605
|
|
|
594
606
|
```
|
|
595
607
|
|
|
@@ -601,7 +613,7 @@ console.log("Transaction hash:", result.StableCoinFactoryCreate?.transactionHash
|
|
|
601
613
|
|
|
602
614
|
> **createPortalClient**\<`Setup`\>(`options`, `clientOptions?`): `object`
|
|
603
615
|
|
|
604
|
-
Defined in: [sdk/portal/src/portal.ts:72](https://github.com/settlemint/sdk/blob/v2.
|
|
616
|
+
Defined in: [sdk/portal/src/portal.ts:72](https://github.com/settlemint/sdk/blob/v2.6.0/sdk/portal/src/portal.ts#L72)
|
|
605
617
|
|
|
606
618
|
Creates a Portal GraphQL client with the provided configuration.
|
|
607
619
|
|
|
@@ -629,8 +641,8 @@ An object containing the configured GraphQL client and graphql helper function
|
|
|
629
641
|
|
|
630
642
|
| Name | Type | Defined in |
|
|
631
643
|
| ------ | ------ | ------ |
|
|
632
|
-
| `client` | `GraphQLClient` | [sdk/portal/src/portal.ts:76](https://github.com/settlemint/sdk/blob/v2.
|
|
633
|
-
| `graphql` | `initGraphQLTada`\<`Setup`\> | [sdk/portal/src/portal.ts:77](https://github.com/settlemint/sdk/blob/v2.
|
|
644
|
+
| `client` | `GraphQLClient` | [sdk/portal/src/portal.ts:76](https://github.com/settlemint/sdk/blob/v2.6.0/sdk/portal/src/portal.ts#L76) |
|
|
645
|
+
| `graphql` | `initGraphQLTada`\<`Setup`\> | [sdk/portal/src/portal.ts:77](https://github.com/settlemint/sdk/blob/v2.6.0/sdk/portal/src/portal.ts#L77) |
|
|
634
646
|
|
|
635
647
|
##### Throws
|
|
636
648
|
|
|
@@ -682,7 +694,7 @@ const result = await portalClient.request(query);
|
|
|
682
694
|
|
|
683
695
|
> **getWebsocketClient**(`options`): `Client`
|
|
684
696
|
|
|
685
|
-
Defined in: [sdk/portal/src/utils/websocket-client.ts:30](https://github.com/settlemint/sdk/blob/v2.
|
|
697
|
+
Defined in: [sdk/portal/src/utils/websocket-client.ts:30](https://github.com/settlemint/sdk/blob/v2.6.0/sdk/portal/src/utils/websocket-client.ts#L30)
|
|
686
698
|
|
|
687
699
|
Creates a GraphQL WebSocket client for the Portal API
|
|
688
700
|
|
|
@@ -713,9 +725,9 @@ const client = getWebsocketClient({
|
|
|
713
725
|
|
|
714
726
|
#### handleWalletVerificationChallenge()
|
|
715
727
|
|
|
716
|
-
> **handleWalletVerificationChallenge**\<`Setup`\>(`options`): `Promise`\<\{ `
|
|
728
|
+
> **handleWalletVerificationChallenge**\<`Setup`\>(`options`): `Promise`\<\{ `challengeId`: `string`; `challengeResponse`: `string`; \}\>
|
|
717
729
|
|
|
718
|
-
Defined in: [sdk/portal/src/utils/wallet-verification-challenge.ts:
|
|
730
|
+
Defined in: [sdk/portal/src/utils/wallet-verification-challenge.ts:111](https://github.com/settlemint/sdk/blob/v2.6.0/sdk/portal/src/utils/wallet-verification-challenge.ts#L111)
|
|
719
731
|
|
|
720
732
|
Handles a wallet verification challenge by generating an appropriate response
|
|
721
733
|
|
|
@@ -733,7 +745,7 @@ Handles a wallet verification challenge by generating an appropriate response
|
|
|
733
745
|
|
|
734
746
|
##### Returns
|
|
735
747
|
|
|
736
|
-
`Promise`\<\{ `
|
|
748
|
+
`Promise`\<\{ `challengeId`: `string`; `challengeResponse`: `string`; \}\>
|
|
737
749
|
|
|
738
750
|
Promise resolving to an object containing the challenge response and optionally the verification ID
|
|
739
751
|
|
|
@@ -758,7 +770,7 @@ const result = await handleWalletVerificationChallenge({
|
|
|
758
770
|
verificationId: "verification-123",
|
|
759
771
|
userWalletAddress: "0x123...",
|
|
760
772
|
code: "123456",
|
|
761
|
-
verificationType: "
|
|
773
|
+
verificationType: "OTP"
|
|
762
774
|
});
|
|
763
775
|
```
|
|
764
776
|
|
|
@@ -768,7 +780,7 @@ const result = await handleWalletVerificationChallenge({
|
|
|
768
780
|
|
|
769
781
|
> **waitForTransactionReceipt**(`transactionHash`, `options`): `Promise`\<[`Transaction`](#transaction)\>
|
|
770
782
|
|
|
771
|
-
Defined in: [sdk/portal/src/utils/wait-for-transaction-receipt.ts:80](https://github.com/settlemint/sdk/blob/v2.
|
|
783
|
+
Defined in: [sdk/portal/src/utils/wait-for-transaction-receipt.ts:80](https://github.com/settlemint/sdk/blob/v2.6.0/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L80)
|
|
772
784
|
|
|
773
785
|
Waits for a blockchain transaction receipt by subscribing to transaction updates via GraphQL.
|
|
774
786
|
This function polls until the transaction is confirmed or the timeout is reached.
|
|
@@ -802,11 +814,23 @@ const transaction = await waitForTransactionReceipt("0x123...", {
|
|
|
802
814
|
});
|
|
803
815
|
```
|
|
804
816
|
|
|
817
|
+
### Classes
|
|
818
|
+
|
|
819
|
+
#### WalletVerificationChallengeError
|
|
820
|
+
|
|
821
|
+
Defined in: [sdk/portal/src/utils/wallet-verification-challenge.ts:14](https://github.com/settlemint/sdk/blob/v2.6.0/sdk/portal/src/utils/wallet-verification-challenge.ts#L14)
|
|
822
|
+
|
|
823
|
+
Custom error class for challenge-related errors
|
|
824
|
+
|
|
825
|
+
##### Extends
|
|
826
|
+
|
|
827
|
+
- `Error`
|
|
828
|
+
|
|
805
829
|
### Interfaces
|
|
806
830
|
|
|
807
831
|
#### HandleWalletVerificationChallengeOptions\<Setup\>
|
|
808
832
|
|
|
809
|
-
Defined in: [sdk/portal/src/utils/wallet-verification-challenge.ts:
|
|
833
|
+
Defined in: [sdk/portal/src/utils/wallet-verification-challenge.ts:70](https://github.com/settlemint/sdk/blob/v2.6.0/sdk/portal/src/utils/wallet-verification-challenge.ts#L70)
|
|
810
834
|
|
|
811
835
|
Options for handling a wallet verification challenge
|
|
812
836
|
|
|
@@ -820,18 +844,19 @@ Options for handling a wallet verification challenge
|
|
|
820
844
|
|
|
821
845
|
| Property | Type | Description | Defined in |
|
|
822
846
|
| ------ | ------ | ------ | ------ |
|
|
823
|
-
| <a id="code"></a> `code` | `string` \| `number` | The verification code provided by the user | [sdk/portal/src/utils/wallet-verification-challenge.ts:
|
|
824
|
-
| <a id="portalclient"></a> `portalClient` | `GraphQLClient` | The portal client instance | [sdk/portal/src/utils/wallet-verification-challenge.ts:
|
|
825
|
-
| <a id="portalgraphql"></a> `portalGraphql` | `initGraphQLTada`\<`Setup`\> | The GraphQL query builder | [sdk/portal/src/utils/wallet-verification-challenge.ts:
|
|
826
|
-
| <a id="
|
|
827
|
-
| <a id="
|
|
828
|
-
| <a id="
|
|
847
|
+
| <a id="code"></a> `code` | `string` \| `number` | The verification code provided by the user | [sdk/portal/src/utils/wallet-verification-challenge.ts:80](https://github.com/settlemint/sdk/blob/v2.6.0/sdk/portal/src/utils/wallet-verification-challenge.ts#L80) |
|
|
848
|
+
| <a id="portalclient"></a> `portalClient` | `GraphQLClient` | The portal client instance | [sdk/portal/src/utils/wallet-verification-challenge.ts:72](https://github.com/settlemint/sdk/blob/v2.6.0/sdk/portal/src/utils/wallet-verification-challenge.ts#L72) |
|
|
849
|
+
| <a id="portalgraphql"></a> `portalGraphql` | `initGraphQLTada`\<`Setup`\> | The GraphQL query builder | [sdk/portal/src/utils/wallet-verification-challenge.ts:74](https://github.com/settlemint/sdk/blob/v2.6.0/sdk/portal/src/utils/wallet-verification-challenge.ts#L74) |
|
|
850
|
+
| <a id="requestid"></a> `requestId?` | `string` | Request id which can be added for tracing purposes | [sdk/portal/src/utils/wallet-verification-challenge.ts:84](https://github.com/settlemint/sdk/blob/v2.6.0/sdk/portal/src/utils/wallet-verification-challenge.ts#L84) |
|
|
851
|
+
| <a id="userwalletaddress"></a> `userWalletAddress` | `` `0x${string}` `` | The wallet address to verify | [sdk/portal/src/utils/wallet-verification-challenge.ts:78](https://github.com/settlemint/sdk/blob/v2.6.0/sdk/portal/src/utils/wallet-verification-challenge.ts#L78) |
|
|
852
|
+
| <a id="verificationid"></a> `verificationId` | `string` | The ID of the verification challenge | [sdk/portal/src/utils/wallet-verification-challenge.ts:76](https://github.com/settlemint/sdk/blob/v2.6.0/sdk/portal/src/utils/wallet-verification-challenge.ts#L76) |
|
|
853
|
+
| <a id="verificationtype"></a> `verificationType` | [`WalletVerificationType`](#walletverificationtype) | The type of verification being performed | [sdk/portal/src/utils/wallet-verification-challenge.ts:82](https://github.com/settlemint/sdk/blob/v2.6.0/sdk/portal/src/utils/wallet-verification-challenge.ts#L82) |
|
|
829
854
|
|
|
830
855
|
***
|
|
831
856
|
|
|
832
857
|
#### Transaction
|
|
833
858
|
|
|
834
|
-
Defined in: [sdk/portal/src/utils/wait-for-transaction-receipt.ts:34](https://github.com/settlemint/sdk/blob/v2.
|
|
859
|
+
Defined in: [sdk/portal/src/utils/wait-for-transaction-receipt.ts:34](https://github.com/settlemint/sdk/blob/v2.6.0/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L34)
|
|
835
860
|
|
|
836
861
|
Represents the structure of a blockchain transaction with its receipt
|
|
837
862
|
|
|
@@ -839,18 +864,18 @@ Represents the structure of a blockchain transaction with its receipt
|
|
|
839
864
|
|
|
840
865
|
| Property | Type | Description | Defined in |
|
|
841
866
|
| ------ | ------ | ------ | ------ |
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
867
|
+
| <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.6.0/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L43) |
|
|
868
|
+
| <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.6.0/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L41) |
|
|
869
|
+
| <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.6.0/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L39) |
|
|
870
|
+
| <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.6.0/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L45) |
|
|
871
|
+
| <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.6.0/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L47) |
|
|
872
|
+
| <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.6.0/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L37) |
|
|
848
873
|
|
|
849
874
|
***
|
|
850
875
|
|
|
851
876
|
#### TransactionEvent
|
|
852
877
|
|
|
853
|
-
Defined in: [sdk/portal/src/utils/wait-for-transaction-receipt.ts:8](https://github.com/settlemint/sdk/blob/v2.
|
|
878
|
+
Defined in: [sdk/portal/src/utils/wait-for-transaction-receipt.ts:8](https://github.com/settlemint/sdk/blob/v2.6.0/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L8)
|
|
854
879
|
|
|
855
880
|
Represents an event emitted during a transaction execution
|
|
856
881
|
|
|
@@ -858,15 +883,15 @@ Represents an event emitted during a transaction execution
|
|
|
858
883
|
|
|
859
884
|
| Property | Type | Description | Defined in |
|
|
860
885
|
| ------ | ------ | ------ | ------ |
|
|
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.
|
|
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.
|
|
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.
|
|
886
|
+
| <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.6.0/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L12) |
|
|
887
|
+
| <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.6.0/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L10) |
|
|
888
|
+
| <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.6.0/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L14) |
|
|
864
889
|
|
|
865
890
|
***
|
|
866
891
|
|
|
867
892
|
#### TransactionReceipt
|
|
868
893
|
|
|
869
|
-
Defined in: [sdk/portal/src/utils/wait-for-transaction-receipt.ts:20](https://github.com/settlemint/sdk/blob/v2.
|
|
894
|
+
Defined in: [sdk/portal/src/utils/wait-for-transaction-receipt.ts:20](https://github.com/settlemint/sdk/blob/v2.6.0/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L20)
|
|
870
895
|
|
|
871
896
|
Represents the structure of a blockchain transaction receipt
|
|
872
897
|
|
|
@@ -878,16 +903,16 @@ Represents the structure of a blockchain transaction receipt
|
|
|
878
903
|
|
|
879
904
|
| Property | Type | Description | Overrides | Defined in |
|
|
880
905
|
| ------ | ------ | ------ | ------ | ------ |
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
906
|
+
| <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.6.0/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L28) |
|
|
907
|
+
| <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.6.0/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L26) |
|
|
908
|
+
| <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.6.0/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L22) |
|
|
909
|
+
| <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.6.0/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L24) |
|
|
885
910
|
|
|
886
911
|
***
|
|
887
912
|
|
|
888
913
|
#### WaitForTransactionReceiptOptions
|
|
889
914
|
|
|
890
|
-
Defined in: [sdk/portal/src/utils/wait-for-transaction-receipt.ts:57](https://github.com/settlemint/sdk/blob/v2.
|
|
915
|
+
Defined in: [sdk/portal/src/utils/wait-for-transaction-receipt.ts:57](https://github.com/settlemint/sdk/blob/v2.6.0/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L57)
|
|
891
916
|
|
|
892
917
|
Options for waiting for a transaction receipt
|
|
893
918
|
|
|
@@ -899,15 +924,15 @@ Options for waiting for a transaction receipt
|
|
|
899
924
|
|
|
900
925
|
| Property | Type | Description | Inherited from | Defined in |
|
|
901
926
|
| ------ | ------ | ------ | ------ | ------ |
|
|
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.
|
|
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.
|
|
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.
|
|
927
|
+
| <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.6.0/sdk/portal/src/utils/websocket-client.ts#L14) |
|
|
928
|
+
| <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.6.0/sdk/portal/src/utils/websocket-client.ts#L10) |
|
|
929
|
+
| <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.6.0/sdk/portal/src/utils/wait-for-transaction-receipt.ts#L59) |
|
|
905
930
|
|
|
906
931
|
***
|
|
907
932
|
|
|
908
933
|
#### WebsocketClientOptions
|
|
909
934
|
|
|
910
|
-
Defined in: [sdk/portal/src/utils/websocket-client.ts:6](https://github.com/settlemint/sdk/blob/v2.
|
|
935
|
+
Defined in: [sdk/portal/src/utils/websocket-client.ts:6](https://github.com/settlemint/sdk/blob/v2.6.0/sdk/portal/src/utils/websocket-client.ts#L6)
|
|
911
936
|
|
|
912
937
|
Options for the GraphQL WebSocket client
|
|
913
938
|
|
|
@@ -919,8 +944,8 @@ Options for the GraphQL WebSocket client
|
|
|
919
944
|
|
|
920
945
|
| Property | Type | Description | Defined in |
|
|
921
946
|
| ------ | ------ | ------ | ------ |
|
|
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.
|
|
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.
|
|
947
|
+
| <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.6.0/sdk/portal/src/utils/websocket-client.ts#L14) |
|
|
948
|
+
| <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.6.0/sdk/portal/src/utils/websocket-client.ts#L10) |
|
|
924
949
|
|
|
925
950
|
### Type Aliases
|
|
926
951
|
|
|
@@ -928,7 +953,7 @@ Options for the GraphQL WebSocket client
|
|
|
928
953
|
|
|
929
954
|
> **ClientOptions** = `object`
|
|
930
955
|
|
|
931
|
-
Defined in: [sdk/portal/src/portal.ts:25](https://github.com/settlemint/sdk/blob/v2.
|
|
956
|
+
Defined in: [sdk/portal/src/portal.ts:25](https://github.com/settlemint/sdk/blob/v2.6.0/sdk/portal/src/portal.ts#L25)
|
|
932
957
|
|
|
933
958
|
Type representing the validated client options.
|
|
934
959
|
|
|
@@ -936,9 +961,9 @@ Type representing the validated client options.
|
|
|
936
961
|
|
|
937
962
|
| Name | Type | Default value | Defined in |
|
|
938
963
|
| ------ | ------ | ------ | ------ |
|
|
939
|
-
| <a id="accesstoken-2"></a> `accessToken?` | `string` | - | [sdk/portal/src/portal.ts:18](https://github.com/settlemint/sdk/blob/v2.
|
|
940
|
-
| <a id="cache"></a> `cache?` | `"default"` \| `"force-cache"` \| `"no-cache"` \| `"no-store"` \| `"only-if-cached"` \| `"reload"` | - | [sdk/portal/src/portal.ts:19](https://github.com/settlemint/sdk/blob/v2.
|
|
941
|
-
| <a id="instance"></a> `instance` | `string` | `UrlOrPathSchema` | [sdk/portal/src/portal.ts:17](https://github.com/settlemint/sdk/blob/v2.
|
|
964
|
+
| <a id="accesstoken-2"></a> `accessToken?` | `string` | - | [sdk/portal/src/portal.ts:18](https://github.com/settlemint/sdk/blob/v2.6.0/sdk/portal/src/portal.ts#L18) |
|
|
965
|
+
| <a id="cache"></a> `cache?` | `"default"` \| `"force-cache"` \| `"no-cache"` \| `"no-store"` \| `"only-if-cached"` \| `"reload"` | - | [sdk/portal/src/portal.ts:19](https://github.com/settlemint/sdk/blob/v2.6.0/sdk/portal/src/portal.ts#L19) |
|
|
966
|
+
| <a id="instance"></a> `instance` | `string` | `UrlOrPathSchema` | [sdk/portal/src/portal.ts:17](https://github.com/settlemint/sdk/blob/v2.6.0/sdk/portal/src/portal.ts#L17) |
|
|
942
967
|
|
|
943
968
|
***
|
|
944
969
|
|
|
@@ -946,17 +971,27 @@ Type representing the validated client options.
|
|
|
946
971
|
|
|
947
972
|
> **RequestConfig** = `ConstructorParameters`\<*typeof* `GraphQLClient`\>\[`1`\]
|
|
948
973
|
|
|
949
|
-
Defined in: [sdk/portal/src/portal.ts:11](https://github.com/settlemint/sdk/blob/v2.
|
|
974
|
+
Defined in: [sdk/portal/src/portal.ts:11](https://github.com/settlemint/sdk/blob/v2.6.0/sdk/portal/src/portal.ts#L11)
|
|
950
975
|
|
|
951
976
|
Configuration options for the GraphQL client, excluding 'url' and 'exchanges'.
|
|
952
977
|
|
|
978
|
+
***
|
|
979
|
+
|
|
980
|
+
#### WalletVerificationType
|
|
981
|
+
|
|
982
|
+
> **WalletVerificationType** = `"PINCODE"` \| `"OTP"` \| `"SECRET_CODES"`
|
|
983
|
+
|
|
984
|
+
Defined in: [sdk/portal/src/utils/wallet-verification-challenge.ts:9](https://github.com/settlemint/sdk/blob/v2.6.0/sdk/portal/src/utils/wallet-verification-challenge.ts#L9)
|
|
985
|
+
|
|
986
|
+
Type representing the different types of wallet verification methods
|
|
987
|
+
|
|
953
988
|
### Variables
|
|
954
989
|
|
|
955
990
|
#### ClientOptionsSchema
|
|
956
991
|
|
|
957
992
|
> `const` **ClientOptionsSchema**: `ZodObject`\<[`ClientOptions`](#clientoptions)\>
|
|
958
993
|
|
|
959
|
-
Defined in: [sdk/portal/src/portal.ts:16](https://github.com/settlemint/sdk/blob/v2.
|
|
994
|
+
Defined in: [sdk/portal/src/portal.ts:16](https://github.com/settlemint/sdk/blob/v2.6.0/sdk/portal/src/portal.ts#L16)
|
|
960
995
|
|
|
961
996
|
Schema for validating Portal client configuration options.
|
|
962
997
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"portal.js","names":["url: URL","transactionHash: string","options: WaitForTransactionReceiptOptions","timeout: number","subscription: AsyncIterableIterator<FormattedExecutionResult<GetTransactionResponse, unknown>>","message: string","code: string","pincode: string","salt: string","challenge: string","options: ClientOptions","clientOptions?: RequestConfig"],"sources":["../../src/utils/websocket-client.ts","../../src/utils/wait-for-transaction-receipt.ts","../../src/utils/wallet-verification-challenge.ts","../../src/portal.ts"],"sourcesContent":["import { createClient } from \"graphql-ws\";\n\n/**\n * Options for the GraphQL WebSocket client\n */\nexport interface WebsocketClientOptions {\n /**\n * The GraphQL endpoint URL for the Portal API\n */\n portalGraphqlEndpoint: string;\n /**\n * The access token for authentication with the Portal API\n */\n accessToken?: string;\n}\n\n/**\n * Creates a GraphQL WebSocket client for the Portal API\n *\n * @param {WebsocketClientOptions} options - The options for the client\n * @returns {Client} The GraphQL WebSocket client\n * @example\n * import { getWebsocketClient } from \"@settlemint/sdk-portal\";\n *\n * const client = getWebsocketClient({\n * portalGraphqlEndpoint: \"https://portal.settlemint.com/graphql\",\n * accessToken: \"your-access-token\",\n * });\n */\nexport function getWebsocketClient({ portalGraphqlEndpoint, accessToken }: WebsocketClientOptions) {\n if (!portalGraphqlEndpoint) {\n throw new Error(\"portalGraphqlEndpoint is required\");\n }\n const graphqlEndpoint = setWsProtocol(new URL(portalGraphqlEndpoint));\n return createClient({\n url: accessToken\n ? `${graphqlEndpoint.protocol}//${graphqlEndpoint.host}/${accessToken}${graphqlEndpoint.pathname}${graphqlEndpoint.search}`\n : graphqlEndpoint.toString(),\n });\n}\n\nfunction setWsProtocol(url: URL) {\n if (url.protocol === \"ws:\" || url.protocol === \"wss:\") {\n return url;\n }\n if (url.protocol === \"http:\") {\n url.protocol = \"ws:\";\n } else {\n url.protocol = \"wss:\";\n }\n return url;\n}\n","import type { FormattedExecutionResult } from \"graphql-ws\";\nimport type { Address, Hex, TransactionReceipt as TransactionReceiptViem } from \"viem\";\nimport { type WebsocketClientOptions, getWebsocketClient } from \"./websocket-client.js\";\n\n/**\n * Represents an event emitted during a transaction execution\n */\nexport interface TransactionEvent {\n /** The name of the event that was emitted */\n eventName: string;\n /** The arguments emitted by the event */\n args: Record<string, unknown>;\n /** Indexed event parameters used for filtering and searching */\n topics: Hex[];\n}\n\n/**\n * Represents the structure of a blockchain transaction receipt\n */\nexport interface TransactionReceipt extends TransactionReceiptViem<string, number, \"Success\" | \"Reverted\"> {\n /** The raw reason for transaction reversion, if applicable */\n revertReason: string;\n /** Human-readable version of the revert reason */\n revertReasonDecoded: string;\n /** Array of events emitted during the transaction */\n events: TransactionEvent[];\n /** The address of the contract deployed in the transaction */\n contractAddress: Address;\n}\n\n/**\n * Represents the structure of a blockchain transaction with its receipt\n */\nexport interface Transaction {\n receipt: TransactionReceipt;\n /** The hash of the transaction (duplicate of receipt.transactionHash) */\n transactionHash: string;\n /** The sender address (duplicate of receipt.from) */\n from: string;\n /** Timestamp when the transaction was created */\n createdAt: string;\n /** The contract address involved in the transaction */\n address: string;\n /** The name of the function called in the transaction */\n functionName: string;\n /** Whether the transaction is a contract deployment */\n isContract: boolean;\n}\n\ninterface GetTransactionResponse {\n getTransaction: Transaction;\n}\n\n/**\n * Options for waiting for a transaction receipt\n */\nexport interface WaitForTransactionReceiptOptions extends WebsocketClientOptions {\n /** Optional timeout in milliseconds before the operation fails */\n timeout?: number;\n}\n\n/**\n * Waits for a blockchain transaction receipt by subscribing to transaction updates via GraphQL.\n * This function polls until the transaction is confirmed or the timeout is reached.\n *\n * @param transactionHash - The hash of the transaction to wait for\n * @param options - Configuration options for the waiting process\n * @returns The transaction details including receipt information when the transaction is confirmed\n * @throws Error if the transaction receipt cannot be retrieved within the specified timeout\n *\n * @example\n * import { waitForTransactionReceipt } from \"@settlemint/sdk-portal\";\n *\n * const transaction = await waitForTransactionReceipt(\"0x123...\", {\n * portalGraphqlEndpoint: \"https://example.settlemint.com/graphql\",\n * accessToken: \"your-access-token\",\n * timeout: 30000 // 30 seconds timeout\n * });\n */\nexport async function waitForTransactionReceipt(transactionHash: string, options: WaitForTransactionReceiptOptions) {\n const wsClient = getWebsocketClient(options);\n const subscription = wsClient.iterate<GetTransactionResponse>({\n query: `subscription getTransaction($transactionHash: String!) {\n getTransaction(transactionHash: $transactionHash) {\n receipt {\n transactionHash\n to\n status\n from\n type\n revertReason\n revertReasonDecoded\n logs\n events\n contractAddress\n }\n transactionHash\n from\n createdAt\n address\n functionName\n isContract\n }\n }`,\n variables: { transactionHash },\n });\n const promises = [getTransactionFromSubscription(subscription)];\n if (options.timeout) {\n promises.push(createTimeoutPromise(options.timeout));\n }\n\n return Promise.race(promises);\n}\n\nfunction createTimeoutPromise(timeout: number): Promise<never> {\n return new Promise((_, reject) => {\n setTimeout(() => reject(new Error(\"Transaction receipt not found\")), timeout);\n });\n}\n\nasync function getTransactionFromSubscription(\n subscription: AsyncIterableIterator<FormattedExecutionResult<GetTransactionResponse, unknown>>,\n): Promise<Transaction> {\n for await (const result of subscription) {\n if (result?.data?.getTransaction?.receipt) {\n return result.data.getTransaction;\n }\n }\n throw new Error(\"No transaction found\");\n}\n","import { createHash } from \"node:crypto\";\nimport type { AbstractSetupSchema, initGraphQLTada } from \"gql.tada\";\nimport type { GraphQLClient } from \"graphql-request\";\nimport type { Address } from \"viem\";\n\n/**\n * Type representing the different types of wallet verification methods\n */\nexport type WalletVerificationType = \"PINCODE\" | \"OTP\" | \"SECRET_CODES\";\n\n/**\n * Custom error class for challenge-related errors\n */\nexport class WalletVerificationChallengeError 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 id: string;\n name: string;\n verificationId: string;\n verificationType: WalletVerificationType;\n challenge?: {\n salt: string;\n secret: string;\n };\n}\n\n/**\n * Response type for the CreateWalletVerificationChallenge mutation\n */\ninterface CreateWalletVerificationChallengeResponse {\n createWalletVerificationChallenge: 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: WalletVerificationType;\n /** Request id which can be added for tracing purposes */\n requestId?: string;\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 {WalletVerificationChallengeError} 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 requestId,\n}: HandleWalletVerificationChallengeOptions<Setup>): Promise<{\n challengeResponse: string;\n challengeId: string;\n}> {\n try {\n const requestHeaders = new Headers();\n if (requestId) {\n requestHeaders.append(\"x-request-id\", requestId);\n }\n const verificationChallenge = await portalClient.request<CreateWalletVerificationChallengeResponse>(\n portalGraphql(`\n mutation CreateWalletVerificationChallenge($userWalletAddress: String!, $verificationId: String!) {\n createWalletVerificationChallenge(\n userWalletAddress: $userWalletAddress\n verificationId: $verificationId\n ) {\n id\n name\n verificationId\n verificationType\n challenge {\n salt\n secret\n }\n }\n }\n `),\n {\n userWalletAddress,\n verificationId,\n },\n requestHeaders,\n );\n\n if (!verificationChallenge.createWalletVerificationChallenge) {\n throw new WalletVerificationChallengeError(\"No verification challenge received\", \"NO_CHALLENGES\");\n }\n\n if (verificationType === \"OTP\") {\n return {\n challengeResponse: code.toString(),\n challengeId: verificationChallenge.createWalletVerificationChallenge.id,\n };\n }\n\n if (verificationType === \"SECRET_CODES\") {\n // Add - separator to the code\n const formattedCode = code.toString().replace(/(.{5})(?=.)/, \"$1-\");\n return {\n challengeResponse: formattedCode,\n challengeId: verificationChallenge.createWalletVerificationChallenge.id,\n };\n }\n\n const { secret, salt } = verificationChallenge.createWalletVerificationChallenge.challenge ?? {};\n\n if (!secret || !salt) {\n throw new WalletVerificationChallengeError(\"Invalid challenge format\", \"INVALID_CHALLENGE\");\n }\n\n const challengeResponse = generateResponse(code.toString(), salt, secret);\n return {\n challengeResponse,\n challengeId: verificationChallenge.createWalletVerificationChallenge.id,\n };\n } catch (error) {\n if (error instanceof WalletVerificationChallengeError) {\n throw error;\n }\n throw new WalletVerificationChallengeError(\n \"Failed to process wallet verification challenge\",\n \"CHALLENGE_PROCESSING_ERROR\",\n );\n }\n}\n","import { appendHeaders } from \"@settlemint/sdk-utils/http\";\nimport { ensureServer } from \"@settlemint/sdk-utils/runtime\";\nimport { ApplicationAccessTokenSchema, UrlOrPathSchema, validate } from \"@settlemint/sdk-utils/validation\";\nimport { type AbstractSetupSchema, initGraphQLTada } from \"gql.tada\";\nimport { GraphQLClient } from \"graphql-request\";\nimport { z } from \"zod\";\n\n/**\n * Configuration options for the GraphQL client, excluding 'url' and 'exchanges'.\n */\nexport type RequestConfig = ConstructorParameters<typeof GraphQLClient>[1];\n\n/**\n * Schema for validating Portal client configuration options.\n */\nexport const ClientOptionsSchema = z.object({\n instance: UrlOrPathSchema,\n accessToken: ApplicationAccessTokenSchema.optional(),\n cache: z.enum([\"default\", \"force-cache\", \"no-cache\", \"no-store\", \"only-if-cached\", \"reload\"]).optional(),\n});\n\n/**\n * Type representing the validated client options.\n */\nexport type ClientOptions = z.infer<typeof ClientOptionsSchema>;\n\n/**\n * Creates a Portal GraphQL client with the provided configuration.\n *\n * @param options - Configuration options for the Portal client\n * @param clientOptions - Additional GraphQL client configuration options\n * @returns An object containing the configured GraphQL client and graphql helper function\n * @throws If the provided options fail validation\n *\n * @example\n * import { createPortalClient } from \"@settlemint/sdk-portal\";\n * import { loadEnv } from \"@settlemint/sdk-utils/environment\";\n * import { createLogger, requestLogger } from \"@settlemint/sdk-utils/logging\";\n * import type { introspection } from \"@schemas/portal-env\";\n *\n * const env = await loadEnv(false, false);\n * const logger = createLogger();\n *\n * const { client: portalClient, graphql: portalGraphql } = createPortalClient<{\n * introspection: introspection;\n * disableMasking: true;\n * scalars: {\n * // Change unknown to the type you are using to store metadata\n * JSON: unknown;\n * };\n * }>(\n * {\n * instance: env.SETTLEMINT_PORTAL_GRAPHQL_ENDPOINT!,\n * accessToken: env.SETTLEMINT_ACCESS_TOKEN!,\n * },\n * {\n * fetch: requestLogger(logger, \"portal\", fetch) as typeof fetch,\n * },\n * );\n *\n * // Making GraphQL queries\n * const query = portalGraphql(`\n * query GetPendingTransactions {\n * getPendingTransactions {\n * count\n * }\n * }\n * `);\n *\n * const result = await portalClient.request(query);\n */\nexport function createPortalClient<const Setup extends AbstractSetupSchema>(\n options: ClientOptions,\n clientOptions?: RequestConfig,\n): {\n client: GraphQLClient;\n graphql: initGraphQLTada<Setup>;\n} {\n ensureServer();\n const validatedOptions = validate(ClientOptionsSchema, options);\n const graphql = initGraphQLTada<Setup>();\n const fullUrl = new URL(validatedOptions.instance).toString();\n\n return {\n client: new GraphQLClient(fullUrl, {\n ...clientOptions,\n headers: appendHeaders(clientOptions?.headers, { \"x-auth-token\": validatedOptions.accessToken }),\n }),\n graphql,\n };\n}\n\nexport type { FragmentOf, ResultOf, VariablesOf } from \"gql.tada\";\nexport { readFragment } from \"gql.tada\";\nexport {\n type Transaction,\n type TransactionEvent,\n type TransactionReceipt,\n type WaitForTransactionReceiptOptions,\n waitForTransactionReceipt,\n} from \"./utils/wait-for-transaction-receipt.js\";\nexport {\n type HandleWalletVerificationChallengeOptions,\n handleWalletVerificationChallenge,\n WalletVerificationChallengeError,\n type WalletVerificationType,\n} from \"./utils/wallet-verification-challenge.js\";\nexport { getWebsocketClient, type WebsocketClientOptions } from \"./utils/websocket-client.js\";\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"portal.js","names":["url: URL","transactionHash: string","options: WaitForTransactionReceiptOptions","timeout: number","subscription: AsyncIterableIterator<FormattedExecutionResult<GetTransactionResponse, unknown>>","message: string","code: string","pincode: string","salt: string","challenge: string","options: ClientOptions","clientOptions?: RequestConfig"],"sources":["../../src/utils/websocket-client.ts","../../src/utils/wait-for-transaction-receipt.ts","../../src/utils/wallet-verification-challenge.ts","../../src/portal.ts"],"sourcesContent":["import { createClient } from \"graphql-ws\";\n\n/**\n * Options for the GraphQL WebSocket client\n */\nexport interface WebsocketClientOptions {\n /**\n * The GraphQL endpoint URL for the Portal API\n */\n portalGraphqlEndpoint: string;\n /**\n * The access token for authentication with the Portal API\n */\n accessToken?: string;\n}\n\n/**\n * Creates a GraphQL WebSocket client for the Portal API\n *\n * @param {WebsocketClientOptions} options - The options for the client\n * @returns {Client} The GraphQL WebSocket client\n * @example\n * import { getWebsocketClient } from \"@settlemint/sdk-portal\";\n *\n * const client = getWebsocketClient({\n * portalGraphqlEndpoint: \"https://portal.settlemint.com/graphql\",\n * accessToken: \"your-access-token\",\n * });\n */\nexport function getWebsocketClient({ portalGraphqlEndpoint, accessToken }: WebsocketClientOptions) {\n if (!portalGraphqlEndpoint) {\n throw new Error(\"portalGraphqlEndpoint is required\");\n }\n const graphqlEndpoint = setWsProtocol(new URL(portalGraphqlEndpoint));\n return createClient({\n url: accessToken\n ? `${graphqlEndpoint.protocol}//${graphqlEndpoint.host}/${accessToken}${graphqlEndpoint.pathname}${graphqlEndpoint.search}`\n : graphqlEndpoint.toString(),\n });\n}\n\nfunction setWsProtocol(url: URL) {\n if (url.protocol === \"ws:\" || url.protocol === \"wss:\") {\n return url;\n }\n if (url.protocol === \"http:\") {\n url.protocol = \"ws:\";\n } else {\n url.protocol = \"wss:\";\n }\n return url;\n}\n","import type { FormattedExecutionResult } from \"graphql-ws\";\nimport type { Address, Hex, TransactionReceipt as TransactionReceiptViem } from \"viem\";\nimport { type WebsocketClientOptions, getWebsocketClient } from \"./websocket-client.js\";\n\n/**\n * Represents an event emitted during a transaction execution\n */\nexport interface TransactionEvent {\n /** The name of the event that was emitted */\n eventName: string;\n /** The arguments emitted by the event */\n args: Record<string, unknown>;\n /** Indexed event parameters used for filtering and searching */\n topics: Hex[];\n}\n\n/**\n * Represents the structure of a blockchain transaction receipt\n */\nexport interface TransactionReceipt extends TransactionReceiptViem<string, number, \"Success\" | \"Reverted\"> {\n /** The raw reason for transaction reversion, if applicable */\n revertReason: string;\n /** Human-readable version of the revert reason */\n revertReasonDecoded: string;\n /** Array of events emitted during the transaction */\n events: TransactionEvent[];\n /** The address of the contract deployed in the transaction */\n contractAddress: Address;\n}\n\n/**\n * Represents the structure of a blockchain transaction with its receipt\n */\nexport interface Transaction {\n receipt: TransactionReceipt;\n /** The hash of the transaction (duplicate of receipt.transactionHash) */\n transactionHash: string;\n /** The sender address (duplicate of receipt.from) */\n from: string;\n /** Timestamp when the transaction was created */\n createdAt: string;\n /** The contract address involved in the transaction */\n address: string;\n /** The name of the function called in the transaction */\n functionName: string;\n /** Whether the transaction is a contract deployment */\n isContract: boolean;\n}\n\ninterface GetTransactionResponse {\n getTransaction: Transaction;\n}\n\n/**\n * Options for waiting for a transaction receipt\n */\nexport interface WaitForTransactionReceiptOptions extends WebsocketClientOptions {\n /** Optional timeout in milliseconds before the operation fails */\n timeout?: number;\n}\n\n/**\n * Waits for a blockchain transaction receipt by subscribing to transaction updates via GraphQL.\n * This function polls until the transaction is confirmed or the timeout is reached.\n *\n * @param transactionHash - The hash of the transaction to wait for\n * @param options - Configuration options for the waiting process\n * @returns The transaction details including receipt information when the transaction is confirmed\n * @throws Error if the transaction receipt cannot be retrieved within the specified timeout\n *\n * @example\n * import { waitForTransactionReceipt } from \"@settlemint/sdk-portal\";\n *\n * const transaction = await waitForTransactionReceipt(\"0x123...\", {\n * portalGraphqlEndpoint: \"https://example.settlemint.com/graphql\",\n * accessToken: \"your-access-token\",\n * timeout: 30000 // 30 seconds timeout\n * });\n */\nexport async function waitForTransactionReceipt(transactionHash: string, options: WaitForTransactionReceiptOptions) {\n const wsClient = getWebsocketClient(options);\n const subscription = wsClient.iterate<GetTransactionResponse>({\n query: `subscription getTransaction($transactionHash: String!) {\n getTransaction(transactionHash: $transactionHash) {\n receipt {\n transactionHash\n to\n status\n from\n type\n revertReason\n revertReasonDecoded\n logs\n events\n contractAddress\n }\n transactionHash\n from\n createdAt\n address\n functionName\n isContract\n }\n }`,\n variables: { transactionHash },\n });\n const promises = [getTransactionFromSubscription(subscription)];\n if (options.timeout) {\n promises.push(createTimeoutPromise(options.timeout));\n }\n\n return Promise.race(promises);\n}\n\nfunction createTimeoutPromise(timeout: number): Promise<never> {\n return new Promise((_, reject) => {\n setTimeout(() => reject(new Error(\"Transaction receipt not found\")), timeout);\n });\n}\n\nasync function getTransactionFromSubscription(\n subscription: AsyncIterableIterator<FormattedExecutionResult<GetTransactionResponse, unknown>>,\n): Promise<Transaction> {\n for await (const result of subscription) {\n if (result?.data?.getTransaction?.receipt) {\n return result.data.getTransaction;\n }\n }\n throw new Error(\"No transaction found\");\n}\n","import { createHash } from \"node:crypto\";\nimport type { AbstractSetupSchema, initGraphQLTada } from \"gql.tada\";\nimport type { GraphQLClient } from \"graphql-request\";\nimport type { Address } from \"viem\";\n\n/**\n * Type representing the different types of wallet verification methods\n */\nexport type WalletVerificationType = \"PINCODE\" | \"OTP\" | \"SECRET_CODES\";\n\n/**\n * Custom error class for challenge-related errors\n */\nexport class WalletVerificationChallengeError 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 id: string;\n name: string;\n verificationId: string;\n verificationType: WalletVerificationType;\n challenge?: {\n salt: string;\n secret: string;\n };\n}\n\n/**\n * Response type for the CreateWalletVerificationChallenge mutation\n */\ninterface CreateWalletVerificationChallengeResponse {\n createWalletVerificationChallenge: 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: WalletVerificationType;\n /** Request id which can be added for tracing purposes */\n requestId?: string;\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 {WalletVerificationChallengeError} 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 requestId,\n}: HandleWalletVerificationChallengeOptions<Setup>): Promise<{\n challengeResponse: string;\n challengeId: string;\n}> {\n try {\n const requestHeaders = new Headers();\n if (requestId) {\n requestHeaders.append(\"x-request-id\", requestId);\n }\n const verificationChallenge = await portalClient.request<CreateWalletVerificationChallengeResponse>(\n portalGraphql(`\n mutation CreateWalletVerificationChallenge($userWalletAddress: String!, $verificationId: String!) {\n createWalletVerificationChallenge(\n userWalletAddress: $userWalletAddress\n verificationId: $verificationId\n ) {\n id\n name\n verificationId\n verificationType\n challenge {\n salt\n secret\n }\n }\n }\n `),\n {\n userWalletAddress,\n verificationId,\n },\n requestHeaders,\n );\n\n if (!verificationChallenge.createWalletVerificationChallenge) {\n throw new WalletVerificationChallengeError(\"No verification challenge received\", \"NO_CHALLENGES\");\n }\n\n if (verificationType === \"OTP\") {\n return {\n challengeResponse: code.toString(),\n challengeId: verificationChallenge.createWalletVerificationChallenge.id,\n };\n }\n\n if (verificationType === \"SECRET_CODES\") {\n // Add a hyphen after every 5 characters to format the secret code\n const formattedCode = code.toString().replace(/(.{5})(?=.)/, \"$1-\");\n return {\n challengeResponse: formattedCode,\n challengeId: verificationChallenge.createWalletVerificationChallenge.id,\n };\n }\n\n const { secret, salt } = verificationChallenge.createWalletVerificationChallenge.challenge ?? {};\n\n if (!secret || !salt) {\n throw new WalletVerificationChallengeError(\"Invalid challenge format\", \"INVALID_CHALLENGE\");\n }\n\n const challengeResponse = generateResponse(code.toString(), salt, secret);\n return {\n challengeResponse,\n challengeId: verificationChallenge.createWalletVerificationChallenge.id,\n };\n } catch (error) {\n if (error instanceof WalletVerificationChallengeError) {\n throw error;\n }\n throw new WalletVerificationChallengeError(\n \"Failed to process wallet verification challenge\",\n \"CHALLENGE_PROCESSING_ERROR\",\n );\n }\n}\n","import { appendHeaders } from \"@settlemint/sdk-utils/http\";\nimport { ensureServer } from \"@settlemint/sdk-utils/runtime\";\nimport { ApplicationAccessTokenSchema, UrlOrPathSchema, validate } from \"@settlemint/sdk-utils/validation\";\nimport { type AbstractSetupSchema, initGraphQLTada } from \"gql.tada\";\nimport { GraphQLClient } from \"graphql-request\";\nimport { z } from \"zod\";\n\n/**\n * Configuration options for the GraphQL client, excluding 'url' and 'exchanges'.\n */\nexport type RequestConfig = ConstructorParameters<typeof GraphQLClient>[1];\n\n/**\n * Schema for validating Portal client configuration options.\n */\nexport const ClientOptionsSchema = z.object({\n instance: UrlOrPathSchema,\n accessToken: ApplicationAccessTokenSchema.optional(),\n cache: z.enum([\"default\", \"force-cache\", \"no-cache\", \"no-store\", \"only-if-cached\", \"reload\"]).optional(),\n});\n\n/**\n * Type representing the validated client options.\n */\nexport type ClientOptions = z.infer<typeof ClientOptionsSchema>;\n\n/**\n * Creates a Portal GraphQL client with the provided configuration.\n *\n * @param options - Configuration options for the Portal client\n * @param clientOptions - Additional GraphQL client configuration options\n * @returns An object containing the configured GraphQL client and graphql helper function\n * @throws If the provided options fail validation\n *\n * @example\n * import { createPortalClient } from \"@settlemint/sdk-portal\";\n * import { loadEnv } from \"@settlemint/sdk-utils/environment\";\n * import { createLogger, requestLogger } from \"@settlemint/sdk-utils/logging\";\n * import type { introspection } from \"@schemas/portal-env\";\n *\n * const env = await loadEnv(false, false);\n * const logger = createLogger();\n *\n * const { client: portalClient, graphql: portalGraphql } = createPortalClient<{\n * introspection: introspection;\n * disableMasking: true;\n * scalars: {\n * // Change unknown to the type you are using to store metadata\n * JSON: unknown;\n * };\n * }>(\n * {\n * instance: env.SETTLEMINT_PORTAL_GRAPHQL_ENDPOINT!,\n * accessToken: env.SETTLEMINT_ACCESS_TOKEN!,\n * },\n * {\n * fetch: requestLogger(logger, \"portal\", fetch) as typeof fetch,\n * },\n * );\n *\n * // Making GraphQL queries\n * const query = portalGraphql(`\n * query GetPendingTransactions {\n * getPendingTransactions {\n * count\n * }\n * }\n * `);\n *\n * const result = await portalClient.request(query);\n */\nexport function createPortalClient<const Setup extends AbstractSetupSchema>(\n options: ClientOptions,\n clientOptions?: RequestConfig,\n): {\n client: GraphQLClient;\n graphql: initGraphQLTada<Setup>;\n} {\n ensureServer();\n const validatedOptions = validate(ClientOptionsSchema, options);\n const graphql = initGraphQLTada<Setup>();\n const fullUrl = new URL(validatedOptions.instance).toString();\n\n return {\n client: new GraphQLClient(fullUrl, {\n ...clientOptions,\n headers: appendHeaders(clientOptions?.headers, { \"x-auth-token\": validatedOptions.accessToken }),\n }),\n graphql,\n };\n}\n\nexport type { FragmentOf, ResultOf, VariablesOf } from \"gql.tada\";\nexport { readFragment } from \"gql.tada\";\nexport {\n type Transaction,\n type TransactionEvent,\n type TransactionReceipt,\n type WaitForTransactionReceiptOptions,\n waitForTransactionReceipt,\n} from \"./utils/wait-for-transaction-receipt.js\";\nexport {\n type HandleWalletVerificationChallengeOptions,\n handleWalletVerificationChallenge,\n WalletVerificationChallengeError,\n type WalletVerificationType,\n} from \"./utils/wallet-verification-challenge.js\";\nexport { getWebsocketClient, type WebsocketClientOptions } from \"./utils/websocket-client.js\";\n"],"mappings":"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"}
|
package/dist/portal.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"portal.cjs","names":["url: URL","transactionHash: string","options: WaitForTransactionReceiptOptions","timeout: number","subscription: AsyncIterableIterator<FormattedExecutionResult<GetTransactionResponse, unknown>>","message: string","code: string","pincode: string","salt: string","challenge: string","z","UrlOrPathSchema","ApplicationAccessTokenSchema","options: ClientOptions","clientOptions?: RequestConfig","GraphQLClient"],"sources":["../src/utils/websocket-client.ts","../src/utils/wait-for-transaction-receipt.ts","../src/utils/wallet-verification-challenge.ts","../src/portal.ts"],"sourcesContent":["import { createClient } from \"graphql-ws\";\n\n/**\n * Options for the GraphQL WebSocket client\n */\nexport interface WebsocketClientOptions {\n /**\n * The GraphQL endpoint URL for the Portal API\n */\n portalGraphqlEndpoint: string;\n /**\n * The access token for authentication with the Portal API\n */\n accessToken?: string;\n}\n\n/**\n * Creates a GraphQL WebSocket client for the Portal API\n *\n * @param {WebsocketClientOptions} options - The options for the client\n * @returns {Client} The GraphQL WebSocket client\n * @example\n * import { getWebsocketClient } from \"@settlemint/sdk-portal\";\n *\n * const client = getWebsocketClient({\n * portalGraphqlEndpoint: \"https://portal.settlemint.com/graphql\",\n * accessToken: \"your-access-token\",\n * });\n */\nexport function getWebsocketClient({ portalGraphqlEndpoint, accessToken }: WebsocketClientOptions) {\n if (!portalGraphqlEndpoint) {\n throw new Error(\"portalGraphqlEndpoint is required\");\n }\n const graphqlEndpoint = setWsProtocol(new URL(portalGraphqlEndpoint));\n return createClient({\n url: accessToken\n ? `${graphqlEndpoint.protocol}//${graphqlEndpoint.host}/${accessToken}${graphqlEndpoint.pathname}${graphqlEndpoint.search}`\n : graphqlEndpoint.toString(),\n });\n}\n\nfunction setWsProtocol(url: URL) {\n if (url.protocol === \"ws:\" || url.protocol === \"wss:\") {\n return url;\n }\n if (url.protocol === \"http:\") {\n url.protocol = \"ws:\";\n } else {\n url.protocol = \"wss:\";\n }\n return url;\n}\n","import type { FormattedExecutionResult } from \"graphql-ws\";\nimport type { Address, Hex, TransactionReceipt as TransactionReceiptViem } from \"viem\";\nimport { type WebsocketClientOptions, getWebsocketClient } from \"./websocket-client.js\";\n\n/**\n * Represents an event emitted during a transaction execution\n */\nexport interface TransactionEvent {\n /** The name of the event that was emitted */\n eventName: string;\n /** The arguments emitted by the event */\n args: Record<string, unknown>;\n /** Indexed event parameters used for filtering and searching */\n topics: Hex[];\n}\n\n/**\n * Represents the structure of a blockchain transaction receipt\n */\nexport interface TransactionReceipt extends TransactionReceiptViem<string, number, \"Success\" | \"Reverted\"> {\n /** The raw reason for transaction reversion, if applicable */\n revertReason: string;\n /** Human-readable version of the revert reason */\n revertReasonDecoded: string;\n /** Array of events emitted during the transaction */\n events: TransactionEvent[];\n /** The address of the contract deployed in the transaction */\n contractAddress: Address;\n}\n\n/**\n * Represents the structure of a blockchain transaction with its receipt\n */\nexport interface Transaction {\n receipt: TransactionReceipt;\n /** The hash of the transaction (duplicate of receipt.transactionHash) */\n transactionHash: string;\n /** The sender address (duplicate of receipt.from) */\n from: string;\n /** Timestamp when the transaction was created */\n createdAt: string;\n /** The contract address involved in the transaction */\n address: string;\n /** The name of the function called in the transaction */\n functionName: string;\n /** Whether the transaction is a contract deployment */\n isContract: boolean;\n}\n\ninterface GetTransactionResponse {\n getTransaction: Transaction;\n}\n\n/**\n * Options for waiting for a transaction receipt\n */\nexport interface WaitForTransactionReceiptOptions extends WebsocketClientOptions {\n /** Optional timeout in milliseconds before the operation fails */\n timeout?: number;\n}\n\n/**\n * Waits for a blockchain transaction receipt by subscribing to transaction updates via GraphQL.\n * This function polls until the transaction is confirmed or the timeout is reached.\n *\n * @param transactionHash - The hash of the transaction to wait for\n * @param options - Configuration options for the waiting process\n * @returns The transaction details including receipt information when the transaction is confirmed\n * @throws Error if the transaction receipt cannot be retrieved within the specified timeout\n *\n * @example\n * import { waitForTransactionReceipt } from \"@settlemint/sdk-portal\";\n *\n * const transaction = await waitForTransactionReceipt(\"0x123...\", {\n * portalGraphqlEndpoint: \"https://example.settlemint.com/graphql\",\n * accessToken: \"your-access-token\",\n * timeout: 30000 // 30 seconds timeout\n * });\n */\nexport async function waitForTransactionReceipt(transactionHash: string, options: WaitForTransactionReceiptOptions) {\n const wsClient = getWebsocketClient(options);\n const subscription = wsClient.iterate<GetTransactionResponse>({\n query: `subscription getTransaction($transactionHash: String!) {\n getTransaction(transactionHash: $transactionHash) {\n receipt {\n transactionHash\n to\n status\n from\n type\n revertReason\n revertReasonDecoded\n logs\n events\n contractAddress\n }\n transactionHash\n from\n createdAt\n address\n functionName\n isContract\n }\n }`,\n variables: { transactionHash },\n });\n const promises = [getTransactionFromSubscription(subscription)];\n if (options.timeout) {\n promises.push(createTimeoutPromise(options.timeout));\n }\n\n return Promise.race(promises);\n}\n\nfunction createTimeoutPromise(timeout: number): Promise<never> {\n return new Promise((_, reject) => {\n setTimeout(() => reject(new Error(\"Transaction receipt not found\")), timeout);\n });\n}\n\nasync function getTransactionFromSubscription(\n subscription: AsyncIterableIterator<FormattedExecutionResult<GetTransactionResponse, unknown>>,\n): Promise<Transaction> {\n for await (const result of subscription) {\n if (result?.data?.getTransaction?.receipt) {\n return result.data.getTransaction;\n }\n }\n throw new Error(\"No transaction found\");\n}\n","import { createHash } from \"node:crypto\";\nimport type { AbstractSetupSchema, initGraphQLTada } from \"gql.tada\";\nimport type { GraphQLClient } from \"graphql-request\";\nimport type { Address } from \"viem\";\n\n/**\n * Type representing the different types of wallet verification methods\n */\nexport type WalletVerificationType = \"PINCODE\" | \"OTP\" | \"SECRET_CODES\";\n\n/**\n * Custom error class for challenge-related errors\n */\nexport class WalletVerificationChallengeError 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 id: string;\n name: string;\n verificationId: string;\n verificationType: WalletVerificationType;\n challenge?: {\n salt: string;\n secret: string;\n };\n}\n\n/**\n * Response type for the CreateWalletVerificationChallenge mutation\n */\ninterface CreateWalletVerificationChallengeResponse {\n createWalletVerificationChallenge: 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: WalletVerificationType;\n /** Request id which can be added for tracing purposes */\n requestId?: string;\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 {WalletVerificationChallengeError} 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 requestId,\n}: HandleWalletVerificationChallengeOptions<Setup>): Promise<{\n challengeResponse: string;\n challengeId: string;\n}> {\n try {\n const requestHeaders = new Headers();\n if (requestId) {\n requestHeaders.append(\"x-request-id\", requestId);\n }\n const verificationChallenge = await portalClient.request<CreateWalletVerificationChallengeResponse>(\n portalGraphql(`\n mutation CreateWalletVerificationChallenge($userWalletAddress: String!, $verificationId: String!) {\n createWalletVerificationChallenge(\n userWalletAddress: $userWalletAddress\n verificationId: $verificationId\n ) {\n id\n name\n verificationId\n verificationType\n challenge {\n salt\n secret\n }\n }\n }\n `),\n {\n userWalletAddress,\n verificationId,\n },\n requestHeaders,\n );\n\n if (!verificationChallenge.createWalletVerificationChallenge) {\n throw new WalletVerificationChallengeError(\"No verification challenge received\", \"NO_CHALLENGES\");\n }\n\n if (verificationType === \"OTP\") {\n return {\n challengeResponse: code.toString(),\n challengeId: verificationChallenge.createWalletVerificationChallenge.id,\n };\n }\n\n if (verificationType === \"SECRET_CODES\") {\n // Add - separator to the code\n const formattedCode = code.toString().replace(/(.{5})(?=.)/, \"$1-\");\n return {\n challengeResponse: formattedCode,\n challengeId: verificationChallenge.createWalletVerificationChallenge.id,\n };\n }\n\n const { secret, salt } = verificationChallenge.createWalletVerificationChallenge.challenge ?? {};\n\n if (!secret || !salt) {\n throw new WalletVerificationChallengeError(\"Invalid challenge format\", \"INVALID_CHALLENGE\");\n }\n\n const challengeResponse = generateResponse(code.toString(), salt, secret);\n return {\n challengeResponse,\n challengeId: verificationChallenge.createWalletVerificationChallenge.id,\n };\n } catch (error) {\n if (error instanceof WalletVerificationChallengeError) {\n throw error;\n }\n throw new WalletVerificationChallengeError(\n \"Failed to process wallet verification challenge\",\n \"CHALLENGE_PROCESSING_ERROR\",\n );\n }\n}\n","import { appendHeaders } from \"@settlemint/sdk-utils/http\";\nimport { ensureServer } from \"@settlemint/sdk-utils/runtime\";\nimport { ApplicationAccessTokenSchema, UrlOrPathSchema, validate } from \"@settlemint/sdk-utils/validation\";\nimport { type AbstractSetupSchema, initGraphQLTada } from \"gql.tada\";\nimport { GraphQLClient } from \"graphql-request\";\nimport { z } from \"zod\";\n\n/**\n * Configuration options for the GraphQL client, excluding 'url' and 'exchanges'.\n */\nexport type RequestConfig = ConstructorParameters<typeof GraphQLClient>[1];\n\n/**\n * Schema for validating Portal client configuration options.\n */\nexport const ClientOptionsSchema = z.object({\n instance: UrlOrPathSchema,\n accessToken: ApplicationAccessTokenSchema.optional(),\n cache: z.enum([\"default\", \"force-cache\", \"no-cache\", \"no-store\", \"only-if-cached\", \"reload\"]).optional(),\n});\n\n/**\n * Type representing the validated client options.\n */\nexport type ClientOptions = z.infer<typeof ClientOptionsSchema>;\n\n/**\n * Creates a Portal GraphQL client with the provided configuration.\n *\n * @param options - Configuration options for the Portal client\n * @param clientOptions - Additional GraphQL client configuration options\n * @returns An object containing the configured GraphQL client and graphql helper function\n * @throws If the provided options fail validation\n *\n * @example\n * import { createPortalClient } from \"@settlemint/sdk-portal\";\n * import { loadEnv } from \"@settlemint/sdk-utils/environment\";\n * import { createLogger, requestLogger } from \"@settlemint/sdk-utils/logging\";\n * import type { introspection } from \"@schemas/portal-env\";\n *\n * const env = await loadEnv(false, false);\n * const logger = createLogger();\n *\n * const { client: portalClient, graphql: portalGraphql } = createPortalClient<{\n * introspection: introspection;\n * disableMasking: true;\n * scalars: {\n * // Change unknown to the type you are using to store metadata\n * JSON: unknown;\n * };\n * }>(\n * {\n * instance: env.SETTLEMINT_PORTAL_GRAPHQL_ENDPOINT!,\n * accessToken: env.SETTLEMINT_ACCESS_TOKEN!,\n * },\n * {\n * fetch: requestLogger(logger, \"portal\", fetch) as typeof fetch,\n * },\n * );\n *\n * // Making GraphQL queries\n * const query = portalGraphql(`\n * query GetPendingTransactions {\n * getPendingTransactions {\n * count\n * }\n * }\n * `);\n *\n * const result = await portalClient.request(query);\n */\nexport function createPortalClient<const Setup extends AbstractSetupSchema>(\n options: ClientOptions,\n clientOptions?: RequestConfig,\n): {\n client: GraphQLClient;\n graphql: initGraphQLTada<Setup>;\n} {\n ensureServer();\n const validatedOptions = validate(ClientOptionsSchema, options);\n const graphql = initGraphQLTada<Setup>();\n const fullUrl = new URL(validatedOptions.instance).toString();\n\n return {\n client: new GraphQLClient(fullUrl, {\n ...clientOptions,\n headers: appendHeaders(clientOptions?.headers, { \"x-auth-token\": validatedOptions.accessToken }),\n }),\n graphql,\n };\n}\n\nexport type { FragmentOf, ResultOf, VariablesOf } from \"gql.tada\";\nexport { readFragment } from \"gql.tada\";\nexport {\n type Transaction,\n type TransactionEvent,\n type TransactionReceipt,\n type WaitForTransactionReceiptOptions,\n waitForTransactionReceipt,\n} from \"./utils/wait-for-transaction-receipt.js\";\nexport {\n type HandleWalletVerificationChallengeOptions,\n handleWalletVerificationChallenge,\n WalletVerificationChallengeError,\n type WalletVerificationType,\n} from \"./utils/wallet-verification-challenge.js\";\nexport { getWebsocketClient, type WebsocketClientOptions } from \"./utils/websocket-client.js\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BA,SAAgB,mBAAmB,EAAE,uBAAuB,aAAqC,EAAE;AACjG,KAAI,CAAC,uBAAuB;AAC1B,QAAM,IAAI,MAAM;CACjB;CACD,MAAM,kBAAkB,cAAc,IAAI,IAAI,uBAAuB;AACrE,qCAAoB,EAClB,KAAK,cACD,GAAG,gBAAgB,SAAS,EAAE,EAAE,gBAAgB,KAAK,CAAC,EAAE,cAAc,gBAAgB,WAAW,gBAAgB,QAAQ,GACzH,gBAAgB,UAAU,CAC/B,EAAC;AACH;AAED,SAAS,cAAcA,KAAU;AAC/B,KAAI,IAAI,aAAa,SAAS,IAAI,aAAa,QAAQ;AACrD,SAAO;CACR;AACD,KAAI,IAAI,aAAa,SAAS;EAC5B,IAAI,WAAW;CAChB,OAAM;EACL,IAAI,WAAW;CAChB;AACD,QAAO;AACR;;;;;;;;;;;;;;;;;;;;;;AC4BD,eAAsB,0BAA0BC,iBAAyBC,SAA2C;CAClH,MAAM,WAAW,mBAAmB,QAAQ;CAC5C,MAAM,eAAe,SAAS,QAAgC;EAC5D,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;OAqBL,CAAC;EACJ,WAAW,EAAE,gBAAiB;CAC/B,EAAC;CACF,MAAM,WAAW,CAAC,+BAA+B,aAAa,AAAC;AAC/D,KAAI,QAAQ,SAAS;EACnB,SAAS,KAAK,qBAAqB,QAAQ,QAAQ,CAAC;CACrD;AAED,QAAO,QAAQ,KAAK,SAAS;AAC9B;AAED,SAAS,qBAAqBC,SAAiC;AAC7D,QAAO,IAAI,QAAQ,CAAC,GAAG,WAAW;EAChC,WAAW,MAAM,OAAO,IAAI,MAAM,iCAAiC,EAAE,QAAQ;CAC9E;AACF;AAED,eAAe,+BACbC,cACsB;AACtB,YAAW,MAAM,UAAU,cAAc;AACvC,MAAI,QAAQ,MAAM,gBAAgB,SAAS;AACzC,UAAO,OAAO,KAAK;EACpB;CACF;AACD,OAAM,IAAI,MAAM;AACjB;;;;;;;ACpHD,IAAa,mCAAb,cAAsD,MAAM;CAC1D,AAAS;CAET,YAAYC,SAAiBC,MAAc;EACzC,MAAM,QAAQ;EACd,KAAK,OAAO;EACZ,KAAK,OAAO;CACb;AACF;;;;;;;AA6BD,SAAS,YAAYC,SAAiBC,MAAsB;AAC1D,oCAAkB,SAAS,CAAC,OAAO,GAAG,OAAO,SAAS,CAAC,CAAC,OAAO,MAAM;AACtE;;;;;;;;AASD,SAAS,iBAAiBD,SAAiBC,MAAcC,WAA2B;CAClF,MAAM,gBAAgB,YAAY,SAAS,KAAK;AAChD,oCAAkB,SAAS,CAAC,OAAO,GAAG,cAAc,CAAC,EAAE,WAAW,CAAC,CAAC,OAAO,MAAM;AAClF;;;;;;;;;;;;;;;;;;;;;;;;;AA8CD,eAAsB,kCAA2E,EAC/F,cACA,eACA,gBACA,mBACA,MACA,kBACA,WACgD,EAG/C;AACD,KAAI;EACF,MAAM,iBAAiB,IAAI;AAC3B,MAAI,WAAW;GACb,eAAe,OAAO,gBAAgB,UAAU;EACjD;EACD,MAAM,wBAAwB,MAAM,aAAa,QAC/C,cAAc,CAAC;;;;;;;;;;;;;;;;MAgBf,CAAC,CAAC,EACF;GACE;GACA;EACD,GACD,eACD;AAED,MAAI,CAAC,sBAAsB,mCAAmC;AAC5D,SAAM,IAAI,iCAAiC,sCAAsC;EAClF;AAED,MAAI,qBAAqB,OAAO;AAC9B,UAAO;IACL,mBAAmB,KAAK,UAAU;IAClC,aAAa,sBAAsB,kCAAkC;GACtE;EACF;AAED,MAAI,qBAAqB,gBAAgB;GAEvC,MAAM,gBAAgB,KAAK,UAAU,CAAC,QAAQ,eAAe,MAAM;AACnE,UAAO;IACL,mBAAmB;IACnB,aAAa,sBAAsB,kCAAkC;GACtE;EACF;EAED,MAAM,EAAE,QAAQ,MAAM,GAAG,sBAAsB,kCAAkC,aAAa,CAAE;AAEhG,MAAI,CAAC,UAAU,CAAC,MAAM;AACpB,SAAM,IAAI,iCAAiC,4BAA4B;EACxE;EAED,MAAM,oBAAoB,iBAAiB,KAAK,UAAU,EAAE,MAAM,OAAO;AACzE,SAAO;GACL;GACA,aAAa,sBAAsB,kCAAkC;EACtE;CACF,SAAQ,OAAO;AACd,MAAI,iBAAiB,kCAAkC;AACrD,SAAM;EACP;AACD,QAAM,IAAI,iCACR,mDACA;CAEH;AACF;;;;;;;ACjLD,MAAa,sBAAsBC,MAAE,OAAO;CAC1C,UAAUC;CACV,aAAaC,+DAA6B,UAAU;CACpD,OAAOF,MAAE,KAAK;EAAC;EAAW;EAAe;EAAY;EAAY;EAAkB;CAAS,EAAC,CAAC,UAAU;AACzG,EAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoDF,SAAgB,mBACdG,SACAC,eAIA;mDACc;CACd,MAAM,mEAA4B,qBAAqB,QAAQ;CAC/D,MAAM,yCAAkC;CACxC,MAAM,UAAU,IAAI,IAAI,iBAAiB,UAAU,UAAU;AAE7D,QAAO;EACL,QAAQ,IAAIC,8BAAc,SAAS;GACjC,GAAG;GACH,wDAAuB,eAAe,SAAS,EAAE,gBAAgB,iBAAiB,YAAa,EAAC;EACjG;EACD;CACD;AACF"}
|
|
1
|
+
{"version":3,"file":"portal.cjs","names":["url: URL","transactionHash: string","options: WaitForTransactionReceiptOptions","timeout: number","subscription: AsyncIterableIterator<FormattedExecutionResult<GetTransactionResponse, unknown>>","message: string","code: string","pincode: string","salt: string","challenge: string","z","UrlOrPathSchema","ApplicationAccessTokenSchema","options: ClientOptions","clientOptions?: RequestConfig","GraphQLClient"],"sources":["../src/utils/websocket-client.ts","../src/utils/wait-for-transaction-receipt.ts","../src/utils/wallet-verification-challenge.ts","../src/portal.ts"],"sourcesContent":["import { createClient } from \"graphql-ws\";\n\n/**\n * Options for the GraphQL WebSocket client\n */\nexport interface WebsocketClientOptions {\n /**\n * The GraphQL endpoint URL for the Portal API\n */\n portalGraphqlEndpoint: string;\n /**\n * The access token for authentication with the Portal API\n */\n accessToken?: string;\n}\n\n/**\n * Creates a GraphQL WebSocket client for the Portal API\n *\n * @param {WebsocketClientOptions} options - The options for the client\n * @returns {Client} The GraphQL WebSocket client\n * @example\n * import { getWebsocketClient } from \"@settlemint/sdk-portal\";\n *\n * const client = getWebsocketClient({\n * portalGraphqlEndpoint: \"https://portal.settlemint.com/graphql\",\n * accessToken: \"your-access-token\",\n * });\n */\nexport function getWebsocketClient({ portalGraphqlEndpoint, accessToken }: WebsocketClientOptions) {\n if (!portalGraphqlEndpoint) {\n throw new Error(\"portalGraphqlEndpoint is required\");\n }\n const graphqlEndpoint = setWsProtocol(new URL(portalGraphqlEndpoint));\n return createClient({\n url: accessToken\n ? `${graphqlEndpoint.protocol}//${graphqlEndpoint.host}/${accessToken}${graphqlEndpoint.pathname}${graphqlEndpoint.search}`\n : graphqlEndpoint.toString(),\n });\n}\n\nfunction setWsProtocol(url: URL) {\n if (url.protocol === \"ws:\" || url.protocol === \"wss:\") {\n return url;\n }\n if (url.protocol === \"http:\") {\n url.protocol = \"ws:\";\n } else {\n url.protocol = \"wss:\";\n }\n return url;\n}\n","import type { FormattedExecutionResult } from \"graphql-ws\";\nimport type { Address, Hex, TransactionReceipt as TransactionReceiptViem } from \"viem\";\nimport { type WebsocketClientOptions, getWebsocketClient } from \"./websocket-client.js\";\n\n/**\n * Represents an event emitted during a transaction execution\n */\nexport interface TransactionEvent {\n /** The name of the event that was emitted */\n eventName: string;\n /** The arguments emitted by the event */\n args: Record<string, unknown>;\n /** Indexed event parameters used for filtering and searching */\n topics: Hex[];\n}\n\n/**\n * Represents the structure of a blockchain transaction receipt\n */\nexport interface TransactionReceipt extends TransactionReceiptViem<string, number, \"Success\" | \"Reverted\"> {\n /** The raw reason for transaction reversion, if applicable */\n revertReason: string;\n /** Human-readable version of the revert reason */\n revertReasonDecoded: string;\n /** Array of events emitted during the transaction */\n events: TransactionEvent[];\n /** The address of the contract deployed in the transaction */\n contractAddress: Address;\n}\n\n/**\n * Represents the structure of a blockchain transaction with its receipt\n */\nexport interface Transaction {\n receipt: TransactionReceipt;\n /** The hash of the transaction (duplicate of receipt.transactionHash) */\n transactionHash: string;\n /** The sender address (duplicate of receipt.from) */\n from: string;\n /** Timestamp when the transaction was created */\n createdAt: string;\n /** The contract address involved in the transaction */\n address: string;\n /** The name of the function called in the transaction */\n functionName: string;\n /** Whether the transaction is a contract deployment */\n isContract: boolean;\n}\n\ninterface GetTransactionResponse {\n getTransaction: Transaction;\n}\n\n/**\n * Options for waiting for a transaction receipt\n */\nexport interface WaitForTransactionReceiptOptions extends WebsocketClientOptions {\n /** Optional timeout in milliseconds before the operation fails */\n timeout?: number;\n}\n\n/**\n * Waits for a blockchain transaction receipt by subscribing to transaction updates via GraphQL.\n * This function polls until the transaction is confirmed or the timeout is reached.\n *\n * @param transactionHash - The hash of the transaction to wait for\n * @param options - Configuration options for the waiting process\n * @returns The transaction details including receipt information when the transaction is confirmed\n * @throws Error if the transaction receipt cannot be retrieved within the specified timeout\n *\n * @example\n * import { waitForTransactionReceipt } from \"@settlemint/sdk-portal\";\n *\n * const transaction = await waitForTransactionReceipt(\"0x123...\", {\n * portalGraphqlEndpoint: \"https://example.settlemint.com/graphql\",\n * accessToken: \"your-access-token\",\n * timeout: 30000 // 30 seconds timeout\n * });\n */\nexport async function waitForTransactionReceipt(transactionHash: string, options: WaitForTransactionReceiptOptions) {\n const wsClient = getWebsocketClient(options);\n const subscription = wsClient.iterate<GetTransactionResponse>({\n query: `subscription getTransaction($transactionHash: String!) {\n getTransaction(transactionHash: $transactionHash) {\n receipt {\n transactionHash\n to\n status\n from\n type\n revertReason\n revertReasonDecoded\n logs\n events\n contractAddress\n }\n transactionHash\n from\n createdAt\n address\n functionName\n isContract\n }\n }`,\n variables: { transactionHash },\n });\n const promises = [getTransactionFromSubscription(subscription)];\n if (options.timeout) {\n promises.push(createTimeoutPromise(options.timeout));\n }\n\n return Promise.race(promises);\n}\n\nfunction createTimeoutPromise(timeout: number): Promise<never> {\n return new Promise((_, reject) => {\n setTimeout(() => reject(new Error(\"Transaction receipt not found\")), timeout);\n });\n}\n\nasync function getTransactionFromSubscription(\n subscription: AsyncIterableIterator<FormattedExecutionResult<GetTransactionResponse, unknown>>,\n): Promise<Transaction> {\n for await (const result of subscription) {\n if (result?.data?.getTransaction?.receipt) {\n return result.data.getTransaction;\n }\n }\n throw new Error(\"No transaction found\");\n}\n","import { createHash } from \"node:crypto\";\nimport type { AbstractSetupSchema, initGraphQLTada } from \"gql.tada\";\nimport type { GraphQLClient } from \"graphql-request\";\nimport type { Address } from \"viem\";\n\n/**\n * Type representing the different types of wallet verification methods\n */\nexport type WalletVerificationType = \"PINCODE\" | \"OTP\" | \"SECRET_CODES\";\n\n/**\n * Custom error class for challenge-related errors\n */\nexport class WalletVerificationChallengeError 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 id: string;\n name: string;\n verificationId: string;\n verificationType: WalletVerificationType;\n challenge?: {\n salt: string;\n secret: string;\n };\n}\n\n/**\n * Response type for the CreateWalletVerificationChallenge mutation\n */\ninterface CreateWalletVerificationChallengeResponse {\n createWalletVerificationChallenge: 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: WalletVerificationType;\n /** Request id which can be added for tracing purposes */\n requestId?: string;\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 {WalletVerificationChallengeError} 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 requestId,\n}: HandleWalletVerificationChallengeOptions<Setup>): Promise<{\n challengeResponse: string;\n challengeId: string;\n}> {\n try {\n const requestHeaders = new Headers();\n if (requestId) {\n requestHeaders.append(\"x-request-id\", requestId);\n }\n const verificationChallenge = await portalClient.request<CreateWalletVerificationChallengeResponse>(\n portalGraphql(`\n mutation CreateWalletVerificationChallenge($userWalletAddress: String!, $verificationId: String!) {\n createWalletVerificationChallenge(\n userWalletAddress: $userWalletAddress\n verificationId: $verificationId\n ) {\n id\n name\n verificationId\n verificationType\n challenge {\n salt\n secret\n }\n }\n }\n `),\n {\n userWalletAddress,\n verificationId,\n },\n requestHeaders,\n );\n\n if (!verificationChallenge.createWalletVerificationChallenge) {\n throw new WalletVerificationChallengeError(\"No verification challenge received\", \"NO_CHALLENGES\");\n }\n\n if (verificationType === \"OTP\") {\n return {\n challengeResponse: code.toString(),\n challengeId: verificationChallenge.createWalletVerificationChallenge.id,\n };\n }\n\n if (verificationType === \"SECRET_CODES\") {\n // Add a hyphen after every 5 characters to format the secret code\n const formattedCode = code.toString().replace(/(.{5})(?=.)/, \"$1-\");\n return {\n challengeResponse: formattedCode,\n challengeId: verificationChallenge.createWalletVerificationChallenge.id,\n };\n }\n\n const { secret, salt } = verificationChallenge.createWalletVerificationChallenge.challenge ?? {};\n\n if (!secret || !salt) {\n throw new WalletVerificationChallengeError(\"Invalid challenge format\", \"INVALID_CHALLENGE\");\n }\n\n const challengeResponse = generateResponse(code.toString(), salt, secret);\n return {\n challengeResponse,\n challengeId: verificationChallenge.createWalletVerificationChallenge.id,\n };\n } catch (error) {\n if (error instanceof WalletVerificationChallengeError) {\n throw error;\n }\n throw new WalletVerificationChallengeError(\n \"Failed to process wallet verification challenge\",\n \"CHALLENGE_PROCESSING_ERROR\",\n );\n }\n}\n","import { appendHeaders } from \"@settlemint/sdk-utils/http\";\nimport { ensureServer } from \"@settlemint/sdk-utils/runtime\";\nimport { ApplicationAccessTokenSchema, UrlOrPathSchema, validate } from \"@settlemint/sdk-utils/validation\";\nimport { type AbstractSetupSchema, initGraphQLTada } from \"gql.tada\";\nimport { GraphQLClient } from \"graphql-request\";\nimport { z } from \"zod\";\n\n/**\n * Configuration options for the GraphQL client, excluding 'url' and 'exchanges'.\n */\nexport type RequestConfig = ConstructorParameters<typeof GraphQLClient>[1];\n\n/**\n * Schema for validating Portal client configuration options.\n */\nexport const ClientOptionsSchema = z.object({\n instance: UrlOrPathSchema,\n accessToken: ApplicationAccessTokenSchema.optional(),\n cache: z.enum([\"default\", \"force-cache\", \"no-cache\", \"no-store\", \"only-if-cached\", \"reload\"]).optional(),\n});\n\n/**\n * Type representing the validated client options.\n */\nexport type ClientOptions = z.infer<typeof ClientOptionsSchema>;\n\n/**\n * Creates a Portal GraphQL client with the provided configuration.\n *\n * @param options - Configuration options for the Portal client\n * @param clientOptions - Additional GraphQL client configuration options\n * @returns An object containing the configured GraphQL client and graphql helper function\n * @throws If the provided options fail validation\n *\n * @example\n * import { createPortalClient } from \"@settlemint/sdk-portal\";\n * import { loadEnv } from \"@settlemint/sdk-utils/environment\";\n * import { createLogger, requestLogger } from \"@settlemint/sdk-utils/logging\";\n * import type { introspection } from \"@schemas/portal-env\";\n *\n * const env = await loadEnv(false, false);\n * const logger = createLogger();\n *\n * const { client: portalClient, graphql: portalGraphql } = createPortalClient<{\n * introspection: introspection;\n * disableMasking: true;\n * scalars: {\n * // Change unknown to the type you are using to store metadata\n * JSON: unknown;\n * };\n * }>(\n * {\n * instance: env.SETTLEMINT_PORTAL_GRAPHQL_ENDPOINT!,\n * accessToken: env.SETTLEMINT_ACCESS_TOKEN!,\n * },\n * {\n * fetch: requestLogger(logger, \"portal\", fetch) as typeof fetch,\n * },\n * );\n *\n * // Making GraphQL queries\n * const query = portalGraphql(`\n * query GetPendingTransactions {\n * getPendingTransactions {\n * count\n * }\n * }\n * `);\n *\n * const result = await portalClient.request(query);\n */\nexport function createPortalClient<const Setup extends AbstractSetupSchema>(\n options: ClientOptions,\n clientOptions?: RequestConfig,\n): {\n client: GraphQLClient;\n graphql: initGraphQLTada<Setup>;\n} {\n ensureServer();\n const validatedOptions = validate(ClientOptionsSchema, options);\n const graphql = initGraphQLTada<Setup>();\n const fullUrl = new URL(validatedOptions.instance).toString();\n\n return {\n client: new GraphQLClient(fullUrl, {\n ...clientOptions,\n headers: appendHeaders(clientOptions?.headers, { \"x-auth-token\": validatedOptions.accessToken }),\n }),\n graphql,\n };\n}\n\nexport type { FragmentOf, ResultOf, VariablesOf } from \"gql.tada\";\nexport { readFragment } from \"gql.tada\";\nexport {\n type Transaction,\n type TransactionEvent,\n type TransactionReceipt,\n type WaitForTransactionReceiptOptions,\n waitForTransactionReceipt,\n} from \"./utils/wait-for-transaction-receipt.js\";\nexport {\n type HandleWalletVerificationChallengeOptions,\n handleWalletVerificationChallenge,\n WalletVerificationChallengeError,\n type WalletVerificationType,\n} from \"./utils/wallet-verification-challenge.js\";\nexport { getWebsocketClient, type WebsocketClientOptions } from \"./utils/websocket-client.js\";\n"],"mappings":"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"}
|
package/dist/portal.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"portal.js","names":["url: URL","transactionHash: string","options: WaitForTransactionReceiptOptions","timeout: number","subscription: AsyncIterableIterator<FormattedExecutionResult<GetTransactionResponse, unknown>>","message: string","code: string","pincode: string","salt: string","challenge: string","options: ClientOptions","clientOptions?: RequestConfig"],"sources":["../src/utils/websocket-client.ts","../src/utils/wait-for-transaction-receipt.ts","../src/utils/wallet-verification-challenge.ts","../src/portal.ts"],"sourcesContent":["import { createClient } from \"graphql-ws\";\n\n/**\n * Options for the GraphQL WebSocket client\n */\nexport interface WebsocketClientOptions {\n /**\n * The GraphQL endpoint URL for the Portal API\n */\n portalGraphqlEndpoint: string;\n /**\n * The access token for authentication with the Portal API\n */\n accessToken?: string;\n}\n\n/**\n * Creates a GraphQL WebSocket client for the Portal API\n *\n * @param {WebsocketClientOptions} options - The options for the client\n * @returns {Client} The GraphQL WebSocket client\n * @example\n * import { getWebsocketClient } from \"@settlemint/sdk-portal\";\n *\n * const client = getWebsocketClient({\n * portalGraphqlEndpoint: \"https://portal.settlemint.com/graphql\",\n * accessToken: \"your-access-token\",\n * });\n */\nexport function getWebsocketClient({ portalGraphqlEndpoint, accessToken }: WebsocketClientOptions) {\n if (!portalGraphqlEndpoint) {\n throw new Error(\"portalGraphqlEndpoint is required\");\n }\n const graphqlEndpoint = setWsProtocol(new URL(portalGraphqlEndpoint));\n return createClient({\n url: accessToken\n ? `${graphqlEndpoint.protocol}//${graphqlEndpoint.host}/${accessToken}${graphqlEndpoint.pathname}${graphqlEndpoint.search}`\n : graphqlEndpoint.toString(),\n });\n}\n\nfunction setWsProtocol(url: URL) {\n if (url.protocol === \"ws:\" || url.protocol === \"wss:\") {\n return url;\n }\n if (url.protocol === \"http:\") {\n url.protocol = \"ws:\";\n } else {\n url.protocol = \"wss:\";\n }\n return url;\n}\n","import type { FormattedExecutionResult } from \"graphql-ws\";\nimport type { Address, Hex, TransactionReceipt as TransactionReceiptViem } from \"viem\";\nimport { type WebsocketClientOptions, getWebsocketClient } from \"./websocket-client.js\";\n\n/**\n * Represents an event emitted during a transaction execution\n */\nexport interface TransactionEvent {\n /** The name of the event that was emitted */\n eventName: string;\n /** The arguments emitted by the event */\n args: Record<string, unknown>;\n /** Indexed event parameters used for filtering and searching */\n topics: Hex[];\n}\n\n/**\n * Represents the structure of a blockchain transaction receipt\n */\nexport interface TransactionReceipt extends TransactionReceiptViem<string, number, \"Success\" | \"Reverted\"> {\n /** The raw reason for transaction reversion, if applicable */\n revertReason: string;\n /** Human-readable version of the revert reason */\n revertReasonDecoded: string;\n /** Array of events emitted during the transaction */\n events: TransactionEvent[];\n /** The address of the contract deployed in the transaction */\n contractAddress: Address;\n}\n\n/**\n * Represents the structure of a blockchain transaction with its receipt\n */\nexport interface Transaction {\n receipt: TransactionReceipt;\n /** The hash of the transaction (duplicate of receipt.transactionHash) */\n transactionHash: string;\n /** The sender address (duplicate of receipt.from) */\n from: string;\n /** Timestamp when the transaction was created */\n createdAt: string;\n /** The contract address involved in the transaction */\n address: string;\n /** The name of the function called in the transaction */\n functionName: string;\n /** Whether the transaction is a contract deployment */\n isContract: boolean;\n}\n\ninterface GetTransactionResponse {\n getTransaction: Transaction;\n}\n\n/**\n * Options for waiting for a transaction receipt\n */\nexport interface WaitForTransactionReceiptOptions extends WebsocketClientOptions {\n /** Optional timeout in milliseconds before the operation fails */\n timeout?: number;\n}\n\n/**\n * Waits for a blockchain transaction receipt by subscribing to transaction updates via GraphQL.\n * This function polls until the transaction is confirmed or the timeout is reached.\n *\n * @param transactionHash - The hash of the transaction to wait for\n * @param options - Configuration options for the waiting process\n * @returns The transaction details including receipt information when the transaction is confirmed\n * @throws Error if the transaction receipt cannot be retrieved within the specified timeout\n *\n * @example\n * import { waitForTransactionReceipt } from \"@settlemint/sdk-portal\";\n *\n * const transaction = await waitForTransactionReceipt(\"0x123...\", {\n * portalGraphqlEndpoint: \"https://example.settlemint.com/graphql\",\n * accessToken: \"your-access-token\",\n * timeout: 30000 // 30 seconds timeout\n * });\n */\nexport async function waitForTransactionReceipt(transactionHash: string, options: WaitForTransactionReceiptOptions) {\n const wsClient = getWebsocketClient(options);\n const subscription = wsClient.iterate<GetTransactionResponse>({\n query: `subscription getTransaction($transactionHash: String!) {\n getTransaction(transactionHash: $transactionHash) {\n receipt {\n transactionHash\n to\n status\n from\n type\n revertReason\n revertReasonDecoded\n logs\n events\n contractAddress\n }\n transactionHash\n from\n createdAt\n address\n functionName\n isContract\n }\n }`,\n variables: { transactionHash },\n });\n const promises = [getTransactionFromSubscription(subscription)];\n if (options.timeout) {\n promises.push(createTimeoutPromise(options.timeout));\n }\n\n return Promise.race(promises);\n}\n\nfunction createTimeoutPromise(timeout: number): Promise<never> {\n return new Promise((_, reject) => {\n setTimeout(() => reject(new Error(\"Transaction receipt not found\")), timeout);\n });\n}\n\nasync function getTransactionFromSubscription(\n subscription: AsyncIterableIterator<FormattedExecutionResult<GetTransactionResponse, unknown>>,\n): Promise<Transaction> {\n for await (const result of subscription) {\n if (result?.data?.getTransaction?.receipt) {\n return result.data.getTransaction;\n }\n }\n throw new Error(\"No transaction found\");\n}\n","import { createHash } from \"node:crypto\";\nimport type { AbstractSetupSchema, initGraphQLTada } from \"gql.tada\";\nimport type { GraphQLClient } from \"graphql-request\";\nimport type { Address } from \"viem\";\n\n/**\n * Type representing the different types of wallet verification methods\n */\nexport type WalletVerificationType = \"PINCODE\" | \"OTP\" | \"SECRET_CODES\";\n\n/**\n * Custom error class for challenge-related errors\n */\nexport class WalletVerificationChallengeError 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 id: string;\n name: string;\n verificationId: string;\n verificationType: WalletVerificationType;\n challenge?: {\n salt: string;\n secret: string;\n };\n}\n\n/**\n * Response type for the CreateWalletVerificationChallenge mutation\n */\ninterface CreateWalletVerificationChallengeResponse {\n createWalletVerificationChallenge: 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: WalletVerificationType;\n /** Request id which can be added for tracing purposes */\n requestId?: string;\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 {WalletVerificationChallengeError} 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 requestId,\n}: HandleWalletVerificationChallengeOptions<Setup>): Promise<{\n challengeResponse: string;\n challengeId: string;\n}> {\n try {\n const requestHeaders = new Headers();\n if (requestId) {\n requestHeaders.append(\"x-request-id\", requestId);\n }\n const verificationChallenge = await portalClient.request<CreateWalletVerificationChallengeResponse>(\n portalGraphql(`\n mutation CreateWalletVerificationChallenge($userWalletAddress: String!, $verificationId: String!) {\n createWalletVerificationChallenge(\n userWalletAddress: $userWalletAddress\n verificationId: $verificationId\n ) {\n id\n name\n verificationId\n verificationType\n challenge {\n salt\n secret\n }\n }\n }\n `),\n {\n userWalletAddress,\n verificationId,\n },\n requestHeaders,\n );\n\n if (!verificationChallenge.createWalletVerificationChallenge) {\n throw new WalletVerificationChallengeError(\"No verification challenge received\", \"NO_CHALLENGES\");\n }\n\n if (verificationType === \"OTP\") {\n return {\n challengeResponse: code.toString(),\n challengeId: verificationChallenge.createWalletVerificationChallenge.id,\n };\n }\n\n if (verificationType === \"SECRET_CODES\") {\n // Add - separator to the code\n const formattedCode = code.toString().replace(/(.{5})(?=.)/, \"$1-\");\n return {\n challengeResponse: formattedCode,\n challengeId: verificationChallenge.createWalletVerificationChallenge.id,\n };\n }\n\n const { secret, salt } = verificationChallenge.createWalletVerificationChallenge.challenge ?? {};\n\n if (!secret || !salt) {\n throw new WalletVerificationChallengeError(\"Invalid challenge format\", \"INVALID_CHALLENGE\");\n }\n\n const challengeResponse = generateResponse(code.toString(), salt, secret);\n return {\n challengeResponse,\n challengeId: verificationChallenge.createWalletVerificationChallenge.id,\n };\n } catch (error) {\n if (error instanceof WalletVerificationChallengeError) {\n throw error;\n }\n throw new WalletVerificationChallengeError(\n \"Failed to process wallet verification challenge\",\n \"CHALLENGE_PROCESSING_ERROR\",\n );\n }\n}\n","import { appendHeaders } from \"@settlemint/sdk-utils/http\";\nimport { ensureServer } from \"@settlemint/sdk-utils/runtime\";\nimport { ApplicationAccessTokenSchema, UrlOrPathSchema, validate } from \"@settlemint/sdk-utils/validation\";\nimport { type AbstractSetupSchema, initGraphQLTada } from \"gql.tada\";\nimport { GraphQLClient } from \"graphql-request\";\nimport { z } from \"zod\";\n\n/**\n * Configuration options for the GraphQL client, excluding 'url' and 'exchanges'.\n */\nexport type RequestConfig = ConstructorParameters<typeof GraphQLClient>[1];\n\n/**\n * Schema for validating Portal client configuration options.\n */\nexport const ClientOptionsSchema = z.object({\n instance: UrlOrPathSchema,\n accessToken: ApplicationAccessTokenSchema.optional(),\n cache: z.enum([\"default\", \"force-cache\", \"no-cache\", \"no-store\", \"only-if-cached\", \"reload\"]).optional(),\n});\n\n/**\n * Type representing the validated client options.\n */\nexport type ClientOptions = z.infer<typeof ClientOptionsSchema>;\n\n/**\n * Creates a Portal GraphQL client with the provided configuration.\n *\n * @param options - Configuration options for the Portal client\n * @param clientOptions - Additional GraphQL client configuration options\n * @returns An object containing the configured GraphQL client and graphql helper function\n * @throws If the provided options fail validation\n *\n * @example\n * import { createPortalClient } from \"@settlemint/sdk-portal\";\n * import { loadEnv } from \"@settlemint/sdk-utils/environment\";\n * import { createLogger, requestLogger } from \"@settlemint/sdk-utils/logging\";\n * import type { introspection } from \"@schemas/portal-env\";\n *\n * const env = await loadEnv(false, false);\n * const logger = createLogger();\n *\n * const { client: portalClient, graphql: portalGraphql } = createPortalClient<{\n * introspection: introspection;\n * disableMasking: true;\n * scalars: {\n * // Change unknown to the type you are using to store metadata\n * JSON: unknown;\n * };\n * }>(\n * {\n * instance: env.SETTLEMINT_PORTAL_GRAPHQL_ENDPOINT!,\n * accessToken: env.SETTLEMINT_ACCESS_TOKEN!,\n * },\n * {\n * fetch: requestLogger(logger, \"portal\", fetch) as typeof fetch,\n * },\n * );\n *\n * // Making GraphQL queries\n * const query = portalGraphql(`\n * query GetPendingTransactions {\n * getPendingTransactions {\n * count\n * }\n * }\n * `);\n *\n * const result = await portalClient.request(query);\n */\nexport function createPortalClient<const Setup extends AbstractSetupSchema>(\n options: ClientOptions,\n clientOptions?: RequestConfig,\n): {\n client: GraphQLClient;\n graphql: initGraphQLTada<Setup>;\n} {\n ensureServer();\n const validatedOptions = validate(ClientOptionsSchema, options);\n const graphql = initGraphQLTada<Setup>();\n const fullUrl = new URL(validatedOptions.instance).toString();\n\n return {\n client: new GraphQLClient(fullUrl, {\n ...clientOptions,\n headers: appendHeaders(clientOptions?.headers, { \"x-auth-token\": validatedOptions.accessToken }),\n }),\n graphql,\n };\n}\n\nexport type { FragmentOf, ResultOf, VariablesOf } from \"gql.tada\";\nexport { readFragment } from \"gql.tada\";\nexport {\n type Transaction,\n type TransactionEvent,\n type TransactionReceipt,\n type WaitForTransactionReceiptOptions,\n waitForTransactionReceipt,\n} from \"./utils/wait-for-transaction-receipt.js\";\nexport {\n type HandleWalletVerificationChallengeOptions,\n handleWalletVerificationChallenge,\n WalletVerificationChallengeError,\n type WalletVerificationType,\n} from \"./utils/wallet-verification-challenge.js\";\nexport { getWebsocketClient, type WebsocketClientOptions } from \"./utils/websocket-client.js\";\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"portal.js","names":["url: URL","transactionHash: string","options: WaitForTransactionReceiptOptions","timeout: number","subscription: AsyncIterableIterator<FormattedExecutionResult<GetTransactionResponse, unknown>>","message: string","code: string","pincode: string","salt: string","challenge: string","options: ClientOptions","clientOptions?: RequestConfig"],"sources":["../src/utils/websocket-client.ts","../src/utils/wait-for-transaction-receipt.ts","../src/utils/wallet-verification-challenge.ts","../src/portal.ts"],"sourcesContent":["import { createClient } from \"graphql-ws\";\n\n/**\n * Options for the GraphQL WebSocket client\n */\nexport interface WebsocketClientOptions {\n /**\n * The GraphQL endpoint URL for the Portal API\n */\n portalGraphqlEndpoint: string;\n /**\n * The access token for authentication with the Portal API\n */\n accessToken?: string;\n}\n\n/**\n * Creates a GraphQL WebSocket client for the Portal API\n *\n * @param {WebsocketClientOptions} options - The options for the client\n * @returns {Client} The GraphQL WebSocket client\n * @example\n * import { getWebsocketClient } from \"@settlemint/sdk-portal\";\n *\n * const client = getWebsocketClient({\n * portalGraphqlEndpoint: \"https://portal.settlemint.com/graphql\",\n * accessToken: \"your-access-token\",\n * });\n */\nexport function getWebsocketClient({ portalGraphqlEndpoint, accessToken }: WebsocketClientOptions) {\n if (!portalGraphqlEndpoint) {\n throw new Error(\"portalGraphqlEndpoint is required\");\n }\n const graphqlEndpoint = setWsProtocol(new URL(portalGraphqlEndpoint));\n return createClient({\n url: accessToken\n ? `${graphqlEndpoint.protocol}//${graphqlEndpoint.host}/${accessToken}${graphqlEndpoint.pathname}${graphqlEndpoint.search}`\n : graphqlEndpoint.toString(),\n });\n}\n\nfunction setWsProtocol(url: URL) {\n if (url.protocol === \"ws:\" || url.protocol === \"wss:\") {\n return url;\n }\n if (url.protocol === \"http:\") {\n url.protocol = \"ws:\";\n } else {\n url.protocol = \"wss:\";\n }\n return url;\n}\n","import type { FormattedExecutionResult } from \"graphql-ws\";\nimport type { Address, Hex, TransactionReceipt as TransactionReceiptViem } from \"viem\";\nimport { type WebsocketClientOptions, getWebsocketClient } from \"./websocket-client.js\";\n\n/**\n * Represents an event emitted during a transaction execution\n */\nexport interface TransactionEvent {\n /** The name of the event that was emitted */\n eventName: string;\n /** The arguments emitted by the event */\n args: Record<string, unknown>;\n /** Indexed event parameters used for filtering and searching */\n topics: Hex[];\n}\n\n/**\n * Represents the structure of a blockchain transaction receipt\n */\nexport interface TransactionReceipt extends TransactionReceiptViem<string, number, \"Success\" | \"Reverted\"> {\n /** The raw reason for transaction reversion, if applicable */\n revertReason: string;\n /** Human-readable version of the revert reason */\n revertReasonDecoded: string;\n /** Array of events emitted during the transaction */\n events: TransactionEvent[];\n /** The address of the contract deployed in the transaction */\n contractAddress: Address;\n}\n\n/**\n * Represents the structure of a blockchain transaction with its receipt\n */\nexport interface Transaction {\n receipt: TransactionReceipt;\n /** The hash of the transaction (duplicate of receipt.transactionHash) */\n transactionHash: string;\n /** The sender address (duplicate of receipt.from) */\n from: string;\n /** Timestamp when the transaction was created */\n createdAt: string;\n /** The contract address involved in the transaction */\n address: string;\n /** The name of the function called in the transaction */\n functionName: string;\n /** Whether the transaction is a contract deployment */\n isContract: boolean;\n}\n\ninterface GetTransactionResponse {\n getTransaction: Transaction;\n}\n\n/**\n * Options for waiting for a transaction receipt\n */\nexport interface WaitForTransactionReceiptOptions extends WebsocketClientOptions {\n /** Optional timeout in milliseconds before the operation fails */\n timeout?: number;\n}\n\n/**\n * Waits for a blockchain transaction receipt by subscribing to transaction updates via GraphQL.\n * This function polls until the transaction is confirmed or the timeout is reached.\n *\n * @param transactionHash - The hash of the transaction to wait for\n * @param options - Configuration options for the waiting process\n * @returns The transaction details including receipt information when the transaction is confirmed\n * @throws Error if the transaction receipt cannot be retrieved within the specified timeout\n *\n * @example\n * import { waitForTransactionReceipt } from \"@settlemint/sdk-portal\";\n *\n * const transaction = await waitForTransactionReceipt(\"0x123...\", {\n * portalGraphqlEndpoint: \"https://example.settlemint.com/graphql\",\n * accessToken: \"your-access-token\",\n * timeout: 30000 // 30 seconds timeout\n * });\n */\nexport async function waitForTransactionReceipt(transactionHash: string, options: WaitForTransactionReceiptOptions) {\n const wsClient = getWebsocketClient(options);\n const subscription = wsClient.iterate<GetTransactionResponse>({\n query: `subscription getTransaction($transactionHash: String!) {\n getTransaction(transactionHash: $transactionHash) {\n receipt {\n transactionHash\n to\n status\n from\n type\n revertReason\n revertReasonDecoded\n logs\n events\n contractAddress\n }\n transactionHash\n from\n createdAt\n address\n functionName\n isContract\n }\n }`,\n variables: { transactionHash },\n });\n const promises = [getTransactionFromSubscription(subscription)];\n if (options.timeout) {\n promises.push(createTimeoutPromise(options.timeout));\n }\n\n return Promise.race(promises);\n}\n\nfunction createTimeoutPromise(timeout: number): Promise<never> {\n return new Promise((_, reject) => {\n setTimeout(() => reject(new Error(\"Transaction receipt not found\")), timeout);\n });\n}\n\nasync function getTransactionFromSubscription(\n subscription: AsyncIterableIterator<FormattedExecutionResult<GetTransactionResponse, unknown>>,\n): Promise<Transaction> {\n for await (const result of subscription) {\n if (result?.data?.getTransaction?.receipt) {\n return result.data.getTransaction;\n }\n }\n throw new Error(\"No transaction found\");\n}\n","import { createHash } from \"node:crypto\";\nimport type { AbstractSetupSchema, initGraphQLTada } from \"gql.tada\";\nimport type { GraphQLClient } from \"graphql-request\";\nimport type { Address } from \"viem\";\n\n/**\n * Type representing the different types of wallet verification methods\n */\nexport type WalletVerificationType = \"PINCODE\" | \"OTP\" | \"SECRET_CODES\";\n\n/**\n * Custom error class for challenge-related errors\n */\nexport class WalletVerificationChallengeError 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 id: string;\n name: string;\n verificationId: string;\n verificationType: WalletVerificationType;\n challenge?: {\n salt: string;\n secret: string;\n };\n}\n\n/**\n * Response type for the CreateWalletVerificationChallenge mutation\n */\ninterface CreateWalletVerificationChallengeResponse {\n createWalletVerificationChallenge: 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: WalletVerificationType;\n /** Request id which can be added for tracing purposes */\n requestId?: string;\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 {WalletVerificationChallengeError} 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 requestId,\n}: HandleWalletVerificationChallengeOptions<Setup>): Promise<{\n challengeResponse: string;\n challengeId: string;\n}> {\n try {\n const requestHeaders = new Headers();\n if (requestId) {\n requestHeaders.append(\"x-request-id\", requestId);\n }\n const verificationChallenge = await portalClient.request<CreateWalletVerificationChallengeResponse>(\n portalGraphql(`\n mutation CreateWalletVerificationChallenge($userWalletAddress: String!, $verificationId: String!) {\n createWalletVerificationChallenge(\n userWalletAddress: $userWalletAddress\n verificationId: $verificationId\n ) {\n id\n name\n verificationId\n verificationType\n challenge {\n salt\n secret\n }\n }\n }\n `),\n {\n userWalletAddress,\n verificationId,\n },\n requestHeaders,\n );\n\n if (!verificationChallenge.createWalletVerificationChallenge) {\n throw new WalletVerificationChallengeError(\"No verification challenge received\", \"NO_CHALLENGES\");\n }\n\n if (verificationType === \"OTP\") {\n return {\n challengeResponse: code.toString(),\n challengeId: verificationChallenge.createWalletVerificationChallenge.id,\n };\n }\n\n if (verificationType === \"SECRET_CODES\") {\n // Add a hyphen after every 5 characters to format the secret code\n const formattedCode = code.toString().replace(/(.{5})(?=.)/, \"$1-\");\n return {\n challengeResponse: formattedCode,\n challengeId: verificationChallenge.createWalletVerificationChallenge.id,\n };\n }\n\n const { secret, salt } = verificationChallenge.createWalletVerificationChallenge.challenge ?? {};\n\n if (!secret || !salt) {\n throw new WalletVerificationChallengeError(\"Invalid challenge format\", \"INVALID_CHALLENGE\");\n }\n\n const challengeResponse = generateResponse(code.toString(), salt, secret);\n return {\n challengeResponse,\n challengeId: verificationChallenge.createWalletVerificationChallenge.id,\n };\n } catch (error) {\n if (error instanceof WalletVerificationChallengeError) {\n throw error;\n }\n throw new WalletVerificationChallengeError(\n \"Failed to process wallet verification challenge\",\n \"CHALLENGE_PROCESSING_ERROR\",\n );\n }\n}\n","import { appendHeaders } from \"@settlemint/sdk-utils/http\";\nimport { ensureServer } from \"@settlemint/sdk-utils/runtime\";\nimport { ApplicationAccessTokenSchema, UrlOrPathSchema, validate } from \"@settlemint/sdk-utils/validation\";\nimport { type AbstractSetupSchema, initGraphQLTada } from \"gql.tada\";\nimport { GraphQLClient } from \"graphql-request\";\nimport { z } from \"zod\";\n\n/**\n * Configuration options for the GraphQL client, excluding 'url' and 'exchanges'.\n */\nexport type RequestConfig = ConstructorParameters<typeof GraphQLClient>[1];\n\n/**\n * Schema for validating Portal client configuration options.\n */\nexport const ClientOptionsSchema = z.object({\n instance: UrlOrPathSchema,\n accessToken: ApplicationAccessTokenSchema.optional(),\n cache: z.enum([\"default\", \"force-cache\", \"no-cache\", \"no-store\", \"only-if-cached\", \"reload\"]).optional(),\n});\n\n/**\n * Type representing the validated client options.\n */\nexport type ClientOptions = z.infer<typeof ClientOptionsSchema>;\n\n/**\n * Creates a Portal GraphQL client with the provided configuration.\n *\n * @param options - Configuration options for the Portal client\n * @param clientOptions - Additional GraphQL client configuration options\n * @returns An object containing the configured GraphQL client and graphql helper function\n * @throws If the provided options fail validation\n *\n * @example\n * import { createPortalClient } from \"@settlemint/sdk-portal\";\n * import { loadEnv } from \"@settlemint/sdk-utils/environment\";\n * import { createLogger, requestLogger } from \"@settlemint/sdk-utils/logging\";\n * import type { introspection } from \"@schemas/portal-env\";\n *\n * const env = await loadEnv(false, false);\n * const logger = createLogger();\n *\n * const { client: portalClient, graphql: portalGraphql } = createPortalClient<{\n * introspection: introspection;\n * disableMasking: true;\n * scalars: {\n * // Change unknown to the type you are using to store metadata\n * JSON: unknown;\n * };\n * }>(\n * {\n * instance: env.SETTLEMINT_PORTAL_GRAPHQL_ENDPOINT!,\n * accessToken: env.SETTLEMINT_ACCESS_TOKEN!,\n * },\n * {\n * fetch: requestLogger(logger, \"portal\", fetch) as typeof fetch,\n * },\n * );\n *\n * // Making GraphQL queries\n * const query = portalGraphql(`\n * query GetPendingTransactions {\n * getPendingTransactions {\n * count\n * }\n * }\n * `);\n *\n * const result = await portalClient.request(query);\n */\nexport function createPortalClient<const Setup extends AbstractSetupSchema>(\n options: ClientOptions,\n clientOptions?: RequestConfig,\n): {\n client: GraphQLClient;\n graphql: initGraphQLTada<Setup>;\n} {\n ensureServer();\n const validatedOptions = validate(ClientOptionsSchema, options);\n const graphql = initGraphQLTada<Setup>();\n const fullUrl = new URL(validatedOptions.instance).toString();\n\n return {\n client: new GraphQLClient(fullUrl, {\n ...clientOptions,\n headers: appendHeaders(clientOptions?.headers, { \"x-auth-token\": validatedOptions.accessToken }),\n }),\n graphql,\n };\n}\n\nexport type { FragmentOf, ResultOf, VariablesOf } from \"gql.tada\";\nexport { readFragment } from \"gql.tada\";\nexport {\n type Transaction,\n type TransactionEvent,\n type TransactionReceipt,\n type WaitForTransactionReceiptOptions,\n waitForTransactionReceipt,\n} from \"./utils/wait-for-transaction-receipt.js\";\nexport {\n type HandleWalletVerificationChallengeOptions,\n handleWalletVerificationChallenge,\n WalletVerificationChallengeError,\n type WalletVerificationType,\n} from \"./utils/wallet-verification-challenge.js\";\nexport { getWebsocketClient, type WebsocketClientOptions } from \"./utils/websocket-client.js\";\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@settlemint/sdk-portal",
|
|
3
3
|
"description": "Portal API client module for SettleMint SDK, providing access to smart contract portal services and APIs",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.6.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"private": false,
|
|
7
7
|
"license": "FSL-1.1-MIT",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"dependencies": {
|
|
60
60
|
"gql.tada": "^1",
|
|
61
61
|
"graphql-ws": "^6",
|
|
62
|
-
"@settlemint/sdk-utils": "2.
|
|
62
|
+
"@settlemint/sdk-utils": "2.6.0",
|
|
63
63
|
"graphql-request": "^7",
|
|
64
64
|
"zod": "^4"
|
|
65
65
|
},
|