integraledger-terms 0.1.0__py3-none-any.whl

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 (149) hide show
  1. integraledger_terms/__init__.py +261 -0
  2. integraledger_terms/_agreement.py +306 -0
  3. integraledger_terms/_channels.py +409 -0
  4. integraledger_terms/_core.py +27 -0
  5. integraledger_terms/_gate.py +394 -0
  6. integraledger_terms/_keccak.py +61 -0
  7. integraledger_terms/_types.py +196 -0
  8. integraledger_terms/bindings/__init__.py +1 -0
  9. integraledger_terms/bindings/_algorand.py +406 -0
  10. integraledger_terms/bindings/_batch.py +59 -0
  11. integraledger_terms/bindings/_batch_evm.py +98 -0
  12. integraledger_terms/bindings/_bcs.py +317 -0
  13. integraledger_terms/bindings/_bolt11.py +208 -0
  14. integraledger_terms/bindings/_borsh_near.py +233 -0
  15. integraledger_terms/bindings/_cbor.py +173 -0
  16. integraledger_terms/bindings/_cbor_spans.py +133 -0
  17. integraledger_terms/bindings/_channel.py +49 -0
  18. integraledger_terms/bindings/_codec.py +248 -0
  19. integraledger_terms/bindings/_evm.py +455 -0
  20. integraledger_terms/bindings/_hedera_proto.py +338 -0
  21. integraledger_terms/bindings/_jose.py +494 -0
  22. integraledger_terms/bindings/_lcp.py +245 -0
  23. integraledger_terms/bindings/_mpp.py +545 -0
  24. integraledger_terms/bindings/_mpp_checks.py +751 -0
  25. integraledger_terms/bindings/_mpp_evm.py +199 -0
  26. integraledger_terms/bindings/_rail_bytes.py +53 -0
  27. integraledger_terms/bindings/_rlp.py +105 -0
  28. integraledger_terms/bindings/_scale.py +35 -0
  29. integraledger_terms/bindings/_session_within.py +107 -0
  30. integraledger_terms/bindings/_sfv.py +216 -0
  31. integraledger_terms/bindings/_ss58.py +21 -0
  32. integraledger_terms/bindings/_stacks.py +322 -0
  33. integraledger_terms/bindings/_stellar.py +354 -0
  34. integraledger_terms/bindings/_stellar_xdr.py +633 -0
  35. integraledger_terms/bindings/_sui_tx.py +443 -0
  36. integraledger_terms/bindings/_svm.py +750 -0
  37. integraledger_terms/bindings/_tempo.py +280 -0
  38. integraledger_terms/bindings/_ton_cell.py +378 -0
  39. integraledger_terms/bindings/_ton_tlb.py +158 -0
  40. integraledger_terms/bindings/_tron_proto.py +249 -0
  41. integraledger_terms/bindings/_url.py +126 -0
  42. integraledger_terms/bindings/_x402.py +145 -0
  43. integraledger_terms/bindings/_xrpl.py +115 -0
  44. integraledger_terms/bindings/_xrpl_codec.py +634 -0
  45. integraledger_terms/bindings/ack_payment_request.py +99 -0
  46. integraledger_terms/bindings/acp_checkout.py +213 -0
  47. integraledger_terms/bindings/ap2_checkout_mandate.py +204 -0
  48. integraledger_terms/bindings/card.py +465 -0
  49. integraledger_terms/bindings/lightning.py +400 -0
  50. integraledger_terms/bindings/mpp_card_stripe.py +51 -0
  51. integraledger_terms/bindings/mpp_charge_evm.py +308 -0
  52. integraledger_terms/bindings/mpp_charge_hedera.py +142 -0
  53. integraledger_terms/bindings/mpp_charge_nearintents.py +42 -0
  54. integraledger_terms/bindings/mpp_charge_solana.py +210 -0
  55. integraledger_terms/bindings/mpp_charge_stellar.py +103 -0
  56. integraledger_terms/bindings/mpp_charge_tempo.py +173 -0
  57. integraledger_terms/bindings/mpp_charge_usdc.py +348 -0
  58. integraledger_terms/bindings/mpp_charge_usdc_stacks.py +127 -0
  59. integraledger_terms/bindings/mpp_charge_xrpl.py +136 -0
  60. integraledger_terms/bindings/mpp_session.py +908 -0
  61. integraledger_terms/bindings/mpp_session_hedera.py +262 -0
  62. integraledger_terms/bindings/mpp_session_solana.py +280 -0
  63. integraledger_terms/bindings/mpp_session_xrpl.py +285 -0
  64. integraledger_terms/bindings/ucp.py +184 -0
  65. integraledger_terms/bindings/x402_batch_settlement_cloudflare.py +76 -0
  66. integraledger_terms/bindings/x402_batch_settlement_eip155.py +351 -0
  67. integraledger_terms/bindings/x402_batch_settlement_solana.py +447 -0
  68. integraledger_terms/bindings/x402_evm.py +733 -0
  69. integraledger_terms/bindings/x402_exact_algorand.py +223 -0
  70. integraledger_terms/bindings/x402_exact_aptos.py +254 -0
  71. integraledger_terms/bindings/x402_exact_cardano.py +249 -0
  72. integraledger_terms/bindings/x402_exact_casper.py +217 -0
  73. integraledger_terms/bindings/x402_exact_ccd.py +282 -0
  74. integraledger_terms/bindings/x402_exact_eip155_eip3009.py +265 -0
  75. integraledger_terms/bindings/x402_exact_hedera.py +315 -0
  76. integraledger_terms/bindings/x402_exact_near.py +204 -0
  77. integraledger_terms/bindings/x402_exact_polkadot_lcp_assets_remark.py +211 -0
  78. integraledger_terms/bindings/x402_exact_solana.py +151 -0
  79. integraledger_terms/bindings/x402_exact_starknet.py +276 -0
  80. integraledger_terms/bindings/x402_exact_stellar.py +120 -0
  81. integraledger_terms/bindings/x402_exact_sui.py +192 -0
  82. integraledger_terms/bindings/x402_exact_tron_lcp_trc20_memo.py +181 -0
  83. integraledger_terms/bindings/x402_exact_tvm.py +360 -0
  84. integraledger_terms/bindings/x402_exact_xrpl.py +166 -0
  85. integraledger_terms/bindings/x402_upto_solana.py +197 -0
  86. integraledger_terms/pieces/__init__.py +17 -0
  87. integraledger_terms/pieces/_base.py +21 -0
  88. integraledger_terms/pieces/_batch.py +96 -0
  89. integraledger_terms/pieces/_common.py +151 -0
  90. integraledger_terms/pieces/_family_evm.py +29 -0
  91. integraledger_terms/pieces/_family_hbar.py +22 -0
  92. integraledger_terms/pieces/_family_mpp.py +25 -0
  93. integraledger_terms/pieces/_family_proto.py +23 -0
  94. integraledger_terms/pieces/_family_rails.py +20 -0
  95. integraledger_terms/pieces/_family_sol.py +13 -0
  96. integraledger_terms/pieces/_family_xlm.py +14 -0
  97. integraledger_terms/pieces/_lnbtc_request.py +185 -0
  98. integraledger_terms/pieces/_mpp.py +269 -0
  99. integraledger_terms/pieces/_sol_rail.py +14 -0
  100. integraledger_terms/pieces/_x402_account_rails.py +81 -0
  101. integraledger_terms/pieces/_x402_rail.py +96 -0
  102. integraledger_terms/pieces/ack_payment_request.py +24 -0
  103. integraledger_terms/pieces/acp_checkout.py +68 -0
  104. integraledger_terms/pieces/ap2_checkout_mandate.py +38 -0
  105. integraledger_terms/pieces/card.py +104 -0
  106. integraledger_terms/pieces/evm_x402.py +54 -0
  107. integraledger_terms/pieces/lightning.py +138 -0
  108. integraledger_terms/pieces/mpp_card_stripe.py +10 -0
  109. integraledger_terms/pieces/mpp_charge_evm.py +11 -0
  110. integraledger_terms/pieces/mpp_charge_hedera.py +159 -0
  111. integraledger_terms/pieces/mpp_charge_nearintents.py +54 -0
  112. integraledger_terms/pieces/mpp_charge_solana.py +63 -0
  113. integraledger_terms/pieces/mpp_charge_stellar.py +32 -0
  114. integraledger_terms/pieces/mpp_charge_tempo.py +158 -0
  115. integraledger_terms/pieces/mpp_charge_usdc.py +56 -0
  116. integraledger_terms/pieces/mpp_charge_usdc_stacks.py +29 -0
  117. integraledger_terms/pieces/mpp_charge_xrpl.py +38 -0
  118. integraledger_terms/pieces/mpp_session.py +77 -0
  119. integraledger_terms/pieces/mpp_session_hedera.py +63 -0
  120. integraledger_terms/pieces/mpp_session_solana.py +79 -0
  121. integraledger_terms/pieces/mpp_session_xrpl.py +60 -0
  122. integraledger_terms/pieces/protocol_groups.py +49 -0
  123. integraledger_terms/pieces/ucp.py +51 -0
  124. integraledger_terms/pieces/x402_batch_settlement_cloudflare.py +42 -0
  125. integraledger_terms/pieces/x402_batch_settlement_eip155.py +54 -0
  126. integraledger_terms/pieces/x402_batch_settlement_solana.py +81 -0
  127. integraledger_terms/pieces/x402_exact_algorand.py +53 -0
  128. integraledger_terms/pieces/x402_exact_aptos.py +11 -0
  129. integraledger_terms/pieces/x402_exact_cardano.py +13 -0
  130. integraledger_terms/pieces/x402_exact_casper.py +39 -0
  131. integraledger_terms/pieces/x402_exact_ccd.py +36 -0
  132. integraledger_terms/pieces/x402_exact_eip155_eip3009.py +62 -0
  133. integraledger_terms/pieces/x402_exact_hedera.py +62 -0
  134. integraledger_terms/pieces/x402_exact_hedera_transfer_executor.py +39 -0
  135. integraledger_terms/pieces/x402_exact_near.py +51 -0
  136. integraledger_terms/pieces/x402_exact_polkadot_lcp_assets_remark.py +37 -0
  137. integraledger_terms/pieces/x402_exact_solana.py +38 -0
  138. integraledger_terms/pieces/x402_exact_starknet.py +38 -0
  139. integraledger_terms/pieces/x402_exact_stellar.py +31 -0
  140. integraledger_terms/pieces/x402_exact_sui.py +11 -0
  141. integraledger_terms/pieces/x402_exact_tron_lcp_trc20_memo.py +65 -0
  142. integraledger_terms/pieces/x402_exact_tvm.py +58 -0
  143. integraledger_terms/pieces/x402_exact_xrpl.py +43 -0
  144. integraledger_terms/pieces/x402_upto_solana.py +52 -0
  145. integraledger_terms/py.typed +0 -0
  146. integraledger_terms-0.1.0.dist-info/METADATA +583 -0
  147. integraledger_terms-0.1.0.dist-info/RECORD +149 -0
  148. integraledger_terms-0.1.0.dist-info/WHEEL +4 -0
  149. integraledger_terms-0.1.0.dist-info/licenses/LICENSE +202 -0
@@ -0,0 +1,261 @@
1
+ """The Python buyer gate: before a buyer signs, confirm that the advertised ATR hash is the SHA-256 of the bytes the
2
+ seller's link serves, build the payment with that hash, and confirm the hash inside what was signed."""
3
+
4
+ from ._agreement import agree
5
+ from ._channels import ChannelHold, Within, open_channel, record_charge, within
6
+ from ._core import MAX_ATR_BYTES, AtrHash, atr_hash, hash_equals
7
+ from ._gate import check, confirm, finish, transact
8
+ from ._types import (
9
+ Advertised,
10
+ Agreed,
11
+ AgreementReceipt,
12
+ Binding,
13
+ Checked,
14
+ Chosen,
15
+ Confirmed,
16
+ DeclineCode,
17
+ Declined,
18
+ Finished,
19
+ Inputs,
20
+ Json,
21
+ Next,
22
+ Refusal,
23
+ Signature,
24
+ Signer,
25
+ Step,
26
+ Transacted,
27
+ Unsigned,
28
+ )
29
+ from .bindings.mpp_card_stripe import charge_card, charge_stripe, subscription_stripe
30
+ from .bindings.mpp_charge_evm import (
31
+ MppChargeEvmAuthorization,
32
+ MppChargeEvmHash,
33
+ MppChargeEvmPermit2,
34
+ MppChargeEvmTransaction,
35
+ )
36
+ from .bindings.mpp_charge_nearintents import MppChargeNearIntents
37
+ from .bindings.mpp_charge_tempo import MppChargeTempoMemo, MppChargeTempoPush
38
+ from .bindings.mpp_charge_usdc import MppChargeUsdcEvm, MppChargeUsdcGateway
39
+ from .bindings.mpp_session import MppSessionEvm, MppSessionTempo, MppSubscriptionTempo
40
+ from .bindings._channel import BatchUnsigned, ChannelRef
41
+ from .bindings.ack_payment_request import AckPaymentRequest
42
+ from .bindings.acp_checkout import AcpCheckoutDelegated, AcpCheckoutUndelegated
43
+ from .bindings.ap2_checkout_mandate import Ap2CheckoutMandate
44
+ from .bindings.card import CardMastercardViAutonomous, CardMastercardViImmediate, CardSellerReference, CardVisaTap
45
+ from .bindings.lightning import (
46
+ MPP_CHARGE,
47
+ MppLightning,
48
+ MppLightningSession,
49
+ X402ExactLnbtc,
50
+ X402ExactLnbtcInvoiceNamed,
51
+ )
52
+ from .bindings.ucp import (
53
+ BOOKING_AP2_MANDATE,
54
+ BOOKING_UNSIGNED,
55
+ CHECKOUT_AP2_MANDATE,
56
+ CHECKOUT_UNSIGNED,
57
+ UcpAp2Mandate,
58
+ UcpUnsignedPairing,
59
+ )
60
+ from .bindings.x402_batch_settlement_cloudflare import X402BatchSettlementCloudflare
61
+ from .bindings.x402_batch_settlement_eip155 import X402BatchSettlementEip155
62
+ from .bindings.x402_evm import (
63
+ X402_AUTH_CAPTURE_EIP155_EIP3009,
64
+ X402_AUTH_CAPTURE_EIP155_PERMIT2,
65
+ X402_EXACT_EIP155_ERC7710,
66
+ X402_EXACT_EIP155_ERC7710_SALT,
67
+ X402_EXACT_EIP155_PERMIT2,
68
+ X402_UPTO_EIP155_PERMIT2,
69
+ )
70
+ from .bindings.x402_exact_eip155_eip3009 import X402ExactEip155Eip3009
71
+ from .bindings.mpp_charge_solana import MPP_CHARGE_SOLANA, MPP_CHARGE_USDC_SOLANA
72
+ from .bindings.mpp_session_solana import MPP_SESSION_SOLANA
73
+ from .bindings.x402_batch_settlement_solana import X402BatchSettlementSolana
74
+ from .bindings.x402_exact_solana import X402ExactSolana
75
+ from .bindings.x402_upto_solana import X402UptoSolana
76
+ from .bindings.mpp_charge_hedera import MppChargeHedera
77
+ from .bindings.mpp_session_hedera import MppSessionHedera
78
+ from .bindings.x402_exact_hedera import X402ExactHedera, X402ExactHederaExecutor
79
+ from .bindings.x402_exact_near import X402ExactNear
80
+ from .bindings.x402_exact_tron_lcp_trc20_memo import X402ExactTronLcpTrc20Memo
81
+ from .bindings.x402_exact_tvm import X402ExactTvm
82
+ from .bindings.x402_exact_starknet import X402ExactStarknet
83
+ from .bindings.x402_exact_casper import X402ExactCasper
84
+ from .bindings.x402_exact_aptos import X402ExactAptos
85
+ from .bindings.x402_exact_polkadot_lcp_assets_remark import X402ExactPolkadotLcpAssetsRemark
86
+ from .bindings.x402_exact_ccd import X402ExactCcd
87
+ from .bindings.x402_exact_cardano import X402ExactCardano
88
+ from .bindings.x402_exact_sui import X402ExactSui
89
+ from .bindings.mpp_charge_stellar import MppChargeStellar
90
+ from .bindings.mpp_charge_usdc_stacks import MppChargeUsdcStacks
91
+ from .bindings.mpp_charge_xrpl import MppChargeXrpl
92
+ from .bindings.mpp_session_xrpl import MppSessionXrpl
93
+ from .bindings.x402_exact_algorand import X402ExactAlgorand
94
+ from .bindings.x402_exact_stellar import X402ExactStellar
95
+ from .bindings.x402_exact_xrpl import X402ExactXrpl
96
+
97
+ X402_EXACT_EIP155_EIP3009: Binding = X402ExactEip155Eip3009()
98
+ X402_EXACT_HEDERA: Binding = X402ExactHedera()
99
+ MPP_CHARGE_HEDERA: Binding = MppChargeHedera()
100
+ MPP_SESSION_HEDERA: Binding = MppSessionHedera()
101
+ X402_EXACT_HEDERA_TRANSFER_EXECUTOR: Binding = X402ExactHederaExecutor()
102
+ X402_EXACT_NEAR: Binding = X402ExactNear()
103
+ X402_EXACT_TRON_LCP_TRC20_MEMO: Binding = X402ExactTronLcpTrc20Memo()
104
+ X402_EXACT_TVM: Binding = X402ExactTvm()
105
+ ACK_PAYMENT_REQUEST: Binding = AckPaymentRequest()
106
+ ACP_CHECKOUT_DELEGATED: Binding = AcpCheckoutDelegated()
107
+ ACP_CHECKOUT_UNDELEGATED: Binding = AcpCheckoutUndelegated()
108
+ CARD_VISA_TAP: Binding = CardVisaTap()
109
+ AP2_CHECKOUT_MANDATE: Binding = Ap2CheckoutMandate()
110
+ UCP_CHECKOUT_AP2_MANDATE: Binding = UcpAp2Mandate(CHECKOUT_AP2_MANDATE)
111
+ UCP_CHECKOUT_UNSIGNED: Binding = UcpUnsignedPairing(CHECKOUT_UNSIGNED)
112
+ UCP_BOOKING_AP2_MANDATE: Binding = UcpAp2Mandate(BOOKING_AP2_MANDATE)
113
+ UCP_BOOKING_UNSIGNED: Binding = UcpUnsignedPairing(BOOKING_UNSIGNED)
114
+ X402_EXACT_LNBTC: Binding = X402ExactLnbtc()
115
+ X402_EXACT_LNBTC_INVOICE_NAMED: Binding = X402ExactLnbtcInvoiceNamed()
116
+ MPP_CHARGE_LIGHTNING: Binding = MppLightning(MPP_CHARGE)
117
+ MPP_SESSION_LIGHTNING: Binding = MppLightningSession()
118
+ CARD_MASTERCARD_VI_IMMEDIATE: Binding = CardMastercardViImmediate()
119
+ CARD_MASTERCARD_VI_AUTONOMOUS: Binding = CardMastercardViAutonomous()
120
+ CARD_SELLER_REFERENCE: Binding = CardSellerReference()
121
+ X402_BATCH_SETTLEMENT_EIP155 = X402BatchSettlementEip155()
122
+ X402_BATCH_SETTLEMENT_CLOUDFLARE = X402BatchSettlementCloudflare()
123
+ X402_EXACT_SOLANA: Binding = X402ExactSolana()
124
+ X402_BATCH_SETTLEMENT_SOLANA: Binding = X402BatchSettlementSolana()
125
+ X402_UPTO_SOLANA: Binding = X402UptoSolana()
126
+
127
+ MPP_CHARGE_EVM_AUTHORIZATION: Binding = MppChargeEvmAuthorization()
128
+ MPP_CHARGE_EVM_PERMIT2: Binding = MppChargeEvmPermit2()
129
+ MPP_CHARGE_EVM_TRANSACTION: Binding = MppChargeEvmTransaction()
130
+ MPP_CHARGE_EVM_HASH: Binding = MppChargeEvmHash()
131
+ MPP_CHARGE_CARD: Binding = charge_card()
132
+ MPP_CHARGE_STRIPE: Binding = charge_stripe()
133
+ MPP_SUBSCRIPTION_STRIPE: Binding = subscription_stripe()
134
+ MPP_CHARGE_NEARINTENTS: Binding = MppChargeNearIntents()
135
+ MPP_CHARGE_TEMPO_MEMO: Binding = MppChargeTempoMemo()
136
+ MPP_CHARGE_TEMPO_PUSH: Binding = MppChargeTempoPush()
137
+ MPP_CHARGE_USDC_EVM: Binding = MppChargeUsdcEvm()
138
+ MPP_CHARGE_USDC_GATEWAY: Binding = MppChargeUsdcGateway()
139
+ MPP_SESSION_EVM: Binding = MppSessionEvm()
140
+ MPP_SESSION_TEMPO: Binding = MppSessionTempo()
141
+ MPP_SUBSCRIPTION_TEMPO: Binding = MppSubscriptionTempo()
142
+ X402_EXACT_STARKNET: Binding = X402ExactStarknet()
143
+ X402_EXACT_CASPER: Binding = X402ExactCasper()
144
+ X402_EXACT_APTOS: Binding = X402ExactAptos()
145
+ X402_EXACT_POLKADOT_LCP_ASSETS_REMARK: Binding = X402ExactPolkadotLcpAssetsRemark()
146
+ X402_EXACT_CCD: Binding = X402ExactCcd()
147
+ X402_EXACT_CARDANO: Binding = X402ExactCardano()
148
+ X402_EXACT_SUI: Binding = X402ExactSui()
149
+
150
+ X402_EXACT_XRPL: Binding = X402ExactXrpl()
151
+ X402_EXACT_ALGORAND: Binding = X402ExactAlgorand()
152
+ X402_EXACT_STELLAR: Binding = X402ExactStellar()
153
+ MPP_CHARGE_XRPL: Binding = MppChargeXrpl()
154
+ MPP_CHARGE_STELLAR: Binding = MppChargeStellar()
155
+ MPP_CHARGE_USDC_STACKS: Binding = MppChargeUsdcStacks()
156
+ MPP_SESSION_XRPL: Binding = MppSessionXrpl()
157
+
158
+ __all__ = [
159
+ "ACK_PAYMENT_REQUEST",
160
+ "ACP_CHECKOUT_DELEGATED",
161
+ "ACP_CHECKOUT_UNDELEGATED",
162
+ "AP2_CHECKOUT_MANDATE",
163
+ "CARD_MASTERCARD_VI_AUTONOMOUS",
164
+ "CARD_MASTERCARD_VI_IMMEDIATE",
165
+ "CARD_SELLER_REFERENCE",
166
+ "CARD_VISA_TAP",
167
+ "MAX_ATR_BYTES",
168
+ "MPP_CHARGE_CARD",
169
+ "MPP_CHARGE_EVM_AUTHORIZATION",
170
+ "MPP_CHARGE_EVM_HASH",
171
+ "MPP_CHARGE_EVM_PERMIT2",
172
+ "MPP_CHARGE_EVM_TRANSACTION",
173
+ "MPP_CHARGE_HEDERA",
174
+ "MPP_CHARGE_LIGHTNING",
175
+ "MPP_CHARGE_NEARINTENTS",
176
+ "MPP_CHARGE_SOLANA",
177
+ "MPP_CHARGE_STRIPE",
178
+ "MPP_CHARGE_TEMPO_MEMO",
179
+ "MPP_CHARGE_TEMPO_PUSH",
180
+ "MPP_CHARGE_USDC_EVM",
181
+ "MPP_CHARGE_USDC_GATEWAY",
182
+ "MPP_CHARGE_USDC_SOLANA",
183
+ "MPP_SESSION_EVM",
184
+ "MPP_SESSION_HEDERA",
185
+ "MPP_SESSION_LIGHTNING",
186
+ "MPP_SESSION_SOLANA",
187
+ "MPP_SESSION_TEMPO",
188
+ "MPP_SUBSCRIPTION_STRIPE",
189
+ "MPP_SUBSCRIPTION_TEMPO",
190
+ "UCP_BOOKING_AP2_MANDATE",
191
+ "UCP_BOOKING_UNSIGNED",
192
+ "UCP_CHECKOUT_AP2_MANDATE",
193
+ "UCP_CHECKOUT_UNSIGNED",
194
+ "X402_AUTH_CAPTURE_EIP155_EIP3009",
195
+ "X402_AUTH_CAPTURE_EIP155_PERMIT2",
196
+ "X402_BATCH_SETTLEMENT_CLOUDFLARE",
197
+ "X402_BATCH_SETTLEMENT_EIP155",
198
+ "X402_BATCH_SETTLEMENT_SOLANA",
199
+ "X402_EXACT_APTOS",
200
+ "X402_EXACT_CARDANO",
201
+ "X402_EXACT_CASPER",
202
+ "X402_EXACT_CCD",
203
+ "X402_EXACT_EIP155_EIP3009",
204
+ "X402_EXACT_EIP155_ERC7710",
205
+ "X402_EXACT_EIP155_ERC7710_SALT",
206
+ "X402_EXACT_EIP155_PERMIT2",
207
+ "X402_EXACT_HEDERA",
208
+ "X402_EXACT_HEDERA_TRANSFER_EXECUTOR",
209
+ "X402_EXACT_LNBTC",
210
+ "X402_EXACT_LNBTC_INVOICE_NAMED",
211
+ "X402_EXACT_NEAR",
212
+ "X402_EXACT_POLKADOT_LCP_ASSETS_REMARK",
213
+ "X402_EXACT_SOLANA",
214
+ "X402_EXACT_STARKNET",
215
+ "X402_EXACT_SUI",
216
+ "X402_EXACT_TRON_LCP_TRC20_MEMO",
217
+ "X402_EXACT_TVM",
218
+ "X402_UPTO_EIP155_PERMIT2",
219
+ "X402_UPTO_SOLANA",
220
+ "X402_EXACT_XRPL",
221
+ "X402_EXACT_ALGORAND",
222
+ "X402_EXACT_STELLAR",
223
+ "MPP_CHARGE_XRPL",
224
+ "MPP_CHARGE_STELLAR",
225
+ "MPP_CHARGE_USDC_STACKS",
226
+ "MPP_SESSION_XRPL",
227
+ "Advertised",
228
+ "Agreed",
229
+ "AgreementReceipt",
230
+ "AtrHash",
231
+ "BatchUnsigned",
232
+ "Binding",
233
+ "ChannelHold",
234
+ "ChannelRef",
235
+ "Checked",
236
+ "Chosen",
237
+ "Confirmed",
238
+ "DeclineCode",
239
+ "Declined",
240
+ "Finished",
241
+ "Inputs",
242
+ "Json",
243
+ "Next",
244
+ "Refusal",
245
+ "Signature",
246
+ "Signer",
247
+ "Step",
248
+ "Transacted",
249
+ "Unsigned",
250
+ "Within",
251
+ "agree",
252
+ "atr_hash",
253
+ "check",
254
+ "confirm",
255
+ "finish",
256
+ "hash_equals",
257
+ "open_channel",
258
+ "record_charge",
259
+ "transact",
260
+ "within",
261
+ ]
@@ -0,0 +1,306 @@
1
+ """The agreement payment: ask the agreement URL for its challenge, pay it through the buyer piece of the pairing that
2
+ placed it, a pairing whose payment is itself a public proof of the ATR hash, and return the resource's receipt once the
3
+ payment is recorded. Nothing is signed when the challenge advertises another hash, and nothing is sent unless what was
4
+ signed carries the hash. Once sent, the same signed payment is sent again after each 202, 5xx or timeout, each paid
5
+ request bounded by min(maxTimeoutSeconds, 120) + 60 + 10 seconds and the whole exchange by the agreement option's
6
+ maxTimeoutSeconds + 180 seconds; no second agreement payment is signed, and every decline after it was sent carries it
7
+ as moved."""
8
+
9
+ import asyncio
10
+ import base64
11
+ import binascii
12
+ import json
13
+ import re
14
+ import time
15
+ from collections.abc import Mapping, Sequence
16
+ from dataclasses import dataclass, replace
17
+ from typing import Any
18
+
19
+ import httpx
20
+
21
+ from . import _gate
22
+ from ._core import AtrHash, hash_equals, is_hash
23
+ from .bindings._jose import UNPARSED, parse_json
24
+ from .bindings._lcp import is_https_link, is_other_scheme_link
25
+ from ._types import Advertised, AgreementReceipt, Agreed, Binding, Declined, Inputs, Moved, Refusal, Signer
26
+
27
+ UNPAID_DEADLINE_S = 10.0
28
+ EXCHANGE_CAP_S = 120
29
+ SETTLE_S = 60
30
+ VERIFY_S = 10
31
+ WINDOW_EXTRA_S = 180
32
+ MAX_ANSWER_BYTES = 65_536
33
+ RETRY_DEFAULT_S = 2
34
+ RETRY_MIN_S = 1
35
+
36
+ _DECIMAL = re.compile(r"[0-9]{1,9}")
37
+
38
+
39
+ def _clock() -> float:
40
+ return time.monotonic()
41
+
42
+
43
+ async def _sleep(seconds: float) -> None:
44
+ await asyncio.sleep(seconds)
45
+
46
+
47
+ @dataclass(frozen=True, slots=True)
48
+ class _Answer:
49
+ status: int
50
+ payment_required: str | None
51
+ retry_after: str | None
52
+ body: bytes | None
53
+
54
+
55
+ @dataclass(frozen=True, slots=True)
56
+ class _Unanswered:
57
+ """A request that reached no answer: its deadline passed, or the URL could not be reached."""
58
+
59
+
60
+ def _failed(detail: str, moved: Moved | None = None) -> Declined:
61
+ return Declined("agreement-failed", detail, moved)
62
+
63
+
64
+ def _server_error(status: int) -> bool:
65
+ """A 5xx answer to the paid request, which is read as a timeout: the same payment is sent again."""
66
+ return 500 <= status <= 599
67
+
68
+
69
+ def _to_base64(value: object) -> str:
70
+ """Standard base64 of the UTF-8 bytes of the compact JSON of value."""
71
+ text = json.dumps(value, separators=(",", ":"), ensure_ascii=False)
72
+ return base64.b64encode(text.encode("utf-8")).decode("ascii")
73
+
74
+
75
+ def _from_base64_json(header: str) -> object | None:
76
+ """The JSON value a base64 header carries, or None when it is not base64 of UTF-8 JSON."""
77
+ if len(header) > MAX_ANSWER_BYTES:
78
+ return None
79
+ try:
80
+ loaded: object = parse_json(base64.b64decode(header, validate=True).decode("utf-8"))
81
+ except (binascii.Error, UnicodeDecodeError, ValueError):
82
+ return None
83
+ return None if loaded is UNPARSED else loaded
84
+
85
+
86
+ def _retry_seconds(header: str | None) -> int:
87
+ """retry-after in whole seconds, at least 1; 2 when absent or not a number of seconds."""
88
+ value = header.strip() if header is not None else None
89
+ if value is None or _DECIMAL.fullmatch(value) is None:
90
+ return RETRY_DEFAULT_S
91
+ return max(RETRY_MIN_S, int(value))
92
+
93
+
94
+ async def _get(
95
+ fetch: httpx.AsyncClient, url: str, signature: str | None, seconds: float
96
+ ) -> _Answer | _Unanswered | Declined:
97
+ """One GET of the agreement URL, with no redirect and a deadline of seconds over headers and body. A 200 body is
98
+ read up to 64 KiB; any other body is left unread."""
99
+ headers = None if signature is None else {"PAYMENT-SIGNATURE": signature}
100
+ too_large = _failed("The agreement receipt is larger than 64 KiB.")
101
+ try:
102
+ async with asyncio.timeout(seconds):
103
+ async with fetch.stream("GET", url, headers=headers, follow_redirects=False) as response:
104
+ answer = _Answer(
105
+ status=response.status_code,
106
+ payment_required=response.headers.get("payment-required"),
107
+ retry_after=response.headers.get("retry-after"),
108
+ body=None,
109
+ )
110
+ if response.status_code != 200:
111
+ return answer
112
+ declared = response.headers.get("content-length")
113
+ if declared is not None and declared.strip().isdigit() and int(declared) > MAX_ANSWER_BYTES:
114
+ return too_large
115
+ body = bytearray()
116
+ async for chunk in response.aiter_bytes():
117
+ body += chunk
118
+ if len(body) > MAX_ANSWER_BYTES:
119
+ return too_large
120
+ return replace(answer, body=bytes(body))
121
+ except Exception:
122
+ return _Unanswered()
123
+
124
+
125
+ def _receipt(body: bytes | None, h: AtrHash) -> Agreed | Declined:
126
+ """The receipt a 200 carries, when it is the agreement receipt for h."""
127
+ try:
128
+ parsed: object = parse_json((body or b"").decode("utf-8"))
129
+ except (UnicodeDecodeError, ValueError):
130
+ return _failed("The agreement URL answered 200 without a JSON receipt.")
131
+ if parsed is UNPARSED or not isinstance(parsed, Mapping):
132
+ return _failed("The agreement URL answered 200 without a JSON receipt.")
133
+ atr_hash = parsed.get("atrHash")
134
+ if not isinstance(atr_hash, str) or not is_hash(atr_hash) or not hash_equals(atr_hash, h):
135
+ return _failed("The agreement receipt names another ATR hash.")
136
+ network = parsed.get("network")
137
+ transaction = parsed.get("transaction")
138
+ if parsed.get("agreed") is not True or not isinstance(network, str) or not isinstance(transaction, str):
139
+ return _failed("The agreement receipt is not a recorded agreement.")
140
+ return Agreed(AgreementReceipt(atr_hash=atr_hash, agreed=True, network=network, transaction=transaction))
141
+
142
+
143
+ def _x402_bindings() -> tuple[Binding, ...]:
144
+ """The x402 pairings the gate serves, in the protocol package's order."""
145
+ from . import (
146
+ X402_AUTH_CAPTURE_EIP155_EIP3009,
147
+ X402_AUTH_CAPTURE_EIP155_PERMIT2,
148
+ X402_BATCH_SETTLEMENT_CLOUDFLARE,
149
+ X402_BATCH_SETTLEMENT_EIP155,
150
+ X402_BATCH_SETTLEMENT_SOLANA,
151
+ X402_EXACT_ALGORAND,
152
+ X402_EXACT_APTOS,
153
+ X402_EXACT_CARDANO,
154
+ X402_EXACT_CASPER,
155
+ X402_EXACT_CCD,
156
+ X402_EXACT_EIP155_EIP3009,
157
+ X402_EXACT_EIP155_ERC7710,
158
+ X402_EXACT_EIP155_ERC7710_SALT,
159
+ X402_EXACT_EIP155_PERMIT2,
160
+ X402_EXACT_HEDERA,
161
+ X402_EXACT_HEDERA_TRANSFER_EXECUTOR,
162
+ X402_EXACT_LNBTC,
163
+ X402_EXACT_LNBTC_INVOICE_NAMED,
164
+ X402_EXACT_NEAR,
165
+ X402_EXACT_POLKADOT_LCP_ASSETS_REMARK,
166
+ X402_EXACT_SOLANA,
167
+ X402_EXACT_STARKNET,
168
+ X402_EXACT_STELLAR,
169
+ X402_EXACT_SUI,
170
+ X402_EXACT_TRON_LCP_TRC20_MEMO,
171
+ X402_EXACT_TVM,
172
+ X402_EXACT_XRPL,
173
+ X402_UPTO_EIP155_PERMIT2,
174
+ X402_UPTO_SOLANA,
175
+ )
176
+
177
+ return (
178
+ X402_EXACT_EIP155_EIP3009,
179
+ X402_AUTH_CAPTURE_EIP155_EIP3009,
180
+ X402_AUTH_CAPTURE_EIP155_PERMIT2,
181
+ X402_BATCH_SETTLEMENT_CLOUDFLARE,
182
+ X402_BATCH_SETTLEMENT_EIP155,
183
+ X402_BATCH_SETTLEMENT_SOLANA,
184
+ X402_EXACT_ALGORAND,
185
+ X402_EXACT_APTOS,
186
+ X402_EXACT_CARDANO,
187
+ X402_EXACT_CASPER,
188
+ X402_EXACT_CCD,
189
+ X402_EXACT_EIP155_ERC7710,
190
+ X402_EXACT_EIP155_ERC7710_SALT,
191
+ X402_EXACT_EIP155_PERMIT2,
192
+ X402_EXACT_HEDERA,
193
+ X402_EXACT_HEDERA_TRANSFER_EXECUTOR,
194
+ X402_EXACT_LNBTC,
195
+ X402_EXACT_LNBTC_INVOICE_NAMED,
196
+ X402_EXACT_NEAR,
197
+ X402_EXACT_POLKADOT_LCP_ASSETS_REMARK,
198
+ X402_EXACT_SOLANA,
199
+ X402_EXACT_STARKNET,
200
+ X402_EXACT_STELLAR,
201
+ X402_EXACT_SUI,
202
+ X402_EXACT_TRON_LCP_TRC20_MEMO,
203
+ X402_EXACT_TVM,
204
+ X402_EXACT_XRPL,
205
+ X402_UPTO_EIP155_PERMIT2,
206
+ X402_UPTO_SOLANA,
207
+ )
208
+
209
+
210
+ def _agreement_pairing(required: Mapping[str, Any]) -> tuple[Binding, Advertised, Mapping[str, Any]] | Declined:
211
+ """The pairing that placed the agreement option, when its payment is itself a public proof, with its read and the
212
+ option."""
213
+ accepts = required.get("accepts")
214
+ if not isinstance(accepts, Sequence) or isinstance(accepts, str) or not accepts or not isinstance(accepts[0], Mapping):
215
+ return Declined("offer-unreadable", "x402/no-payable-option")
216
+ for binding in _x402_bindings():
217
+ try:
218
+ read = binding.read(required)
219
+ except Exception:
220
+ continue
221
+ if isinstance(read, Advertised):
222
+ if getattr(binding, "public_proof", False) is not True:
223
+ return Declined("pairing-not-supported", f"The agreement pairing {binding.id} is not itself a public proof.")
224
+ return binding, read, accepts[0]
225
+ return Declined("pairing-not-supported", "The agreement option names no pairing the gate serves.")
226
+
227
+
228
+ def _bounds(option: Mapping[str, Any]) -> tuple[int, int] | None:
229
+ """The paid request's deadline and the whole exchange's, in seconds, from the option's maxTimeoutSeconds."""
230
+ t = option.get("maxTimeoutSeconds")
231
+ if isinstance(t, bool) or not isinstance(t, int) or t <= 0 or t > 2**53 - 1:
232
+ return None
233
+ return min(t, EXCHANGE_CAP_S) + SETTLE_S + VERIFY_S, t + WINDOW_EXTRA_S
234
+
235
+
236
+ async def agree(
237
+ h: AtrHash,
238
+ url: str,
239
+ signer: Signer,
240
+ fetch: httpx.AsyncClient,
241
+ *,
242
+ atr_bytes: bytes,
243
+ inputs: Inputs | None = None,
244
+ ns: str | None = None,
245
+ ) -> Agreed | Declined:
246
+ """Pay the agreement for h at url with signer, and return its receipt once recorded. atr_bytes are the ATR the
247
+ gate compared, for a pairing whose build reads them; inputs are the buyer's own chain values; ns is the namespace
248
+ of the pairing whose offer named the URL, which a refused URL's detail carries with the protocol package's code."""
249
+ if not is_https_link(url):
250
+ if ns is None:
251
+ return Declined("link-not-https", "The agreement URL is not an https URL.")
252
+ fault = "link-not-https" if is_other_scheme_link(url) else "legal-context-malformed"
253
+ return Declined("link-not-https", f"{ns}/{fault}")
254
+
255
+ unpaid = await _get(fetch, url, None, UNPAID_DEADLINE_S)
256
+ if isinstance(unpaid, Declined):
257
+ return unpaid
258
+ if isinstance(unpaid, _Unanswered):
259
+ return _failed("The agreement URL could not be reached.")
260
+ if unpaid.status == 200:
261
+ return _receipt(unpaid.body, h)
262
+ if unpaid.status == 202:
263
+ return Declined("agreement-pending", "An agreement payment for this ATR is already settling.")
264
+ if unpaid.status != 402:
265
+ return _failed(f"The agreement URL answered status {unpaid.status}.")
266
+
267
+ required = None if unpaid.payment_required is None else _from_base64_json(unpaid.payment_required)
268
+ if not isinstance(required, Mapping):
269
+ return _failed("The agreement URL answered 402 without a readable PAYMENT-REQUIRED.")
270
+ found = _agreement_pairing(required)
271
+ if isinstance(found, Declined):
272
+ return found
273
+ binding, read, option = found
274
+ limits = _bounds(option)
275
+ if limits is None:
276
+ return Declined("offer-unreadable", "x402/option-malformed")
277
+ if not hash_equals(read.h, h):
278
+ return Declined("hash-mismatch", "The agreement challenge advertises another ATR hash.")
279
+
280
+ paid = await _gate.pay(binding, read, required, signer, inputs if isinstance(inputs, Mapping) else {}, atr_bytes)
281
+ if isinstance(paid, Declined):
282
+ return paid
283
+ if paid is None:
284
+ return Declined("offer-unreadable", "The agreement payment gave nothing to sign.")
285
+ payment = _to_base64(paid.signed)
286
+ moved = Moved(paid.signed, atr_bytes, h)
287
+ pending = Declined("agreement-pending", "The agreement payment was sent and is not yet recorded.", moved)
288
+
289
+ request_s, exchange_s = limits
290
+ end = _clock() + exchange_s
291
+ while True:
292
+ remaining = end - _clock()
293
+ if remaining <= 0:
294
+ return pending
295
+ answer = await _get(fetch, url, payment, min(request_s, remaining))
296
+ if isinstance(answer, Declined):
297
+ return replace(answer, moved=moved)
298
+ wait = float(RETRY_DEFAULT_S)
299
+ if isinstance(answer, _Answer) and not _server_error(answer.status):
300
+ if answer.status == 200:
301
+ receipt = _receipt(answer.body, h)
302
+ return replace(receipt, moved=moved) if isinstance(receipt, Declined) else receipt
303
+ if answer.status != 202:
304
+ return _failed(f"The agreement URL answered status {answer.status} to the payment.", moved)
305
+ wait = float(_retry_seconds(answer.retry_after))
306
+ await _sleep(max(0.0, min(wait, end - _clock())))