@t402/cosmos 2.4.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 (38) hide show
  1. package/README.md +175 -0
  2. package/dist/cjs/exact-direct/client/index.d.ts +50 -0
  3. package/dist/cjs/exact-direct/client/index.js +122 -0
  4. package/dist/cjs/exact-direct/client/index.js.map +1 -0
  5. package/dist/cjs/exact-direct/facilitator/index.d.ts +70 -0
  6. package/dist/cjs/exact-direct/facilitator/index.js +300 -0
  7. package/dist/cjs/exact-direct/facilitator/index.js.map +1 -0
  8. package/dist/cjs/exact-direct/server/index.d.ts +87 -0
  9. package/dist/cjs/exact-direct/server/index.js +241 -0
  10. package/dist/cjs/exact-direct/server/index.js.map +1 -0
  11. package/dist/cjs/index.d.ts +178 -0
  12. package/dist/cjs/index.js +619 -0
  13. package/dist/cjs/index.js.map +1 -0
  14. package/dist/cjs/types-CgseoctH.d.ts +155 -0
  15. package/dist/esm/chunk-2UTEGIZ2.mjs +101 -0
  16. package/dist/esm/chunk-2UTEGIZ2.mjs.map +1 -0
  17. package/dist/esm/chunk-57DBLYIR.mjs +58 -0
  18. package/dist/esm/chunk-57DBLYIR.mjs.map +1 -0
  19. package/dist/esm/chunk-JV6LXL2U.mjs +158 -0
  20. package/dist/esm/chunk-JV6LXL2U.mjs.map +1 -0
  21. package/dist/esm/chunk-QP5VO3IO.mjs +68 -0
  22. package/dist/esm/chunk-QP5VO3IO.mjs.map +1 -0
  23. package/dist/esm/chunk-XUMAS5DJ.mjs +223 -0
  24. package/dist/esm/chunk-XUMAS5DJ.mjs.map +1 -0
  25. package/dist/esm/exact-direct/client/index.d.mts +50 -0
  26. package/dist/esm/exact-direct/client/index.mjs +8 -0
  27. package/dist/esm/exact-direct/client/index.mjs.map +1 -0
  28. package/dist/esm/exact-direct/facilitator/index.d.mts +70 -0
  29. package/dist/esm/exact-direct/facilitator/index.mjs +9 -0
  30. package/dist/esm/exact-direct/facilitator/index.mjs.map +1 -0
  31. package/dist/esm/exact-direct/server/index.d.mts +87 -0
  32. package/dist/esm/exact-direct/server/index.mjs +9 -0
  33. package/dist/esm/exact-direct/server/index.mjs.map +1 -0
  34. package/dist/esm/index.d.mts +178 -0
  35. package/dist/esm/index.mjs +83 -0
  36. package/dist/esm/index.mjs.map +1 -0
  37. package/dist/esm/types-CgseoctH.d.mts +155 -0
  38. package/package.json +96 -0
@@ -0,0 +1,68 @@
1
+ import {
2
+ SCHEME_EXACT_DIRECT,
3
+ USDC_DENOM,
4
+ isValidAddress,
5
+ normalizeNetwork
6
+ } from "./chunk-2UTEGIZ2.mjs";
7
+
8
+ // src/exact-direct/client/scheme.ts
9
+ var ExactDirectCosmosClient = class {
10
+ /**
11
+ * Creates a new ExactDirectCosmosClient instance.
12
+ *
13
+ * @param signer - The Cosmos signer for client operations
14
+ * @param config - Optional configuration overrides
15
+ */
16
+ constructor(signer, config = {}) {
17
+ this.signer = signer;
18
+ this.config = config;
19
+ this.scheme = SCHEME_EXACT_DIRECT;
20
+ }
21
+ /**
22
+ * Creates a payment payload by executing the transfer.
23
+ *
24
+ * Unlike other schemes where the client creates a signed message for
25
+ * the facilitator to execute, the exact-direct scheme has the client
26
+ * execute the transfer directly. The transaction hash is then used
27
+ * as proof of payment.
28
+ *
29
+ * @param t402Version - The t402 protocol version
30
+ * @param paymentRequirements - The payment requirements
31
+ * @returns Promise resolving to a payment payload with transaction hash
32
+ */
33
+ async createPaymentPayload(t402Version, paymentRequirements) {
34
+ const network = normalizeNetwork(paymentRequirements.network);
35
+ if (!paymentRequirements.payTo) {
36
+ throw new Error("PayTo address is required");
37
+ }
38
+ if (!paymentRequirements.amount) {
39
+ throw new Error("Amount is required");
40
+ }
41
+ if (!isValidAddress(paymentRequirements.payTo)) {
42
+ throw new Error(`Invalid recipient address: ${paymentRequirements.payTo}`);
43
+ }
44
+ if (!isValidAddress(this.signer.address)) {
45
+ throw new Error(`Invalid sender address: ${this.signer.address}`);
46
+ }
47
+ const recipient = paymentRequirements.payTo;
48
+ const amount = paymentRequirements.amount;
49
+ const denom = paymentRequirements.extra?.denom || this.config.denom || USDC_DENOM;
50
+ const txHash = await this.signer.sendTokens(network, recipient, amount, denom);
51
+ const payload = {
52
+ txHash,
53
+ from: this.signer.address,
54
+ to: recipient,
55
+ amount,
56
+ denom
57
+ };
58
+ return {
59
+ t402Version,
60
+ payload
61
+ };
62
+ }
63
+ };
64
+
65
+ export {
66
+ ExactDirectCosmosClient
67
+ };
68
+ //# sourceMappingURL=chunk-QP5VO3IO.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/exact-direct/client/scheme.ts"],"sourcesContent":["/**\n * Cosmos Client Scheme Implementation - Exact Direct\n *\n * Creates payment payloads for Cosmos MsgSend transfers using the exact-direct scheme.\n * In this scheme, the client executes the bank send directly and provides\n * the transaction hash as proof of payment.\n */\n\nimport type { PaymentPayload, PaymentRequirements, SchemeNetworkClient } from \"@t402/core/types\";\nimport type { ClientCosmosSigner, ExactDirectCosmosPayload } from \"../../types.js\";\nimport { SCHEME_EXACT_DIRECT, USDC_DENOM } from \"../../constants.js\";\nimport { normalizeNetwork, isValidAddress } from \"../../utils.js\";\n\n/**\n * Configuration for ExactDirectCosmosClient\n */\nexport interface ExactDirectCosmosClientConfig {\n /** Override the default denomination */\n denom?: string;\n}\n\n/**\n * Cosmos client implementation for the Exact-Direct payment scheme.\n *\n * Executes a Cosmos MsgSend and returns the transaction hash as proof.\n */\nexport class ExactDirectCosmosClient implements SchemeNetworkClient {\n readonly scheme = SCHEME_EXACT_DIRECT;\n\n /**\n * Creates a new ExactDirectCosmosClient instance.\n *\n * @param signer - The Cosmos signer for client operations\n * @param config - Optional configuration overrides\n */\n constructor(\n private readonly signer: ClientCosmosSigner,\n private readonly config: ExactDirectCosmosClientConfig = {},\n ) {}\n\n /**\n * Creates a payment payload by executing the transfer.\n *\n * Unlike other schemes where the client creates a signed message for\n * the facilitator to execute, the exact-direct scheme has the client\n * execute the transfer directly. The transaction hash is then used\n * as proof of payment.\n *\n * @param t402Version - The t402 protocol version\n * @param paymentRequirements - The payment requirements\n * @returns Promise resolving to a payment payload with transaction hash\n */\n async createPaymentPayload(\n t402Version: number,\n paymentRequirements: PaymentRequirements,\n ): Promise<Pick<PaymentPayload, \"t402Version\" | \"payload\">> {\n // Normalize and validate network\n const network = normalizeNetwork(paymentRequirements.network);\n\n // Validate required fields\n if (!paymentRequirements.payTo) {\n throw new Error(\"PayTo address is required\");\n }\n if (!paymentRequirements.amount) {\n throw new Error(\"Amount is required\");\n }\n\n // Validate addresses\n if (!isValidAddress(paymentRequirements.payTo)) {\n throw new Error(`Invalid recipient address: ${paymentRequirements.payTo}`);\n }\n if (!isValidAddress(this.signer.address)) {\n throw new Error(`Invalid sender address: ${this.signer.address}`);\n }\n\n const recipient = paymentRequirements.payTo;\n const amount = paymentRequirements.amount;\n\n // Determine denomination from extra field, config, or default\n const denom =\n (paymentRequirements.extra?.denom as string) || this.config.denom || USDC_DENOM;\n\n // Execute the transfer\n const txHash = await this.signer.sendTokens(network, recipient, amount, denom);\n\n // Build the payload\n const payload: ExactDirectCosmosPayload = {\n txHash,\n from: this.signer.address,\n to: recipient,\n amount: amount,\n denom,\n };\n\n return {\n t402Version,\n payload,\n };\n }\n}\n"],"mappings":";;;;;;;;AA0BO,IAAM,0BAAN,MAA6D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASlE,YACmB,QACA,SAAwC,CAAC,GAC1D;AAFiB;AACA;AAVnB,SAAS,SAAS;AAAA,EAWf;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcH,MAAM,qBACJ,aACA,qBAC0D;AAE1D,UAAM,UAAU,iBAAiB,oBAAoB,OAAO;AAG5D,QAAI,CAAC,oBAAoB,OAAO;AAC9B,YAAM,IAAI,MAAM,2BAA2B;AAAA,IAC7C;AACA,QAAI,CAAC,oBAAoB,QAAQ;AAC/B,YAAM,IAAI,MAAM,oBAAoB;AAAA,IACtC;AAGA,QAAI,CAAC,eAAe,oBAAoB,KAAK,GAAG;AAC9C,YAAM,IAAI,MAAM,8BAA8B,oBAAoB,KAAK,EAAE;AAAA,IAC3E;AACA,QAAI,CAAC,eAAe,KAAK,OAAO,OAAO,GAAG;AACxC,YAAM,IAAI,MAAM,2BAA2B,KAAK,OAAO,OAAO,EAAE;AAAA,IAClE;AAEA,UAAM,YAAY,oBAAoB;AACtC,UAAM,SAAS,oBAAoB;AAGnC,UAAM,QACH,oBAAoB,OAAO,SAAoB,KAAK,OAAO,SAAS;AAGvE,UAAM,SAAS,MAAM,KAAK,OAAO,WAAW,SAAS,WAAW,QAAQ,KAAK;AAG7E,UAAM,UAAoC;AAAA,MACxC;AAAA,MACA,MAAM,KAAK,OAAO;AAAA,MAClB,IAAI;AAAA,MACJ;AAAA,MACA;AAAA,IACF;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
@@ -0,0 +1,223 @@
1
+ import {
2
+ getDefaultToken
3
+ } from "./chunk-57DBLYIR.mjs";
4
+ import {
5
+ COSMOS_CAIP2_NAMESPACE,
6
+ MAX_TRANSACTION_AGE,
7
+ MSG_TYPE_SEND,
8
+ SCHEME_EXACT_DIRECT,
9
+ isValidAddress,
10
+ normalizeNetwork
11
+ } from "./chunk-2UTEGIZ2.mjs";
12
+
13
+ // src/exact-direct/facilitator/scheme.ts
14
+ var ExactDirectCosmosFacilitator = class {
15
+ constructor(signer, config) {
16
+ this.signer = signer;
17
+ this.scheme = SCHEME_EXACT_DIRECT;
18
+ this.caipFamily = `${COSMOS_CAIP2_NAMESPACE}:*`;
19
+ this.usedTxs = /* @__PURE__ */ new Map();
20
+ this.config = {
21
+ maxTransactionAge: config?.maxTransactionAge ?? MAX_TRANSACTION_AGE,
22
+ usedTxCacheDuration: config?.usedTxCacheDuration ?? 24 * 60 * 60 * 1e3
23
+ // 24 hours
24
+ };
25
+ this.startCleanupInterval();
26
+ }
27
+ /**
28
+ * Get extra data for a supported kind
29
+ */
30
+ getExtra(network) {
31
+ const token = getDefaultToken(network);
32
+ if (!token) {
33
+ return void 0;
34
+ }
35
+ return {
36
+ assetSymbol: token.symbol,
37
+ assetDecimals: token.decimals,
38
+ assetDenom: token.denom
39
+ };
40
+ }
41
+ /**
42
+ * Get signer addresses for a network
43
+ */
44
+ getSigners(network) {
45
+ return this.signer.getAddresses(network);
46
+ }
47
+ /**
48
+ * Verify a payment payload
49
+ */
50
+ async verify(payload, requirements) {
51
+ const network = normalizeNetwork(requirements.network);
52
+ if (payload.accepted.scheme !== SCHEME_EXACT_DIRECT) {
53
+ return {
54
+ isValid: false,
55
+ invalidReason: "invalid_scheme"
56
+ };
57
+ }
58
+ if (normalizeNetwork(payload.accepted.network) !== network) {
59
+ return {
60
+ isValid: false,
61
+ invalidReason: "network_mismatch"
62
+ };
63
+ }
64
+ const cosmosPayload = payload.payload;
65
+ if (!cosmosPayload.txHash) {
66
+ return {
67
+ isValid: false,
68
+ invalidReason: "missing_tx_hash"
69
+ };
70
+ }
71
+ if (!cosmosPayload.from || !isValidAddress(cosmosPayload.from)) {
72
+ return {
73
+ isValid: false,
74
+ invalidReason: "invalid_from_address"
75
+ };
76
+ }
77
+ if (this.isTxUsed(cosmosPayload.txHash)) {
78
+ return {
79
+ isValid: false,
80
+ invalidReason: "transaction_already_used",
81
+ payer: cosmosPayload.from
82
+ };
83
+ }
84
+ try {
85
+ const tx = await this.signer.queryTransaction(network, cosmosPayload.txHash);
86
+ if (tx.code !== 0) {
87
+ return {
88
+ isValid: false,
89
+ invalidReason: "transaction_failed",
90
+ payer: cosmosPayload.from
91
+ };
92
+ }
93
+ const msgSend = this.findMsgSend(tx.tx.body.messages);
94
+ if (!msgSend) {
95
+ return {
96
+ isValid: false,
97
+ invalidReason: "no_msg_send_found",
98
+ payer: cosmosPayload.from
99
+ };
100
+ }
101
+ if (msgSend.toAddress !== requirements.payTo) {
102
+ return {
103
+ isValid: false,
104
+ invalidReason: "wrong_recipient",
105
+ payer: cosmosPayload.from
106
+ };
107
+ }
108
+ if (msgSend.fromAddress !== cosmosPayload.from) {
109
+ return {
110
+ isValid: false,
111
+ invalidReason: "sender_mismatch",
112
+ payer: cosmosPayload.from
113
+ };
114
+ }
115
+ const expectedDenom = requirements.extra?.denom || requirements.asset;
116
+ const coin = this.getAmountByDenom(msgSend, expectedDenom);
117
+ if (!coin) {
118
+ return {
119
+ isValid: false,
120
+ invalidReason: "wrong_denomination",
121
+ payer: cosmosPayload.from
122
+ };
123
+ }
124
+ const txAmount = BigInt(coin.amount);
125
+ const requiredAmount = BigInt(requirements.amount);
126
+ if (txAmount < requiredAmount) {
127
+ return {
128
+ isValid: false,
129
+ invalidReason: "insufficient_amount",
130
+ payer: cosmosPayload.from
131
+ };
132
+ }
133
+ this.markTxUsed(cosmosPayload.txHash);
134
+ return {
135
+ isValid: true,
136
+ payer: cosmosPayload.from
137
+ };
138
+ } catch {
139
+ return {
140
+ isValid: false,
141
+ invalidReason: "transaction_not_found",
142
+ payer: cosmosPayload.from
143
+ };
144
+ }
145
+ }
146
+ /**
147
+ * Settle a payment - for exact-direct, the transfer is already complete
148
+ */
149
+ async settle(payload, requirements) {
150
+ const verifyResult = await this.verify(payload, requirements);
151
+ if (!verifyResult.isValid) {
152
+ return {
153
+ success: false,
154
+ errorReason: verifyResult.invalidReason || "verification_failed",
155
+ payer: verifyResult.payer,
156
+ transaction: "",
157
+ network: normalizeNetwork(requirements.network)
158
+ };
159
+ }
160
+ const cosmosPayload = payload.payload;
161
+ return {
162
+ success: true,
163
+ transaction: cosmosPayload.txHash,
164
+ network: normalizeNetwork(requirements.network),
165
+ payer: cosmosPayload.from
166
+ };
167
+ }
168
+ /**
169
+ * Find a MsgSend in transaction messages
170
+ */
171
+ findMsgSend(messages) {
172
+ for (const msg of messages) {
173
+ if (msg["@type"] === MSG_TYPE_SEND || !msg["@type"] && msg.fromAddress && msg.toAddress) {
174
+ return msg;
175
+ }
176
+ }
177
+ return null;
178
+ }
179
+ /**
180
+ * Get a specific coin amount from a MsgSend by denomination
181
+ */
182
+ getAmountByDenom(msg, denom) {
183
+ for (const coin of msg.amount) {
184
+ if (coin.denom === denom) {
185
+ return coin;
186
+ }
187
+ }
188
+ return null;
189
+ }
190
+ /**
191
+ * Check if a transaction has been used
192
+ */
193
+ isTxUsed(txHash) {
194
+ return this.usedTxs.has(txHash);
195
+ }
196
+ /**
197
+ * Mark a transaction as used
198
+ */
199
+ markTxUsed(txHash) {
200
+ this.usedTxs.set(txHash, Date.now());
201
+ }
202
+ /**
203
+ * Start the cleanup interval for used transactions
204
+ */
205
+ startCleanupInterval() {
206
+ setInterval(
207
+ () => {
208
+ const cutoff = Date.now() - this.config.usedTxCacheDuration;
209
+ for (const [txHash, usedAt] of this.usedTxs.entries()) {
210
+ if (usedAt < cutoff) {
211
+ this.usedTxs.delete(txHash);
212
+ }
213
+ }
214
+ },
215
+ 60 * 60 * 1e3
216
+ );
217
+ }
218
+ };
219
+
220
+ export {
221
+ ExactDirectCosmosFacilitator
222
+ };
223
+ //# sourceMappingURL=chunk-XUMAS5DJ.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/exact-direct/facilitator/scheme.ts"],"sourcesContent":["/**\n * Cosmos Facilitator Scheme Implementation - Exact Direct\n *\n * Verifies and settles Cosmos (Noble USDC) payments using the exact-direct scheme.\n * The facilitator verifies that the client's transaction was successful\n * and matches the payment requirements.\n */\n\nimport type {\n Network,\n PaymentPayload,\n PaymentRequirements,\n SchemeNetworkFacilitator,\n SettleResponse,\n VerifyResponse,\n} from \"@t402/core/types\";\nimport type { FacilitatorCosmosSigner, ExactDirectCosmosPayload, MsgSend } from \"../../types.js\";\nimport { SCHEME_EXACT_DIRECT, COSMOS_CAIP2_NAMESPACE, MAX_TRANSACTION_AGE, MSG_TYPE_SEND } from \"../../constants.js\";\nimport { normalizeNetwork, isValidAddress } from \"../../utils.js\";\nimport { getDefaultToken } from \"../../tokens.js\";\n\n/**\n * Configuration for ExactDirectCosmosFacilitator\n */\nexport interface ExactDirectCosmosFacilitatorConfig {\n /** Maximum age of a transaction to accept (in milliseconds) */\n maxTransactionAge?: number;\n /** Duration to cache used transaction hashes (in milliseconds) */\n usedTxCacheDuration?: number;\n}\n\n/**\n * Cosmos facilitator implementation for the Exact-Direct payment scheme.\n * Verifies transaction proofs and confirms payments.\n */\nexport class ExactDirectCosmosFacilitator implements SchemeNetworkFacilitator {\n readonly scheme = SCHEME_EXACT_DIRECT;\n readonly caipFamily = `${COSMOS_CAIP2_NAMESPACE}:*`;\n\n private readonly config: Required<ExactDirectCosmosFacilitatorConfig>;\n private usedTxs: Map<string, number> = new Map();\n\n constructor(\n private readonly signer: FacilitatorCosmosSigner,\n config?: ExactDirectCosmosFacilitatorConfig,\n ) {\n this.config = {\n maxTransactionAge: config?.maxTransactionAge ?? MAX_TRANSACTION_AGE,\n usedTxCacheDuration: config?.usedTxCacheDuration ?? 24 * 60 * 60 * 1000, // 24 hours\n };\n\n // Start cleanup interval\n this.startCleanupInterval();\n }\n\n /**\n * Get extra data for a supported kind\n */\n getExtra(network: Network): Record<string, unknown> | undefined {\n const token = getDefaultToken(network);\n if (!token) {\n return undefined;\n }\n return {\n assetSymbol: token.symbol,\n assetDecimals: token.decimals,\n assetDenom: token.denom,\n };\n }\n\n /**\n * Get signer addresses for a network\n */\n getSigners(network: Network): string[] {\n return this.signer.getAddresses(network);\n }\n\n /**\n * Verify a payment payload\n */\n async verify(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<VerifyResponse> {\n const network = normalizeNetwork(requirements.network);\n\n // Validate scheme\n if (payload.accepted.scheme !== SCHEME_EXACT_DIRECT) {\n return {\n isValid: false,\n invalidReason: \"invalid_scheme\",\n };\n }\n\n // Validate network\n if (normalizeNetwork(payload.accepted.network) !== network) {\n return {\n isValid: false,\n invalidReason: \"network_mismatch\",\n };\n }\n\n // Parse payload\n const cosmosPayload = payload.payload as ExactDirectCosmosPayload;\n if (!cosmosPayload.txHash) {\n return {\n isValid: false,\n invalidReason: \"missing_tx_hash\",\n };\n }\n if (!cosmosPayload.from || !isValidAddress(cosmosPayload.from)) {\n return {\n isValid: false,\n invalidReason: \"invalid_from_address\",\n };\n }\n\n // Check for replay attack\n if (this.isTxUsed(cosmosPayload.txHash)) {\n return {\n isValid: false,\n invalidReason: \"transaction_already_used\",\n payer: cosmosPayload.from,\n };\n }\n\n try {\n // Query the transaction\n const tx = await this.signer.queryTransaction(network, cosmosPayload.txHash);\n\n // Check transaction succeeded (code 0 = success)\n if (tx.code !== 0) {\n return {\n isValid: false,\n invalidReason: \"transaction_failed\",\n payer: cosmosPayload.from,\n };\n }\n\n // Find the MsgSend in the transaction messages\n const msgSend = this.findMsgSend(tx.tx.body.messages);\n if (!msgSend) {\n return {\n isValid: false,\n invalidReason: \"no_msg_send_found\",\n payer: cosmosPayload.from,\n };\n }\n\n // Verify recipient\n if (msgSend.toAddress !== requirements.payTo) {\n return {\n isValid: false,\n invalidReason: \"wrong_recipient\",\n payer: cosmosPayload.from,\n };\n }\n\n // Verify sender matches payload\n if (msgSend.fromAddress !== cosmosPayload.from) {\n return {\n isValid: false,\n invalidReason: \"sender_mismatch\",\n payer: cosmosPayload.from,\n };\n }\n\n // Determine expected denom\n const expectedDenom = (requirements.extra?.denom as string) || requirements.asset;\n\n // Verify amount and denomination\n const coin = this.getAmountByDenom(msgSend, expectedDenom);\n if (!coin) {\n return {\n isValid: false,\n invalidReason: \"wrong_denomination\",\n payer: cosmosPayload.from,\n };\n }\n\n const txAmount = BigInt(coin.amount);\n const requiredAmount = BigInt(requirements.amount);\n if (txAmount < requiredAmount) {\n return {\n isValid: false,\n invalidReason: \"insufficient_amount\",\n payer: cosmosPayload.from,\n };\n }\n\n // Mark transaction as used\n this.markTxUsed(cosmosPayload.txHash);\n\n return {\n isValid: true,\n payer: cosmosPayload.from,\n };\n } catch {\n return {\n isValid: false,\n invalidReason: \"transaction_not_found\",\n payer: cosmosPayload.from,\n };\n }\n }\n\n /**\n * Settle a payment - for exact-direct, the transfer is already complete\n */\n async settle(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<SettleResponse> {\n // Verify first\n const verifyResult = await this.verify(payload, requirements);\n if (!verifyResult.isValid) {\n return {\n success: false,\n errorReason: verifyResult.invalidReason || \"verification_failed\",\n payer: verifyResult.payer,\n transaction: \"\",\n network: normalizeNetwork(requirements.network),\n };\n }\n\n const cosmosPayload = payload.payload as ExactDirectCosmosPayload;\n\n // For exact-direct, settlement is already complete\n return {\n success: true,\n transaction: cosmosPayload.txHash,\n network: normalizeNetwork(requirements.network),\n payer: cosmosPayload.from,\n };\n }\n\n /**\n * Find a MsgSend in transaction messages\n */\n private findMsgSend(messages: MsgSend[]): MsgSend | null {\n for (const msg of messages) {\n if (msg[\"@type\"] === MSG_TYPE_SEND || (!msg[\"@type\"] && msg.fromAddress && msg.toAddress)) {\n return msg;\n }\n }\n return null;\n }\n\n /**\n * Get a specific coin amount from a MsgSend by denomination\n */\n private getAmountByDenom(msg: MsgSend, denom: string): { denom: string; amount: string } | null {\n for (const coin of msg.amount) {\n if (coin.denom === denom) {\n return coin;\n }\n }\n return null;\n }\n\n /**\n * Check if a transaction has been used\n */\n private isTxUsed(txHash: string): boolean {\n return this.usedTxs.has(txHash);\n }\n\n /**\n * Mark a transaction as used\n */\n private markTxUsed(txHash: string): void {\n this.usedTxs.set(txHash, Date.now());\n }\n\n /**\n * Start the cleanup interval for used transactions\n */\n private startCleanupInterval(): void {\n setInterval(\n () => {\n const cutoff = Date.now() - this.config.usedTxCacheDuration;\n for (const [txHash, usedAt] of this.usedTxs.entries()) {\n if (usedAt < cutoff) {\n this.usedTxs.delete(txHash);\n }\n }\n },\n 60 * 60 * 1000,\n ); // Cleanup every hour\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,50 @@
1
+ import { SchemeNetworkClient, PaymentRequirements, PaymentPayload } from '@t402/core/types';
2
+ import { d as ClientCosmosSigner } from '../../types-CgseoctH.mjs';
3
+
4
+ /**
5
+ * Cosmos Client Scheme Implementation - Exact Direct
6
+ *
7
+ * Creates payment payloads for Cosmos MsgSend transfers using the exact-direct scheme.
8
+ * In this scheme, the client executes the bank send directly and provides
9
+ * the transaction hash as proof of payment.
10
+ */
11
+
12
+ /**
13
+ * Configuration for ExactDirectCosmosClient
14
+ */
15
+ interface ExactDirectCosmosClientConfig {
16
+ /** Override the default denomination */
17
+ denom?: string;
18
+ }
19
+ /**
20
+ * Cosmos client implementation for the Exact-Direct payment scheme.
21
+ *
22
+ * Executes a Cosmos MsgSend and returns the transaction hash as proof.
23
+ */
24
+ declare class ExactDirectCosmosClient implements SchemeNetworkClient {
25
+ private readonly signer;
26
+ private readonly config;
27
+ readonly scheme = "exact-direct";
28
+ /**
29
+ * Creates a new ExactDirectCosmosClient instance.
30
+ *
31
+ * @param signer - The Cosmos signer for client operations
32
+ * @param config - Optional configuration overrides
33
+ */
34
+ constructor(signer: ClientCosmosSigner, config?: ExactDirectCosmosClientConfig);
35
+ /**
36
+ * Creates a payment payload by executing the transfer.
37
+ *
38
+ * Unlike other schemes where the client creates a signed message for
39
+ * the facilitator to execute, the exact-direct scheme has the client
40
+ * execute the transfer directly. The transaction hash is then used
41
+ * as proof of payment.
42
+ *
43
+ * @param t402Version - The t402 protocol version
44
+ * @param paymentRequirements - The payment requirements
45
+ * @returns Promise resolving to a payment payload with transaction hash
46
+ */
47
+ createPaymentPayload(t402Version: number, paymentRequirements: PaymentRequirements): Promise<Pick<PaymentPayload, "t402Version" | "payload">>;
48
+ }
49
+
50
+ export { ExactDirectCosmosClient, type ExactDirectCosmosClientConfig };
@@ -0,0 +1,8 @@
1
+ import {
2
+ ExactDirectCosmosClient
3
+ } from "../../chunk-QP5VO3IO.mjs";
4
+ import "../../chunk-2UTEGIZ2.mjs";
5
+ export {
6
+ ExactDirectCosmosClient
7
+ };
8
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,70 @@
1
+ import { SchemeNetworkFacilitator, Network, PaymentPayload, PaymentRequirements, VerifyResponse, SettleResponse } from '@t402/core/types';
2
+ import { F as FacilitatorCosmosSigner } from '../../types-CgseoctH.mjs';
3
+
4
+ /**
5
+ * Cosmos Facilitator Scheme Implementation - Exact Direct
6
+ *
7
+ * Verifies and settles Cosmos (Noble USDC) payments using the exact-direct scheme.
8
+ * The facilitator verifies that the client's transaction was successful
9
+ * and matches the payment requirements.
10
+ */
11
+
12
+ /**
13
+ * Configuration for ExactDirectCosmosFacilitator
14
+ */
15
+ interface ExactDirectCosmosFacilitatorConfig {
16
+ /** Maximum age of a transaction to accept (in milliseconds) */
17
+ maxTransactionAge?: number;
18
+ /** Duration to cache used transaction hashes (in milliseconds) */
19
+ usedTxCacheDuration?: number;
20
+ }
21
+ /**
22
+ * Cosmos facilitator implementation for the Exact-Direct payment scheme.
23
+ * Verifies transaction proofs and confirms payments.
24
+ */
25
+ declare class ExactDirectCosmosFacilitator implements SchemeNetworkFacilitator {
26
+ private readonly signer;
27
+ readonly scheme = "exact-direct";
28
+ readonly caipFamily = "cosmos:*";
29
+ private readonly config;
30
+ private usedTxs;
31
+ constructor(signer: FacilitatorCosmosSigner, config?: ExactDirectCosmosFacilitatorConfig);
32
+ /**
33
+ * Get extra data for a supported kind
34
+ */
35
+ getExtra(network: Network): Record<string, unknown> | undefined;
36
+ /**
37
+ * Get signer addresses for a network
38
+ */
39
+ getSigners(network: Network): string[];
40
+ /**
41
+ * Verify a payment payload
42
+ */
43
+ verify(payload: PaymentPayload, requirements: PaymentRequirements): Promise<VerifyResponse>;
44
+ /**
45
+ * Settle a payment - for exact-direct, the transfer is already complete
46
+ */
47
+ settle(payload: PaymentPayload, requirements: PaymentRequirements): Promise<SettleResponse>;
48
+ /**
49
+ * Find a MsgSend in transaction messages
50
+ */
51
+ private findMsgSend;
52
+ /**
53
+ * Get a specific coin amount from a MsgSend by denomination
54
+ */
55
+ private getAmountByDenom;
56
+ /**
57
+ * Check if a transaction has been used
58
+ */
59
+ private isTxUsed;
60
+ /**
61
+ * Mark a transaction as used
62
+ */
63
+ private markTxUsed;
64
+ /**
65
+ * Start the cleanup interval for used transactions
66
+ */
67
+ private startCleanupInterval;
68
+ }
69
+
70
+ export { ExactDirectCosmosFacilitator, type ExactDirectCosmosFacilitatorConfig };
@@ -0,0 +1,9 @@
1
+ import {
2
+ ExactDirectCosmosFacilitator
3
+ } from "../../chunk-XUMAS5DJ.mjs";
4
+ import "../../chunk-57DBLYIR.mjs";
5
+ import "../../chunk-2UTEGIZ2.mjs";
6
+ export {
7
+ ExactDirectCosmosFacilitator
8
+ };
9
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,87 @@
1
+ import { SchemeNetworkServer, MoneyParser, Price, Network, AssetAmount, PaymentRequirements } from '@t402/core/types';
2
+
3
+ /**
4
+ * Cosmos Server Scheme Implementation - Exact Direct
5
+ *
6
+ * Handles price parsing and payment requirement enhancement for
7
+ * Cosmos (Noble USDC) payments using the exact-direct scheme.
8
+ */
9
+
10
+ /**
11
+ * Configuration options for ExactDirectCosmosServer
12
+ */
13
+ interface ExactDirectCosmosServerConfig {
14
+ /** Preferred token symbol (e.g., "USDC"). Defaults to network's highest priority token. */
15
+ preferredToken?: string;
16
+ }
17
+ /**
18
+ * Cosmos server implementation for the Exact-Direct payment scheme.
19
+ * Handles price parsing and converts user-friendly amounts to token amounts.
20
+ */
21
+ declare class ExactDirectCosmosServer implements SchemeNetworkServer {
22
+ readonly scheme = "exact-direct";
23
+ private moneyParsers;
24
+ private config;
25
+ constructor(config?: ExactDirectCosmosServerConfig);
26
+ /**
27
+ * Register a custom money parser in the parser chain.
28
+ * Multiple parsers can be registered - they will be tried in registration order.
29
+ * Each parser receives a decimal amount (e.g., 1.50 for $1.50).
30
+ * If a parser returns null, the next parser in the chain will be tried.
31
+ * The default parser is always the final fallback.
32
+ *
33
+ * @param parser - Custom function to convert amount to AssetAmount (or null to skip)
34
+ * @returns The server instance for chaining
35
+ */
36
+ registerMoneyParser(parser: MoneyParser): ExactDirectCosmosServer;
37
+ /**
38
+ * Parses a price into an asset amount.
39
+ * If price is already an AssetAmount, returns it directly.
40
+ * If price is Money (string | number), parses to decimal and tries custom parsers.
41
+ * Falls back to default conversion if all custom parsers return null.
42
+ *
43
+ * @param price - The price to parse
44
+ * @param network - The network to use
45
+ * @returns Promise that resolves to the parsed asset amount
46
+ */
47
+ parsePrice(price: Price, network: Network): Promise<AssetAmount>;
48
+ /**
49
+ * Build payment requirements for this scheme/network combination.
50
+ *
51
+ * @param paymentRequirements - Base payment requirements with amount/asset already set
52
+ * @param supportedKind - The supported kind from facilitator's /supported endpoint
53
+ * @param extensionKeys - Extensions supported by the facilitator
54
+ * @returns Enhanced payment requirements ready to be sent to clients
55
+ */
56
+ enhancePaymentRequirements(paymentRequirements: PaymentRequirements, supportedKind: {
57
+ t402Version: number;
58
+ scheme: string;
59
+ network: Network;
60
+ extra?: Record<string, unknown>;
61
+ }, extensionKeys: string[]): Promise<PaymentRequirements>;
62
+ /**
63
+ * Parse Money (string | number) to a decimal number.
64
+ * Handles formats like "$1.50", "1.50", 1.50, etc.
65
+ */
66
+ private parseMoneyToDecimal;
67
+ /**
68
+ * Default money conversion implementation.
69
+ * Converts decimal amount to the preferred token on the specified network.
70
+ */
71
+ private defaultMoneyConversion;
72
+ /**
73
+ * Get the default asset info for a network.
74
+ * Priority: configured preferredToken > network default
75
+ */
76
+ private getDefaultAsset;
77
+ /**
78
+ * Get all supported networks
79
+ */
80
+ static getSupportedNetworks(): string[];
81
+ /**
82
+ * Check if a network is supported
83
+ */
84
+ static isNetworkSupported(network: string): boolean;
85
+ }
86
+
87
+ export { ExactDirectCosmosServer, type ExactDirectCosmosServerConfig };
@@ -0,0 +1,9 @@
1
+ import {
2
+ ExactDirectCosmosServer
3
+ } from "../../chunk-JV6LXL2U.mjs";
4
+ import "../../chunk-57DBLYIR.mjs";
5
+ import "../../chunk-2UTEGIZ2.mjs";
6
+ export {
7
+ ExactDirectCosmosServer
8
+ };
9
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}