@t402/polkadot 2.3.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.
Files changed (40) hide show
  1. package/README.md +139 -0
  2. package/dist/exact-direct/client/index.cjs +189 -0
  3. package/dist/exact-direct/client/index.cjs.map +1 -0
  4. package/dist/exact-direct/client/index.d.cts +39 -0
  5. package/dist/exact-direct/client/index.d.ts +39 -0
  6. package/dist/exact-direct/client/index.mjs +161 -0
  7. package/dist/exact-direct/client/index.mjs.map +1 -0
  8. package/dist/exact-direct/facilitator/index.cjs +394 -0
  9. package/dist/exact-direct/facilitator/index.cjs.map +1 -0
  10. package/dist/exact-direct/facilitator/index.d.cts +55 -0
  11. package/dist/exact-direct/facilitator/index.d.ts +55 -0
  12. package/dist/exact-direct/facilitator/index.mjs +366 -0
  13. package/dist/exact-direct/facilitator/index.mjs.map +1 -0
  14. package/dist/exact-direct/server/index.cjs +277 -0
  15. package/dist/exact-direct/server/index.cjs.map +1 -0
  16. package/dist/exact-direct/server/index.d.cts +109 -0
  17. package/dist/exact-direct/server/index.d.ts +109 -0
  18. package/dist/exact-direct/server/index.mjs +248 -0
  19. package/dist/exact-direct/server/index.mjs.map +1 -0
  20. package/dist/index.cjs +293 -0
  21. package/dist/index.cjs.map +1 -0
  22. package/dist/index.d.cts +148 -0
  23. package/dist/index.d.ts +148 -0
  24. package/dist/index.mjs +235 -0
  25. package/dist/index.mjs.map +1 -0
  26. package/dist/types-Dbjfcz2Y.d.cts +135 -0
  27. package/dist/types-Dbjfcz2Y.d.ts +135 -0
  28. package/package.json +103 -0
  29. package/src/constants.ts +87 -0
  30. package/src/exact-direct/client/index.ts +5 -0
  31. package/src/exact-direct/client/scheme.ts +117 -0
  32. package/src/exact-direct/facilitator/index.ts +4 -0
  33. package/src/exact-direct/facilitator/scheme.ts +315 -0
  34. package/src/exact-direct/server/index.ts +9 -0
  35. package/src/exact-direct/server/register.ts +57 -0
  36. package/src/exact-direct/server/scheme.ts +216 -0
  37. package/src/index.ts +84 -0
  38. package/src/tokens.ts +111 -0
  39. package/src/types.ts +151 -0
  40. package/src/utils.ts +176 -0
@@ -0,0 +1,135 @@
1
+ import { Network } from '@t402/core/types';
2
+
3
+ /**
4
+ * Polkadot Asset Hub T402 Types
5
+ */
6
+
7
+ /**
8
+ * Payment payload for exact-direct scheme on Polkadot
9
+ */
10
+ type ExactDirectPolkadotPayload = {
11
+ /** Extrinsic hash (block hash + extrinsic index) */
12
+ extrinsicHash: string;
13
+ /** Block hash containing the extrinsic */
14
+ blockHash: string;
15
+ /** Extrinsic index within the block */
16
+ extrinsicIndex: number;
17
+ /** Sender address (SS58 format) */
18
+ from: string;
19
+ /** Recipient address (SS58 format) */
20
+ to: string;
21
+ /** Amount in smallest unit (with decimals) */
22
+ amount: string;
23
+ /** Asset ID */
24
+ assetId: number;
25
+ };
26
+ /**
27
+ * Result of a Polkadot extrinsic query
28
+ */
29
+ interface PolkadotExtrinsicResult {
30
+ /** Extrinsic hash */
31
+ extrinsicHash: string;
32
+ /** Block hash */
33
+ blockHash: string;
34
+ /** Block number */
35
+ blockNumber: number;
36
+ /** Extrinsic index */
37
+ extrinsicIndex: number;
38
+ /** Timestamp (ISO 8601) */
39
+ timestamp: string;
40
+ /** Signer address */
41
+ signer: string;
42
+ /** Success status */
43
+ success: boolean;
44
+ /** Module name (e.g., "assets") */
45
+ module: string;
46
+ /** Call name (e.g., "transfer") */
47
+ call: string;
48
+ /** Call arguments */
49
+ args: Record<string, unknown>;
50
+ /** Events emitted by the extrinsic */
51
+ events: PolkadotEvent[];
52
+ }
53
+ /**
54
+ * Polkadot event structure
55
+ */
56
+ interface PolkadotEvent {
57
+ /** Module name */
58
+ module: string;
59
+ /** Event name */
60
+ name: string;
61
+ /** Event data */
62
+ data: Record<string, unknown>;
63
+ }
64
+ /**
65
+ * Parsed asset transfer from extrinsic
66
+ */
67
+ interface ParsedAssetTransfer {
68
+ /** Asset ID */
69
+ assetId: number;
70
+ /** Sender address */
71
+ from: string;
72
+ /** Recipient address */
73
+ to: string;
74
+ /** Amount transferred */
75
+ amount: string;
76
+ /** Whether the transfer was successful */
77
+ success: boolean;
78
+ }
79
+ /**
80
+ * Signer interface for Polkadot facilitator
81
+ */
82
+ interface FacilitatorPolkadotSigner {
83
+ /**
84
+ * Get the facilitator's addresses for a network
85
+ */
86
+ getAddresses(network: Network): string[];
87
+ /**
88
+ * Query an extrinsic by hash
89
+ */
90
+ queryExtrinsic(extrinsicHash: string, blockHash?: string, extrinsicIndex?: number): Promise<PolkadotExtrinsicResult | null>;
91
+ /**
92
+ * Get balance of an asset for an address
93
+ */
94
+ getBalance(assetId: number, address: string): Promise<string>;
95
+ }
96
+ /**
97
+ * Client signer interface for signing transactions
98
+ */
99
+ interface ClientPolkadotSigner {
100
+ /**
101
+ * Get the signer's address
102
+ */
103
+ getAddress(): Promise<string>;
104
+ /**
105
+ * Sign and submit an asset transfer
106
+ * Returns the extrinsic hash, block hash, and extrinsic index
107
+ */
108
+ transferAsset(assetId: number, to: string, amount: string): Promise<{
109
+ extrinsicHash: string;
110
+ blockHash: string;
111
+ extrinsicIndex: number;
112
+ }>;
113
+ }
114
+ /**
115
+ * Configuration for Polkadot server
116
+ */
117
+ interface PolkadotServerConfig {
118
+ /** Custom RPC URL */
119
+ rpcUrl?: string;
120
+ /** Custom indexer URL */
121
+ indexerUrl?: string;
122
+ /** Facilitator addresses per network */
123
+ facilitatorAddresses?: Record<string, string>;
124
+ }
125
+ /**
126
+ * Configuration for Polkadot facilitator
127
+ */
128
+ interface PolkadotFacilitatorConfig {
129
+ /** Maximum age of extrinsic to accept (in seconds) */
130
+ maxExtrinsicAge?: number;
131
+ /** Duration to cache used extrinsic hashes */
132
+ usedExtrinsicCacheDuration?: number;
133
+ }
134
+
135
+ export type { ClientPolkadotSigner as C, ExactDirectPolkadotPayload as E, FacilitatorPolkadotSigner as F, PolkadotExtrinsicResult as P, ParsedAssetTransfer as a, PolkadotEvent as b, PolkadotServerConfig as c, PolkadotFacilitatorConfig as d };
@@ -0,0 +1,135 @@
1
+ import { Network } from '@t402/core/types';
2
+
3
+ /**
4
+ * Polkadot Asset Hub T402 Types
5
+ */
6
+
7
+ /**
8
+ * Payment payload for exact-direct scheme on Polkadot
9
+ */
10
+ type ExactDirectPolkadotPayload = {
11
+ /** Extrinsic hash (block hash + extrinsic index) */
12
+ extrinsicHash: string;
13
+ /** Block hash containing the extrinsic */
14
+ blockHash: string;
15
+ /** Extrinsic index within the block */
16
+ extrinsicIndex: number;
17
+ /** Sender address (SS58 format) */
18
+ from: string;
19
+ /** Recipient address (SS58 format) */
20
+ to: string;
21
+ /** Amount in smallest unit (with decimals) */
22
+ amount: string;
23
+ /** Asset ID */
24
+ assetId: number;
25
+ };
26
+ /**
27
+ * Result of a Polkadot extrinsic query
28
+ */
29
+ interface PolkadotExtrinsicResult {
30
+ /** Extrinsic hash */
31
+ extrinsicHash: string;
32
+ /** Block hash */
33
+ blockHash: string;
34
+ /** Block number */
35
+ blockNumber: number;
36
+ /** Extrinsic index */
37
+ extrinsicIndex: number;
38
+ /** Timestamp (ISO 8601) */
39
+ timestamp: string;
40
+ /** Signer address */
41
+ signer: string;
42
+ /** Success status */
43
+ success: boolean;
44
+ /** Module name (e.g., "assets") */
45
+ module: string;
46
+ /** Call name (e.g., "transfer") */
47
+ call: string;
48
+ /** Call arguments */
49
+ args: Record<string, unknown>;
50
+ /** Events emitted by the extrinsic */
51
+ events: PolkadotEvent[];
52
+ }
53
+ /**
54
+ * Polkadot event structure
55
+ */
56
+ interface PolkadotEvent {
57
+ /** Module name */
58
+ module: string;
59
+ /** Event name */
60
+ name: string;
61
+ /** Event data */
62
+ data: Record<string, unknown>;
63
+ }
64
+ /**
65
+ * Parsed asset transfer from extrinsic
66
+ */
67
+ interface ParsedAssetTransfer {
68
+ /** Asset ID */
69
+ assetId: number;
70
+ /** Sender address */
71
+ from: string;
72
+ /** Recipient address */
73
+ to: string;
74
+ /** Amount transferred */
75
+ amount: string;
76
+ /** Whether the transfer was successful */
77
+ success: boolean;
78
+ }
79
+ /**
80
+ * Signer interface for Polkadot facilitator
81
+ */
82
+ interface FacilitatorPolkadotSigner {
83
+ /**
84
+ * Get the facilitator's addresses for a network
85
+ */
86
+ getAddresses(network: Network): string[];
87
+ /**
88
+ * Query an extrinsic by hash
89
+ */
90
+ queryExtrinsic(extrinsicHash: string, blockHash?: string, extrinsicIndex?: number): Promise<PolkadotExtrinsicResult | null>;
91
+ /**
92
+ * Get balance of an asset for an address
93
+ */
94
+ getBalance(assetId: number, address: string): Promise<string>;
95
+ }
96
+ /**
97
+ * Client signer interface for signing transactions
98
+ */
99
+ interface ClientPolkadotSigner {
100
+ /**
101
+ * Get the signer's address
102
+ */
103
+ getAddress(): Promise<string>;
104
+ /**
105
+ * Sign and submit an asset transfer
106
+ * Returns the extrinsic hash, block hash, and extrinsic index
107
+ */
108
+ transferAsset(assetId: number, to: string, amount: string): Promise<{
109
+ extrinsicHash: string;
110
+ blockHash: string;
111
+ extrinsicIndex: number;
112
+ }>;
113
+ }
114
+ /**
115
+ * Configuration for Polkadot server
116
+ */
117
+ interface PolkadotServerConfig {
118
+ /** Custom RPC URL */
119
+ rpcUrl?: string;
120
+ /** Custom indexer URL */
121
+ indexerUrl?: string;
122
+ /** Facilitator addresses per network */
123
+ facilitatorAddresses?: Record<string, string>;
124
+ }
125
+ /**
126
+ * Configuration for Polkadot facilitator
127
+ */
128
+ interface PolkadotFacilitatorConfig {
129
+ /** Maximum age of extrinsic to accept (in seconds) */
130
+ maxExtrinsicAge?: number;
131
+ /** Duration to cache used extrinsic hashes */
132
+ usedExtrinsicCacheDuration?: number;
133
+ }
134
+
135
+ export type { ClientPolkadotSigner as C, ExactDirectPolkadotPayload as E, FacilitatorPolkadotSigner as F, PolkadotExtrinsicResult as P, ParsedAssetTransfer as a, PolkadotEvent as b, PolkadotServerConfig as c, PolkadotFacilitatorConfig as d };
package/package.json ADDED
@@ -0,0 +1,103 @@
1
+ {
2
+ "name": "@t402/polkadot",
3
+ "version": "2.3.0",
4
+ "description": "T402 Polkadot Asset Hub mechanism - USDT payments on Polkadot",
5
+ "type": "module",
6
+ "main": "./dist/cjs/index.cjs",
7
+ "module": "./dist/esm/index.mjs",
8
+ "types": "./dist/esm/index.d.mts",
9
+ "exports": {
10
+ ".": {
11
+ "import": {
12
+ "types": "./dist/esm/index.d.mts",
13
+ "default": "./dist/esm/index.mjs"
14
+ },
15
+ "require": {
16
+ "types": "./dist/cjs/index.d.cts",
17
+ "default": "./dist/cjs/index.cjs"
18
+ }
19
+ },
20
+ "./exact-direct/client": {
21
+ "import": {
22
+ "types": "./dist/esm/exact-direct/client/index.d.mts",
23
+ "default": "./dist/esm/exact-direct/client/index.mjs"
24
+ },
25
+ "require": {
26
+ "types": "./dist/cjs/exact-direct/client/index.d.cts",
27
+ "default": "./dist/cjs/exact-direct/client/index.cjs"
28
+ }
29
+ },
30
+ "./exact-direct/server": {
31
+ "import": {
32
+ "types": "./dist/esm/exact-direct/server/index.d.mts",
33
+ "default": "./dist/esm/exact-direct/server/index.mjs"
34
+ },
35
+ "require": {
36
+ "types": "./dist/cjs/exact-direct/server/index.d.cts",
37
+ "default": "./dist/cjs/exact-direct/server/index.cjs"
38
+ }
39
+ },
40
+ "./exact-direct/facilitator": {
41
+ "import": {
42
+ "types": "./dist/esm/exact-direct/facilitator/index.d.mts",
43
+ "default": "./dist/esm/exact-direct/facilitator/index.mjs"
44
+ },
45
+ "require": {
46
+ "types": "./dist/cjs/exact-direct/facilitator/index.d.cts",
47
+ "default": "./dist/cjs/exact-direct/facilitator/index.cjs"
48
+ }
49
+ }
50
+ },
51
+ "files": [
52
+ "dist",
53
+ "src"
54
+ ],
55
+ "dependencies": {
56
+ "@t402/core": "2.3.0"
57
+ },
58
+ "peerDependencies": {
59
+ "@polkadot/api": ">=12.0.0"
60
+ },
61
+ "peerDependenciesMeta": {
62
+ "@polkadot/api": {
63
+ "optional": true
64
+ }
65
+ },
66
+ "devDependencies": {
67
+ "@polkadot/api": "^14.0.0",
68
+ "@types/node": "^22.0.0",
69
+ "@vitest/coverage-v8": "^3.2.4",
70
+ "tsup": "^8.3.5",
71
+ "typescript": "^5.7.2",
72
+ "vitest": "^3.2.4"
73
+ },
74
+ "keywords": [
75
+ "t402",
76
+ "polkadot",
77
+ "asset-hub",
78
+ "usdt",
79
+ "payments",
80
+ "cryptocurrency",
81
+ "web3"
82
+ ],
83
+ "author": "T402 Team",
84
+ "license": "MIT",
85
+ "repository": {
86
+ "type": "git",
87
+ "url": "https://github.com/t402-io/t402.git",
88
+ "directory": "typescript/packages/mechanisms/polkadot"
89
+ },
90
+ "bugs": {
91
+ "url": "https://github.com/t402-io/t402/issues"
92
+ },
93
+ "homepage": "https://t402.io",
94
+ "scripts": {
95
+ "build": "tsup",
96
+ "dev": "tsup --watch",
97
+ "test": "vitest run",
98
+ "test:watch": "vitest",
99
+ "test:coverage": "vitest run --coverage",
100
+ "typecheck": "tsc --noEmit",
101
+ "clean": "rm -rf dist"
102
+ }
103
+ }
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Polkadot Asset Hub T402 Constants
3
+ *
4
+ * Polkadot Asset Hub (formerly Statemint) is a common-good parachain
5
+ * that hosts assets like USDT on the Polkadot network.
6
+ */
7
+
8
+ // CAIP-2 namespace for Polkadot
9
+ export const POLKADOT_CAIP2_NAMESPACE = "polkadot";
10
+
11
+ // CAIP-2 network identifiers (first 32 chars of genesis hash)
12
+ // Polkadot Asset Hub (Parachain ID: 1000)
13
+ export const POLKADOT_ASSET_HUB_CAIP2 = "polkadot:68d56f15f85d3136970ec16946040bc1";
14
+
15
+ // Kusama Asset Hub (Parachain ID: 1000 on Kusama)
16
+ export const KUSAMA_ASSET_HUB_CAIP2 = "polkadot:48239ef607d7928874027a43a67689209727dfb3d3dc5e5b03a39bdc2eda771a";
17
+
18
+ // Westend Asset Hub (Testnet)
19
+ export const WESTEND_ASSET_HUB_CAIP2 = "polkadot:e143f23803ac50e8f6f8e62695d1ce9e";
20
+
21
+ // Scheme identifier
22
+ export const SCHEME_EXACT_DIRECT = "exact-direct";
23
+
24
+ // Default indexers (Subscan API)
25
+ export const DEFAULT_POLKADOT_INDEXER = "https://assethub-polkadot.api.subscan.io";
26
+ export const DEFAULT_KUSAMA_INDEXER = "https://assethub-kusama.api.subscan.io";
27
+ export const DEFAULT_WESTEND_INDEXER = "https://assethub-westend.api.subscan.io";
28
+
29
+ // Default RPC endpoints
30
+ export const DEFAULT_POLKADOT_RPC = "wss://polkadot-asset-hub-rpc.polkadot.io";
31
+ export const DEFAULT_KUSAMA_RPC = "wss://kusama-asset-hub-rpc.polkadot.io";
32
+ export const DEFAULT_WESTEND_RPC = "wss://westend-asset-hub-rpc.polkadot.io";
33
+
34
+ // Network configurations
35
+ export interface PolkadotNetworkConfig {
36
+ readonly name: string;
37
+ readonly caip2: string;
38
+ readonly rpcUrl: string;
39
+ readonly indexerUrl: string;
40
+ readonly genesisHash: string;
41
+ readonly ss58Prefix: number;
42
+ readonly isTestnet: boolean;
43
+ }
44
+
45
+ export const POLKADOT_NETWORKS: Record<string, PolkadotNetworkConfig> = {
46
+ [POLKADOT_ASSET_HUB_CAIP2]: {
47
+ name: "Polkadot Asset Hub",
48
+ caip2: POLKADOT_ASSET_HUB_CAIP2,
49
+ rpcUrl: DEFAULT_POLKADOT_RPC,
50
+ indexerUrl: DEFAULT_POLKADOT_INDEXER,
51
+ genesisHash: "0x68d56f15f85d3136970ec16946040bc1752654e906147f7e43e9d539d7c3de2f",
52
+ ss58Prefix: 0, // Polkadot
53
+ isTestnet: false,
54
+ },
55
+ [KUSAMA_ASSET_HUB_CAIP2]: {
56
+ name: "Kusama Asset Hub",
57
+ caip2: KUSAMA_ASSET_HUB_CAIP2,
58
+ rpcUrl: DEFAULT_KUSAMA_RPC,
59
+ indexerUrl: DEFAULT_KUSAMA_INDEXER,
60
+ genesisHash: "0x48239ef607d7928874027a43a67689209727dfb3d3dc5e5b03a39bdc2eda771a",
61
+ ss58Prefix: 2, // Kusama
62
+ isTestnet: false,
63
+ },
64
+ [WESTEND_ASSET_HUB_CAIP2]: {
65
+ name: "Westend Asset Hub",
66
+ caip2: WESTEND_ASSET_HUB_CAIP2,
67
+ rpcUrl: DEFAULT_WESTEND_RPC,
68
+ indexerUrl: DEFAULT_WESTEND_INDEXER,
69
+ genesisHash: "0xe143f23803ac50e8f6f8e62695d1ce9e4e1d68aa36c1cd2cfd15340213f3423e",
70
+ ss58Prefix: 42, // Generic Substrate
71
+ isTestnet: true,
72
+ },
73
+ };
74
+
75
+ /**
76
+ * Get network configuration by CAIP-2 identifier
77
+ */
78
+ export function getNetworkConfig(network: string): PolkadotNetworkConfig | undefined {
79
+ return POLKADOT_NETWORKS[network];
80
+ }
81
+
82
+ /**
83
+ * Check if a network identifier is a Polkadot network
84
+ */
85
+ export function isPolkadotNetwork(network: string): boolean {
86
+ return network.startsWith(`${POLKADOT_CAIP2_NAMESPACE}:`);
87
+ }
@@ -0,0 +1,5 @@
1
+ export {
2
+ ExactDirectPolkadotClient,
3
+ createExactDirectPolkadotClient,
4
+ type ExactDirectPolkadotClientConfig,
5
+ } from "./scheme.js";
@@ -0,0 +1,117 @@
1
+ /**
2
+ * Polkadot Exact-Direct Client Scheme
3
+ *
4
+ * In the exact-direct scheme, the client executes the asset transfer directly
5
+ * and provides the extrinsic hash as proof of payment.
6
+ */
7
+
8
+ import type {
9
+ PaymentPayload,
10
+ PaymentRequirements,
11
+ SchemeNetworkClient,
12
+ } from "@t402/core/types";
13
+ import type { ClientPolkadotSigner, ExactDirectPolkadotPayload } from "../../types.js";
14
+ import { SCHEME_EXACT_DIRECT, POLKADOT_CAIP2_NAMESPACE } from "../../constants.js";
15
+ import { getAssetId } from "../../tokens.js";
16
+ import { isValidAddress } from "../../utils.js";
17
+
18
+ /**
19
+ * Configuration for the exact-direct client
20
+ */
21
+ export interface ExactDirectPolkadotClientConfig {
22
+ /** Signer for executing transactions */
23
+ signer: ClientPolkadotSigner;
24
+ }
25
+
26
+ /**
27
+ * Exact-direct client scheme for Polkadot Asset Hub
28
+ */
29
+ export class ExactDirectPolkadotClient implements SchemeNetworkClient {
30
+ readonly scheme = SCHEME_EXACT_DIRECT;
31
+ private readonly signer: ClientPolkadotSigner;
32
+
33
+ constructor(config: ExactDirectPolkadotClientConfig) {
34
+ this.signer = config.signer;
35
+ }
36
+
37
+ /**
38
+ * Create a payment payload by executing the transfer
39
+ */
40
+ async createPaymentPayload(
41
+ t402Version: number,
42
+ requirements: PaymentRequirements,
43
+ ): Promise<Pick<PaymentPayload, "t402Version" | "payload">> {
44
+ // Validate requirements
45
+ this.validateRequirements(requirements);
46
+
47
+ const { network, amount, payTo, extra } = requirements;
48
+
49
+ // Get asset ID from extra or use default USDT
50
+ const symbol = (extra?.assetSymbol as string) || "USDT";
51
+ const assetId = (extra?.assetId as number) ?? getAssetId(network, symbol);
52
+
53
+ if (assetId === undefined) {
54
+ throw new Error(`Unknown asset ${symbol} on network ${network}`);
55
+ }
56
+
57
+ // Get sender address
58
+ const from = await this.signer.getAddress();
59
+
60
+ // Execute the transfer
61
+ const { extrinsicHash, blockHash, extrinsicIndex } =
62
+ await this.signer.transferAsset(assetId, payTo, amount);
63
+
64
+ // Build the payload
65
+ const polkadotPayload: ExactDirectPolkadotPayload = {
66
+ extrinsicHash,
67
+ blockHash,
68
+ extrinsicIndex,
69
+ from,
70
+ to: payTo,
71
+ amount,
72
+ assetId,
73
+ };
74
+
75
+ return {
76
+ t402Version,
77
+ payload: polkadotPayload,
78
+ };
79
+ }
80
+
81
+ /**
82
+ * Validate payment requirements
83
+ */
84
+ private validateRequirements(requirements: PaymentRequirements): void {
85
+ // Check scheme
86
+ if (requirements.scheme !== SCHEME_EXACT_DIRECT) {
87
+ throw new Error(
88
+ `Invalid scheme: expected ${SCHEME_EXACT_DIRECT}, got ${requirements.scheme}`,
89
+ );
90
+ }
91
+
92
+ // Check network
93
+ if (!requirements.network.startsWith(`${POLKADOT_CAIP2_NAMESPACE}:`)) {
94
+ throw new Error(`Invalid network: ${requirements.network}`);
95
+ }
96
+
97
+ // Check payTo address
98
+ if (!isValidAddress(requirements.payTo)) {
99
+ throw new Error(`Invalid payTo address: ${requirements.payTo}`);
100
+ }
101
+
102
+ // Check amount
103
+ const amount = BigInt(requirements.amount);
104
+ if (amount <= 0n) {
105
+ throw new Error(`Invalid amount: ${requirements.amount}`);
106
+ }
107
+ }
108
+ }
109
+
110
+ /**
111
+ * Create an exact-direct client for Polkadot
112
+ */
113
+ export function createExactDirectPolkadotClient(
114
+ config: ExactDirectPolkadotClientConfig,
115
+ ): ExactDirectPolkadotClient {
116
+ return new ExactDirectPolkadotClient(config);
117
+ }
@@ -0,0 +1,4 @@
1
+ export {
2
+ ExactDirectPolkadotFacilitator,
3
+ createExactDirectPolkadotFacilitator,
4
+ } from "./scheme.js";