mech-client 0.14.1__py3-none-any.whl → 0.15.1__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 (49) hide show
  1. mech_client/__init__.py +1 -1
  2. mech_client/cli.py +258 -11
  3. mech_client/configs/mechs.json +110 -110
  4. mech_client/interact.py +6 -1
  5. mech_client/marketplace_interact.py +160 -42
  6. mech_client/safe.py +73 -0
  7. mech_client/subgraph.py +0 -11
  8. {mech_client-0.14.1.dist-info → mech_client-0.15.1.dist-info}/METADATA +278 -224
  9. {mech_client-0.14.1.dist-info → mech_client-0.15.1.dist-info}/RECORD +22 -48
  10. scripts/deposit_native.py +48 -16
  11. scripts/deposit_token.py +107 -31
  12. scripts/nvm_subscribe.py +14 -6
  13. scripts/nvm_subscription/contracts/base_contract.py +9 -1
  14. scripts/nvm_subscription/contracts/nft_sales.py +1 -3
  15. scripts/nvm_subscription/contracts/subscription_provider.py +2 -4
  16. scripts/nvm_subscription/contracts/token.py +23 -5
  17. scripts/nvm_subscription/manager.py +109 -16
  18. scripts/utils.py +2 -2
  19. scripts/whitelist.py +5 -1
  20. mech_client/helpers/acn/README.md +0 -76
  21. mech_client/helpers/acn/__init__.py +0 -30
  22. mech_client/helpers/acn/acn.proto +0 -71
  23. mech_client/helpers/acn/acn_pb2.py +0 -42
  24. mech_client/helpers/acn/custom_types.py +0 -224
  25. mech_client/helpers/acn/dialogues.py +0 -126
  26. mech_client/helpers/acn/message.py +0 -274
  27. mech_client/helpers/acn/protocol.yaml +0 -24
  28. mech_client/helpers/acn/serialization.py +0 -149
  29. mech_client/helpers/acn/tests/__init__.py +0 -20
  30. mech_client/helpers/acn/tests/test_acn.py +0 -256
  31. mech_client/helpers/acn/tests/test_acn_dialogues.py +0 -53
  32. mech_client/helpers/acn/tests/test_acn_messages.py +0 -117
  33. mech_client/helpers/acn_data_share/README.md +0 -32
  34. mech_client/helpers/acn_data_share/__init__.py +0 -32
  35. mech_client/helpers/acn_data_share/acn_data_share.proto +0 -17
  36. mech_client/helpers/acn_data_share/acn_data_share_pb2.py +0 -29
  37. mech_client/helpers/acn_data_share/dialogues.py +0 -115
  38. mech_client/helpers/acn_data_share/message.py +0 -213
  39. mech_client/helpers/acn_data_share/protocol.yaml +0 -21
  40. mech_client/helpers/acn_data_share/serialization.py +0 -111
  41. mech_client/helpers/acn_data_share/tests/test_acn_data_share_dialogues.py +0 -49
  42. mech_client/helpers/acn_data_share/tests/test_acn_data_share_messages.py +0 -53
  43. mech_client/helpers/p2p_libp2p_client/README.md +0 -15
  44. mech_client/helpers/p2p_libp2p_client/__init__.py +0 -21
  45. mech_client/helpers/p2p_libp2p_client/connection.py +0 -703
  46. mech_client/helpers/p2p_libp2p_client/connection.yaml +0 -52
  47. {mech_client-0.14.1.dist-info → mech_client-0.15.1.dist-info}/LICENSE +0 -0
  48. {mech_client-0.14.1.dist-info → mech_client-0.15.1.dist-info}/WHEEL +0 -0
  49. {mech_client-0.14.1.dist-info → mech_client-0.15.1.dist-info}/entry_points.txt +0 -0
@@ -1,4 +1,4 @@
1
- mech_client/__init__.py,sha256=qXP3KYo0kVvrn4GI8u6T0gw5y9DiN6Ryz_hOfpB6RIE,43
1
+ mech_client/__init__.py,sha256=Iu9RKNRKh9xSx9NxEMVPqWsKtDpP6qgpMbbJeGBd7V8,43
2
2
  mech_client/abis/AgentMech.json,sha256=IEbs_xBGunBu5h-uT5DvIty8Zw412QoPI46S_DUMYNw,18082
3
3
  mech_client/abis/AgentRegistry.json,sha256=2qmXeFINZWz9pyOma6Bq67kMDSUI1lD7WvgHLwuETD8,24723
4
4
  mech_client/abis/AgreementStoreManager.base.json,sha256=_ljdIZcfFGmFzBHUTfhA4X0382ZHHpkdr_CziTwUETo,34360
@@ -30,72 +30,46 @@ mech_client/abis/SubscriptionToken.base.json,sha256=5StPEyfRvDMTqtQPO-KakXXZqobX
30
30
  mech_client/abis/TransferNFTCondition.base.json,sha256=71O_3itHBz9qPtoTLev8_a7KxlcQfIZSfxK2562lkqw,42540
31
31
  mech_client/abis/TransferNFTCondition.gnosis.json,sha256=-huhxV54eoNY8mR9WtQdmSgQDgaKiUi0PULJ4HEshWw,42540
32
32
  mech_client/acn.py,sha256=Rj_jLPvJ5loDQfGbu3a_O24cJC4SwIErLceSz_zVYS8,5356
33
- mech_client/cli.py,sha256=pDyWyx47X_-j1HFkp7yL627RE5W2-zqClciA5amV7bE,19275
34
- mech_client/configs/mechs.json,sha256=P27UibjGSlmRt199AEWi2xBHrjCnSk6p7KSbZ9nRSiY,5601
33
+ mech_client/cli.py,sha256=4atyFMnVqN0TqczoI935hQKOD500ktt2dztUMFUPH8U,27631
34
+ mech_client/configs/mechs.json,sha256=eR0yoNNtGozNB0w4KMx9E9dxM-zI10EhDSKnBuw8nP0,5099
35
35
  mech_client/delivery.py,sha256=PU_qSzP5juDRHiKQsyg6TH9oacc8nRoRY9BQBBe_fW0,5588
36
36
  mech_client/fetch_ipfs_hash.py,sha256=tg_hYVf4deXl89x3SOBrGFUthaSeN_Vg_OHDtfjdbp4,2752
37
37
  mech_client/helpers/__init__.py,sha256=nmQig1EqBQ9EMOpgdykP3a6_2NWcoVH3-lnyHP5n0ws,1196
38
- mech_client/helpers/acn/README.md,sha256=WMXR2Lk0IpWjr3vpZ8cxcTHk4gwsx4wC06UPkwj9dbQ,1641
39
- mech_client/helpers/acn/__init__.py,sha256=3Yd1hUTcrtp0Kb1VmnOTC3_r-_69ozhzMqLlkNC6MkU,1141
40
- mech_client/helpers/acn/acn.proto,sha256=Ev0f8tQJjnTaK-mdpNLItVRgJ7VibtCeGBTcKz8nfX4,1543
41
- mech_client/helpers/acn/acn_pb2.py,sha256=NnS-rspsKz9ImoLWp8P9FSBNwGJYuj1mRCw8A1bHydQ,4350
42
- mech_client/helpers/acn/custom_types.py,sha256=x2YMQuxd86QDjkCr__SuhcDmlGP8qI-qJRg1XqIlBRw,7982
43
- mech_client/helpers/acn/dialogues.py,sha256=44IExYaKk9zxeu0L6G5grUUX62Px6Lv0Kfp8u56-uJs,4443
44
- mech_client/helpers/acn/message.py,sha256=d918VwybycjtwplngmPV-xbSRmgSwEHYFZnpC3xZz10,10272
45
- mech_client/helpers/acn/protocol.yaml,sha256=nA6sZ48dPR_3cmRb5BuaQbhHFA9uJkMlTnGmz9bbV_0,1233
46
- mech_client/helpers/acn/serialization.py,sha256=3vccK7L4i8ybtgYAUO7N550_6lTBV10EsT26qmCd2lM,6592
47
- mech_client/helpers/acn/tests/__init__.py,sha256=rIdXnZmrjQFe_nuseQ8CIOIELdYDihx9MNQehcbenYw,847
48
- mech_client/helpers/acn/tests/test_acn.py,sha256=wM1SZ4iW20PFNu-491KUFyuvICDM_EkjNLZxzguqO5w,8965
49
- mech_client/helpers/acn/tests/test_acn_dialogues.py,sha256=HWW7KO78lYzTEwMxFzOpdRh2LUaiBtrpUsjG3jfKuU8,1964
50
- mech_client/helpers/acn/tests/test_acn_messages.py,sha256=aMESOF6vsIBNDcMRbptZNiToluMyVF-0MhPa8X5H1Go,4332
51
- mech_client/helpers/acn_data_share/README.md,sha256=LpamqskB0GnXpt_JhxPmtoN7FNejpUcrNxK2RSDAzew,577
52
- mech_client/helpers/acn_data_share/__init__.py,sha256=vI8z6p5Y2EBCzliS8mWYAskAqGeX5BoZogOATuXzZnE,1219
53
- mech_client/helpers/acn_data_share/acn_data_share.proto,sha256=um_1JPkgwwKO-3OILxpokpZ8nXcyjCNIuU0I9t2Tziw,271
54
- mech_client/helpers/acn_data_share/acn_data_share_pb2.py,sha256=E_X7d4q8P3P4aEqvKEYcCaEcpK7HL533rjn9auNw4Jo,1475
55
- mech_client/helpers/acn_data_share/dialogues.py,sha256=_FnqWAW2ijPq6PBpq5EIwNx0EB9hIbCH-2k1eL5IufM,4078
56
- mech_client/helpers/acn_data_share/message.py,sha256=57k0dKwKA0zGZw9MJkyHywdNhfCy0egN_lagRUZen_U,7742
57
- mech_client/helpers/acn_data_share/protocol.yaml,sha256=vcxMleXQcIx_q-5mW4hR3LIYF_sTVOt4XT-LhwWxBeM,1052
58
- mech_client/helpers/acn_data_share/serialization.py,sha256=uctnEpdnXLl5VsJjiS0AanPzYzC53cjollFJyjHXyL4,4617
59
- mech_client/helpers/acn_data_share/tests/test_acn_data_share_dialogues.py,sha256=3bbX52BLXMMxEOLWpq3iC9KL4eCy_qLxzTFlHWZzNm0,1835
60
- mech_client/helpers/acn_data_share/tests/test_acn_data_share_messages.py,sha256=j5H8SRCWh8hR_q5cTPTm7Q_l4L1uiuEUcTgpWDj-fTI,2021
61
- mech_client/helpers/p2p_libp2p_client/README.md,sha256=6x9s6P7TdKkcvAS1wMFHXRz4aIaLZhyi0OnUgbEvpKM,631
62
- mech_client/helpers/p2p_libp2p_client/__init__.py,sha256=-GOP3D_JnmXTDomrMLCbnRk7vRQmihIqTYvyIPzx-q4,879
63
- mech_client/helpers/p2p_libp2p_client/connection.py,sha256=b5jfcUeSoNrUw8DOSTCbK4DTi-N8bf2_pdogUOz0ep0,28606
64
- mech_client/helpers/p2p_libp2p_client/connection.yaml,sha256=nMiHnU_dv9EFjVNqZ-0SAnoATfadJSad-JsbDvk97Mk,1790
65
- mech_client/interact.py,sha256=YvqUppI3m8hXbEfGLvWc05taYOINk0h02MfCgSuAT1A,21126
66
- mech_client/marketplace_interact.py,sha256=h7_71joPy-dDG36MYIT9L4COkbevlo2BTXiN25NesoM,35934
38
+ mech_client/interact.py,sha256=yj9pBM6PcgoalNTkdECdsvD1X5CJjffu0vnQePFCHjk,21347
39
+ mech_client/marketplace_interact.py,sha256=LIXz9_hHM_6PRo_PTWAKplWlkdR6cNA22HRv7qTyzM4,41048
67
40
  mech_client/mech_marketplace_subgraph.py,sha256=X_ypxfokN-YBtsUCVOHUecsinkbRDZ5fR5WCkid1ntM,3153
68
41
  mech_client/mech_marketplace_tool_management.py,sha256=G1O0ajbeltRM5FpqPfmn2C4QRrwqf5HfWKUH2VKn6UA,7365
69
42
  mech_client/mech_tool_management.py,sha256=NQFmVzzGZsIkeHokDPWXGHwa8u-pyQIMPR1Q5H81bKw,7806
70
43
  mech_client/prompt_to_ipfs.py,sha256=XqSIBko15MEkpWOQNT97fRI6jNxMF5EDBDEPOJFdhyk,2533
71
44
  mech_client/push_to_ipfs.py,sha256=IfvgaPU79N_ZmCPF9d7sPCYz2uduZH0KjT_HQ2LHXoQ,2059
72
- mech_client/subgraph.py,sha256=UjQRa2wjCDac8XbOhe-JtB9Wyu4vr5D45mATFTNaAR4,2403
45
+ mech_client/safe.py,sha256=kn28VpgIKRZfo2BvHobkaAPIu1QJMq34GxOipxBJj1w,2420
46
+ mech_client/subgraph.py,sha256=Zv1OqauTyeSJhTgmYAVvdzo3gd3WvhI6XZt2uFC9jPs,1833
73
47
  mech_client/to_png.py,sha256=pjUcFJ63MJj_r73eqnfqCWMtlpsrj6H4ZmgvIEmRcFw,2581
74
48
  mech_client/wss.py,sha256=NoWAzvAjzbnPX9aeLkdiRKGjIX4rptyhcnZyRxCqV_8,8097
75
49
  scripts/__init__.py,sha256=I8VcZ7sjlAw171Er7B6mumpMLfrynrWie4YoeJIayno,26
76
50
  scripts/benchmark.sh,sha256=qgfYEI5u8Qd-vqaD3xZktuubXyz0sdHE1_9qg6stEzs,935
77
51
  scripts/bump.py,sha256=2o4MsFGG_ix4UXscekfX7dqpM-q-T4mTwkHw_KtA8mk,9503
78
- scripts/deposit_native.py,sha256=A66o74w7Mg9VS7uh3xWGg6gu3x6iE9tyHUbhl1usmjw,3902
79
- scripts/deposit_token.py,sha256=PGJszulGTk4utrKIhqtaiP_yKzs8nV9inNAHSUdvxtM,6067
80
- scripts/nvm_subscribe.py,sha256=N3I9r9ugTf_HMfQSAGeKq0TcInJsWI8rYQVF57AmmFM,1473
52
+ scripts/deposit_native.py,sha256=lF8XMvpBo3Z--bR0FOk8fb1SFAgO6FXND5sNg-VK6uU,4850
53
+ scripts/deposit_token.py,sha256=fHOjvR5byIolpexmM9BxQHP889K5Dxp2pv7wdNnlUyY,8810
54
+ scripts/nvm_subscribe.py,sha256=Cnyq2XIoOkR3djIQwXj6WHKXMBWeNVVwl1ET5y4t5bk,1846
81
55
  scripts/nvm_subscription/contracts/agreement_manager.py,sha256=JFP5YJTbo_1liZTBmnkvHtRm-0Dfmp-gyRkXHPdzPG8,1466
82
- scripts/nvm_subscription/contracts/base_contract.py,sha256=DR_GfPZo9i47o3AYAxGR6hjc0KhHQY1dJ2yRXJ8I9DE,2868
56
+ scripts/nvm_subscription/contracts/base_contract.py,sha256=CfifvIsZaaR1rElv2CbB24LUEecw60iGNzo8MNITrJM,3120
83
57
  scripts/nvm_subscription/contracts/did_registry.py,sha256=yoWp2V29qFozgGsndKiExpF-yQ13TfCZmGGWb1DRmS8,3108
84
58
  scripts/nvm_subscription/contracts/escrow_payment.py,sha256=7B-TdZYq9ELj58jWhD-2RcdGg-pYWYxuRnhQXx6K9TA,2856
85
59
  scripts/nvm_subscription/contracts/lock_payment.py,sha256=_nRRkjnHgThSqAQ91bIwGq18yvWVPItAY2JfEz8aWOk,2556
86
60
  scripts/nvm_subscription/contracts/nft.py,sha256=NOOCNcPd0fP7gtShH1fECpSR_hUBcihIcoEaEj8tZN4,1287
87
- scripts/nvm_subscription/contracts/nft_sales.py,sha256=pjCrAgebDL7pet3gxL5TjkPRUwZGu1S95SGILJ2wiKk,4700
88
- scripts/nvm_subscription/contracts/subscription_provider.py,sha256=cVjoZ4yEKR8mJOFYrlsKrVD_A18i6qplGgvw3cKwh5E,3981
89
- scripts/nvm_subscription/contracts/token.py,sha256=NrVnxlcP2J0QyiuPbVIoeSEPHEEUU0IXTmC6AYc1i7w,2728
61
+ scripts/nvm_subscription/contracts/nft_sales.py,sha256=qGd6B6gN2zKl8fQXpSBUb_74FrtgBkAFq1KEqQETaqU,4587
62
+ scripts/nvm_subscription/contracts/subscription_provider.py,sha256=jdFxmqN_KsZreb0LRnmGCN6T4OrTCdlJoWsJYMkId9M,3864
63
+ scripts/nvm_subscription/contracts/token.py,sha256=SQmNLJzhcmNJRQ7A4-ZpN1ThPxOClDwsNRfFIMiw_JM,3164
90
64
  scripts/nvm_subscription/contracts/transfer_nft.py,sha256=Z3IlfBYVQLT4WhI5cszruHCKBrwQGTBuZrlQQcuEN3s,2681
91
65
  scripts/nvm_subscription/envs/base.env,sha256=mI2loQ5Dt-rkZzuzmgyNiV-fUutwN89kOsEmygG4K78,528
92
66
  scripts/nvm_subscription/envs/gnosis.env,sha256=mDCb1wEY4fRQYJQuyqg2b4qTFQtHHopRaKYCXTCeACM,554
93
- scripts/nvm_subscription/manager.py,sha256=y0Qh0aVAmOPB4Ytt93alIarSvhrQpC-lRYNAY09GRZ0,10054
67
+ scripts/nvm_subscription/manager.py,sha256=Ibx_QN8IzkbDGlqHutADl5Wj2a92FOQeXaxSRIoK4MA,13600
94
68
  scripts/nvm_subscription/resources/networks.json,sha256=xH0P3YkgkMTkQdahVKO0kI9m6ybJ67iwHApstUlfRmw,2359
95
- scripts/utils.py,sha256=lXjY3s1HvNHT2fXm2fBpZtVvlQaqW288Y2S-s3rpSDM,3248
96
- scripts/whitelist.py,sha256=uWgX2E19_NS1rK3QfxSyata4ZLIqGVZAKrX8zXpuk_g,448
97
- mech_client-0.14.1.dist-info/LICENSE,sha256=mdBDB-mWKV5Cz4ejBzBiKqan6Z8zVLAh9xwM64O2FW4,11339
98
- mech_client-0.14.1.dist-info/METADATA,sha256=BSNMj9w5rxKExrNp8yFucgnCW4KIS4meMfYvv10_uM0,29678
99
- mech_client-0.14.1.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
100
- mech_client-0.14.1.dist-info/entry_points.txt,sha256=SbRMRsayzD8XfNXhgwPuXEqQsdZ5Bw9XDPnUuaDExyY,45
101
- mech_client-0.14.1.dist-info/RECORD,,
69
+ scripts/utils.py,sha256=bbupA1PwBbVlMRojCFXEvj20eGAZ37PYRM2XsiwT85U,3332
70
+ scripts/whitelist.py,sha256=7PDGrl5GADe6kphxAH02oR5xalYYQovUfBz-xPjUnxw,604
71
+ mech_client-0.15.1.dist-info/LICENSE,sha256=mdBDB-mWKV5Cz4ejBzBiKqan6Z8zVLAh9xwM64O2FW4,11339
72
+ mech_client-0.15.1.dist-info/METADATA,sha256=NrLR6xHEj9ICvf0tZbQsQswFHI-N88UVYKN0XEymB0I,31133
73
+ mech_client-0.15.1.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
74
+ mech_client-0.15.1.dist-info/entry_points.txt,sha256=SbRMRsayzD8XfNXhgwPuXEqQsdZ5Bw9XDPnUuaDExyY,45
75
+ mech_client-0.15.1.dist-info/RECORD,,
scripts/deposit_native.py CHANGED
@@ -30,15 +30,19 @@ from .utils import (
30
30
  CHAIN_TO_NATIVE_BALANCE_TRACKER,
31
31
  )
32
32
  from mech_client.wss import wait_for_receipt
33
+ from mech_client.safe import send_safe_tx, EthereumClient
33
34
 
34
35
 
35
36
  def deposit(
36
37
  ledger_api: EthereumApi,
37
38
  crypto: EthereumCrypto,
39
+ ethereum_client: EthereumClient,
40
+ agent_mode: bool,
41
+ safe_address: Optional[str],
38
42
  to: str,
39
43
  amount: int,
40
44
  ) -> str:
41
- sender = crypto.address
45
+ sender = safe_address or crypto.address
42
46
 
43
47
  try:
44
48
  print("Fetching user balance")
@@ -56,27 +60,42 @@ def deposit(
56
60
 
57
61
  try:
58
62
  print("Sending deposit tx")
59
- raw_transaction = ledger_api.get_transfer_transaction(
60
- sender_address=sender,
61
- destination_address=to,
62
- amount=amount,
63
- tx_fee=50000,
64
- tx_nonce="0x",
63
+ if not agent_mode:
64
+ raw_transaction = ledger_api.get_transfer_transaction(
65
+ sender_address=sender,
66
+ destination_address=to,
67
+ amount=amount,
68
+ tx_fee=50000,
69
+ tx_nonce="0x",
70
+ )
71
+ signed_transaction = crypto.sign_transaction(raw_transaction)
72
+ transaction_digest = ledger_api.send_signed_transaction(
73
+ signed_transaction,
74
+ raise_on_try=True,
75
+ )
76
+ return transaction_digest
77
+
78
+ transaction_digest = send_safe_tx(
79
+ ethereum_client=ethereum_client,
80
+ tx_data="0x",
81
+ to_adress=to,
82
+ safe_address=str(safe_address),
83
+ signer_pkey=crypto.private_key,
84
+ value=amount,
65
85
  )
66
- signed_transaction = crypto.sign_transaction(raw_transaction)
67
- transaction_digest = ledger_api.send_signed_transaction(
68
- signed_transaction,
69
- raise_on_try=True,
70
- )
71
- return transaction_digest
86
+ return transaction_digest.hex()
87
+
72
88
  except Exception as e: # pylint: disable=broad-except
73
89
  print(f"Error occured while sending the transaction: {e}")
74
90
  return str(e)
75
91
 
76
92
 
77
93
  def main(
94
+ agent_mode: bool,
78
95
  amount: str,
96
+ safe_address: Optional[str] = None,
79
97
  private_key_path: Optional[str] = None,
98
+ private_key_password: Optional[str] = None,
80
99
  chain_config: Optional[str] = None,
81
100
  ) -> None:
82
101
  """Runs the deposit functionality for the native mech type"""
@@ -88,6 +107,8 @@ def main(
88
107
  private_key_path = private_key_path or PRIVATE_KEY_FILE_PATH
89
108
 
90
109
  mech_config = get_mech_config(chain_config)
110
+ ledger_rpc = mech_config.ledger_config.address
111
+ ethereum_client = EthereumClient(ledger_rpc)
91
112
  ledger_config = mech_config.ledger_config
92
113
  ledger_api = EthereumApi(**asdict(ledger_config))
93
114
 
@@ -95,14 +116,25 @@ def main(
95
116
  raise FileNotFoundError(
96
117
  f"Private key file `{private_key_path}` does not exist!"
97
118
  )
98
- crypto = EthereumCrypto(private_key_path=private_key_path)
119
+ crypto = EthereumCrypto(
120
+ private_key_path=private_key_path, password=private_key_password
121
+ )
99
122
 
100
- print(f"Sender address: {crypto.address}")
123
+ sender = safe_address or crypto.address
124
+ print(f"Sender address: {sender}")
101
125
 
102
126
  chain_id = mech_config.ledger_config.chain_id
103
127
  to = CHAIN_TO_NATIVE_BALANCE_TRACKER[chain_id]
104
128
 
105
- deposit_tx = deposit(ledger_api, crypto, to, amount_to_deposit)
129
+ deposit_tx = deposit(
130
+ ledger_api,
131
+ crypto,
132
+ ethereum_client,
133
+ agent_mode,
134
+ safe_address,
135
+ to,
136
+ amount_to_deposit,
137
+ )
106
138
  if not deposit_tx:
107
139
  print("Unable to deposit")
108
140
  sys.exit(1)
scripts/deposit_token.py CHANGED
@@ -36,6 +36,7 @@ from .utils import (
36
36
  get_token_balance_tracker_contract,
37
37
  )
38
38
  from mech_client.wss import wait_for_receipt
39
+ from mech_client.safe import get_safe_nonce, send_safe_tx, EthereumClient
39
40
 
40
41
 
41
42
  def check_token_balance(token_contract: Web3Contract, sender: str, amount: int) -> None:
@@ -56,31 +57,62 @@ def check_token_balance(token_contract: Web3Contract, sender: str, amount: int)
56
57
  def approve(
57
58
  crypto: EthereumCrypto,
58
59
  ledger_api: EthereumApi,
60
+ ethereum_client: EthereumClient,
61
+ agent_mode: bool,
62
+ safe_address: Optional[str],
59
63
  token_contract: Web3Contract,
60
64
  token_balance_tracker_contract: Web3Contract,
61
65
  amount: int,
62
66
  ) -> str:
63
- sender = crypto.address
67
+ # Tokens will be on the safe and EOA pays for gas
68
+ # so for agent mode, sender has to be safe
69
+ sender = safe_address or crypto.address
64
70
 
65
71
  print("Sending approve tx")
66
72
  try:
67
73
  tx_args = {"sender_address": sender, "value": 0, "gas": 60000}
68
- raw_transaction = ledger_api.build_transaction(
69
- contract_instance=token_contract,
70
- method_name="approve",
71
- method_args={
72
- "_to": token_balance_tracker_contract.address,
73
- "_value": amount,
74
- },
75
- tx_args=tx_args,
76
- raise_on_try=True,
74
+ method_name = "approve"
75
+ method_args = {
76
+ "_to": token_balance_tracker_contract.address,
77
+ "_value": amount,
78
+ }
79
+
80
+ if not agent_mode:
81
+ raw_transaction = ledger_api.build_transaction(
82
+ contract_instance=token_contract,
83
+ method_name="approve",
84
+ method_args={
85
+ "_to": token_balance_tracker_contract.address,
86
+ "_value": amount,
87
+ },
88
+ tx_args=tx_args,
89
+ raise_on_try=True,
90
+ )
91
+ signed_transaction = crypto.sign_transaction(raw_transaction)
92
+ transaction_digest = ledger_api.send_signed_transaction(
93
+ signed_transaction,
94
+ raise_on_try=True,
95
+ )
96
+ return transaction_digest
97
+
98
+ function = token_contract.functions[method_name](**method_args)
99
+ transaction = function.build_transaction(
100
+ {
101
+ "chainId": int(ledger_api._chain_id),
102
+ "gas": 0,
103
+ "nonce": get_safe_nonce(ethereum_client, str(safe_address)),
104
+ }
77
105
  )
78
- signed_transaction = crypto.sign_transaction(raw_transaction)
79
- transaction_digest = ledger_api.send_signed_transaction(
80
- signed_transaction,
81
- raise_on_try=True,
106
+ transaction_digest = send_safe_tx(
107
+ ethereum_client=ethereum_client,
108
+ tx_data=transaction["data"],
109
+ to_adress=token_contract.address,
110
+ safe_address=str(safe_address),
111
+ signer_pkey=crypto.private_key,
112
+ value=0,
82
113
  )
83
- return transaction_digest
114
+ return transaction_digest.hex()
115
+
84
116
  except Exception as e: # pylint: disable=broad-except
85
117
  print(f"Error occured while sending the transaction: {e}")
86
118
  return str(e)
@@ -89,35 +121,66 @@ def approve(
89
121
  def deposit(
90
122
  ledger_api: EthereumApi,
91
123
  crypto: EthereumCrypto,
124
+ ethereum_client: EthereumClient,
125
+ agent_mode: bool,
126
+ safe_address: Optional[str],
92
127
  token_balance_tracker_contract: Web3Contract,
93
128
  amount: int,
94
129
  ) -> str:
95
- sender = crypto.address
130
+ # Tokens will be on the safe and EOA pays for gas
131
+ # so for agent mode, sender has to be safe
132
+ sender = safe_address or crypto.address
96
133
 
97
134
  print("Sending deposit tx")
98
135
  try:
99
136
  tx_args = {"sender_address": sender, "value": 0, "gas": 100000}
100
- raw_transaction = ledger_api.build_transaction(
101
- contract_instance=token_balance_tracker_contract,
102
- method_name="deposit",
103
- method_args={"amount": amount},
104
- tx_args=tx_args,
105
- raise_on_try=True,
137
+ method_name = "deposit"
138
+ method_args = {"amount": amount}
139
+
140
+ if not agent_mode:
141
+ raw_transaction = ledger_api.build_transaction(
142
+ contract_instance=token_balance_tracker_contract,
143
+ method_name=method_name,
144
+ method_args=method_args,
145
+ tx_args=tx_args,
146
+ raise_on_try=True,
147
+ )
148
+ signed_transaction = crypto.sign_transaction(raw_transaction)
149
+ transaction_digest = ledger_api.send_signed_transaction(
150
+ signed_transaction,
151
+ raise_on_try=True,
152
+ )
153
+ return transaction_digest
154
+
155
+ function = token_balance_tracker_contract.functions[method_name](**method_args)
156
+ transaction = function.build_transaction(
157
+ {
158
+ "chainId": int(ledger_api._chain_id),
159
+ "gas": 0,
160
+ "nonce": get_safe_nonce(ethereum_client, str(safe_address)),
161
+ }
106
162
  )
107
- signed_transaction = crypto.sign_transaction(raw_transaction)
108
- transaction_digest = ledger_api.send_signed_transaction(
109
- signed_transaction,
110
- raise_on_try=True,
163
+ transaction_digest = send_safe_tx(
164
+ ethereum_client=ethereum_client,
165
+ tx_data=transaction["data"],
166
+ to_adress=token_balance_tracker_contract.address,
167
+ safe_address=str(safe_address),
168
+ signer_pkey=crypto.private_key,
169
+ value=0,
111
170
  )
112
- return transaction_digest
171
+ return transaction_digest.hex()
172
+
113
173
  except Exception as e: # pylint: disable=broad-except
114
174
  print(f"Error occured while sending the transaction: {e}")
115
175
  return str(e)
116
176
 
117
177
 
118
178
  def main(
179
+ agent_mode: bool,
119
180
  amount: str,
181
+ safe_address: Optional[str] = None,
120
182
  private_key_path: Optional[str] = None,
183
+ private_key_password: Optional[str] = None,
121
184
  chain_config: Optional[str] = None,
122
185
  ) -> None:
123
186
  """Runs the deposit functionality for the token mech type"""
@@ -129,6 +192,8 @@ def main(
129
192
  private_key_path = private_key_path or PRIVATE_KEY_FILE_PATH
130
193
 
131
194
  mech_config = get_mech_config(chain_config)
195
+ ledger_rpc = mech_config.ledger_config.address
196
+ ethereum_client = EthereumClient(ledger_rpc)
132
197
  ledger_config = mech_config.ledger_config
133
198
  ledger_api = EthereumApi(**asdict(ledger_config))
134
199
 
@@ -136,9 +201,9 @@ def main(
136
201
  raise FileNotFoundError(
137
202
  f"Private key file `{private_key_path}` does not exist!"
138
203
  )
139
- crypto = EthereumCrypto(private_key_path=private_key_path)
140
-
141
- print(f"Sender address: {crypto.address}")
204
+ crypto = EthereumCrypto(
205
+ private_key_path=private_key_path, password=private_key_password
206
+ )
142
207
 
143
208
  chain_id = mech_config.ledger_config.chain_id
144
209
  token_balance_tracker_contract = get_token_balance_tracker_contract(
@@ -146,11 +211,19 @@ def main(
146
211
  )
147
212
  token_contract = get_token_contract(ledger_api, chain_id)
148
213
 
149
- check_token_balance(token_contract, crypto.address, amount_to_deposit)
214
+ # Tokens will be on the safe and EOA pays for gas
215
+ # so for agent mode, sender has to be safe
216
+ sender = safe_address or crypto.address
217
+ print(f"Sender address: {sender}")
218
+
219
+ check_token_balance(token_contract, sender, amount_to_deposit)
150
220
 
151
221
  approve_tx = approve(
152
222
  crypto,
153
223
  ledger_api,
224
+ ethereum_client,
225
+ agent_mode,
226
+ safe_address,
154
227
  token_contract,
155
228
  token_balance_tracker_contract,
156
229
  amount_to_deposit,
@@ -169,6 +242,9 @@ def main(
169
242
  deposit_tx = deposit(
170
243
  ledger_api,
171
244
  crypto,
245
+ ethereum_client,
246
+ agent_mode,
247
+ safe_address,
172
248
  token_balance_tracker_contract,
173
249
  amount_to_deposit,
174
250
  )
scripts/nvm_subscribe.py CHANGED
@@ -3,6 +3,7 @@ import sys
3
3
  from dotenv import load_dotenv
4
4
  from typing import Optional, Dict
5
5
  from pathlib import Path
6
+ from aea_ledger_ethereum import EthereumCrypto
6
7
  from mech_client.interact import PRIVATE_KEY_FILE_PATH
7
8
  from web3 import Web3
8
9
  from scripts.nvm_subscription.manager import NVMSubscriptionManager
@@ -16,8 +17,11 @@ CHAIN_TO_ENVS: Dict[str, Path] = {
16
17
 
17
18
 
18
19
  def main(
20
+ agent_mode: bool,
19
21
  private_key_path: str,
22
+ private_key_password: Optional[str],
20
23
  chain_config: str,
24
+ safe_address: Optional[str] = None,
21
25
  ) -> None:
22
26
 
23
27
  chain_env = CHAIN_TO_ENVS.get(chain_config)
@@ -33,18 +37,22 @@ def main(
33
37
  f"Private key file `{private_key_path}` does not exist!"
34
38
  )
35
39
 
36
- with open(private_key_path, "r") as file:
37
- content = file.read()
38
-
39
- WALLET_PVT_KEY = content
40
+ crypto = EthereumCrypto(
41
+ private_key_path=private_key_path,
42
+ password=private_key_password,
43
+ )
44
+ WALLET_PVT_KEY = crypto.private_key
40
45
  PLAN_DID = os.environ["PLAN_DID"]
41
46
  NETWORK = os.environ["NETWORK_NAME"]
42
47
  CHAIN_ID = int(os.environ["CHAIN_ID"])
43
- SENDER = Web3().eth.account.from_key(WALLET_PVT_KEY).address
48
+ # NVM Subscription has to be purchased for the safe and EOA pays for gas
49
+ # so for agent mode, sender has to be safe
50
+ EOA = Web3().eth.account.from_key(WALLET_PVT_KEY).address
51
+ SENDER = safe_address or EOA
44
52
 
45
53
  print(f"Sender address: {SENDER}")
46
54
 
47
- manager = NVMSubscriptionManager(NETWORK, WALLET_PVT_KEY)
55
+ manager = NVMSubscriptionManager(NETWORK, SENDER, agent_mode, safe_address)
48
56
  tx_receipt = manager.create_subscription(PLAN_DID, WALLET_PVT_KEY, CHAIN_ID)
49
57
 
50
58
  print("Subscription created successfully")
@@ -27,7 +27,15 @@ class BaseContract:
27
27
  self.w3 = w3
28
28
  self.name = name
29
29
  self.chain_id = self.w3.eth.chain_id
30
- self.chain_name = "gnosis" if self.chain_id == 100 else "base"
30
+ chain_name_by_id = {
31
+ 100: "gnosis",
32
+ 8453: "base",
33
+ 137: "polygon",
34
+ }
35
+ self.chain_name = chain_name_by_id.get(self.chain_id)
36
+ if not self.chain_name:
37
+ raise ValueError(f"Unsupported chain id {self.chain_id}; no matching contract artifacts found")
38
+
31
39
  logger.debug(f"Initializing contract wrapper for '{self.name}'")
32
40
  self.contract = self._load_contract() # Load contract from artifact
33
41
 
@@ -41,6 +41,7 @@ class NFTSalesTemplateContract(BaseContract):
41
41
  amounts: List[int],
42
42
  receivers: List[str],
43
43
  sender: str,
44
+ nonce: int,
44
45
  value_eth: float,
45
46
  gas: int = 600_000,
46
47
  chain_id: int = 100
@@ -80,7 +81,6 @@ class NFTSalesTemplateContract(BaseContract):
80
81
 
81
82
  # Convert sender to a checksum address to ensure type safety
82
83
  sender_address: ChecksumAddress = self.w3.to_checksum_address(sender)
83
- nonce = self.w3.eth.get_transaction_count(sender_address)
84
84
  logger.debug(f"Nonce for sender {sender_address}: {nonce}")
85
85
 
86
86
  latest_block = self.w3.eth.get_block("latest")
@@ -107,9 +107,7 @@ class NFTSalesTemplateContract(BaseContract):
107
107
  "gas": gas,
108
108
  "nonce": nonce,
109
109
  })
110
- gas = self.w3.eth.estimate_gas(tx)
111
110
  tx.update({
112
- "gas": gas,
113
111
  "maxFeePerGas": base_fee + max_priority_fee,
114
112
  "maxPriorityFeePerGas": max_priority_fee,
115
113
  })
@@ -33,8 +33,9 @@ class SubscriptionProvider(BaseContract):
33
33
  fulfill_for_delegate_params: tuple,
34
34
  fulfill_params: tuple,
35
35
  sender: str,
36
+ nonce: int,
36
37
  value_eth: float,
37
- gas: int = 450_000,
38
+ gas: int = 500_000,
38
39
  chain_id: int = 100,
39
40
  ) -> Dict[str, Any]:
40
41
  """
@@ -67,7 +68,6 @@ class SubscriptionProvider(BaseContract):
67
68
 
68
69
  # Convert sender to a checksum address to ensure type safety
69
70
  sender_address: ChecksumAddress = self.w3.to_checksum_address(sender)
70
- nonce = self.w3.eth.get_transaction_count(sender_address)
71
71
  logger.debug(f"Nonce for sender {sender_address}: {nonce}")
72
72
 
73
73
  latest_block = self.w3.eth.get_block("latest")
@@ -93,10 +93,8 @@ class SubscriptionProvider(BaseContract):
93
93
  }
94
94
  )
95
95
  )
96
- gas = self.w3.eth.estimate_gas(tx)
97
96
  tx.update(
98
97
  {
99
- "gas": gas,
100
98
  "maxFeePerGas": base_fee + max_priority_fee,
101
99
  "maxPriorityFeePerGas": max_priority_fee,
102
100
  }
@@ -1,6 +1,6 @@
1
1
  # subscription/contracts/transfer_nft.py
2
2
  import logging
3
- from typing import Union
3
+ from typing import Union, Dict, Any
4
4
  from web3 import Web3
5
5
  from eth_typing import ChecksumAddress
6
6
  from web3.types import ENS
@@ -26,14 +26,35 @@ class SubscriptionToken(BaseContract):
26
26
  super().__init__(w3, name="SubscriptionToken")
27
27
  logger.info("Token initialized")
28
28
 
29
+ def get_balance(
30
+ self, sender: Union[ChecksumAddress, ENS]
31
+ ) -> int:
32
+ """
33
+ Gets the user token balance.
34
+
35
+ Args:
36
+ sender (ChecksumAddress | ENS): User address.
37
+
38
+ Returns:
39
+ int: The user's token balance.
40
+ """
41
+ sender_address: ChecksumAddress = self.w3.to_checksum_address(sender)
42
+
43
+ balance = (
44
+ self.functions().balanceOf(sender_address).call()
45
+ )
46
+ logger.debug(f"Fetched Token Balance: {balance}")
47
+ return balance
48
+
29
49
  def build_approve_token_tx(
30
50
  self,
31
51
  sender: Union[ChecksumAddress, ENS],
32
52
  to: Union[ChecksumAddress, ENS],
33
53
  amount: int,
54
+ nonce: int,
34
55
  gas: int = 60_000,
35
56
  chain_id: int = 100,
36
- ) -> bytes:
57
+ ) -> Dict[str, Any]:
37
58
  """
38
59
  Compute the hash of parameters for the transfer condition.
39
60
 
@@ -50,7 +71,6 @@ class SubscriptionToken(BaseContract):
50
71
  logger.debug("Approving token...")
51
72
  sender_address: ChecksumAddress = self.w3.to_checksum_address(sender)
52
73
  to_address: ChecksumAddress = self.w3.to_checksum_address(to)
53
- nonce = self.w3.eth.get_transaction_count(sender_address)
54
74
  logger.debug(f"Nonce for sender {sender_address}: {nonce}")
55
75
 
56
76
  latest_block = self.w3.eth.get_block("latest")
@@ -73,10 +93,8 @@ class SubscriptionToken(BaseContract):
73
93
  }
74
94
  )
75
95
  )
76
- gas = self.w3.eth.estimate_gas(tx)
77
96
  tx.update(
78
97
  {
79
- "gas": gas,
80
98
  "maxFeePerGas": base_fee + max_priority_fee,
81
99
  "maxPriorityFeePerGas": max_priority_fee,
82
100
  }