From 35cae03c5f31cfa8cf43cdd073d340fa5aa1b397 Mon Sep 17 00:00:00 2001 From: luc10921 Date: Wed, 22 May 2024 13:19:25 -0300 Subject: [PATCH] 86dt58c0w - Use local blockchain with neo-go instead of the TestNet on NeonInvoker tests --- .../CU-86dt58c0w_2024-05-22-16-09.json | 10 + .../data/deployReturnMapTest.json | 18 + .../neon-dappkit/data/deployReturnTest.json | 18 + .../neon-dappkit/data/deployVerifiable.json | 18 + packages/neon-dappkit/data/givewallet1.json | 20 + packages/neon-dappkit/data/givewallet2.json | 20 + .../data/protocol.unit_testnet.single.yml | 8 +- packages/neon-dappkit/data/wallet1_solo.json | 27 +- packages/neon-dappkit/package.json | 6 +- .../{src => test}/NeonEventListener.spec.ts | 92 ++--- .../{src => test}/NeonInvoker.spec.ts | 368 ++++++++---------- .../{src => test}/NeonParser.spec.ts | 2 +- .../{src => test}/NeonSigner.spec.ts | 2 +- packages/neon-dappkit/test/helper.ts | 66 ++++ packages/neon-dappkit/test/setup-neo-go.ts | 2 +- packages/neon-dappkit/tsconfig.build.json | 4 + packages/neon-dappkit/tsconfig.json | 2 +- 17 files changed, 407 insertions(+), 276 deletions(-) create mode 100644 common/changes/@cityofzion/neon-dappkit/CU-86dt58c0w_2024-05-22-16-09.json create mode 100644 packages/neon-dappkit/data/deployReturnMapTest.json create mode 100644 packages/neon-dappkit/data/deployReturnTest.json create mode 100644 packages/neon-dappkit/data/deployVerifiable.json create mode 100644 packages/neon-dappkit/data/givewallet1.json create mode 100644 packages/neon-dappkit/data/givewallet2.json rename packages/neon-dappkit/{src => test}/NeonEventListener.spec.ts (83%) rename packages/neon-dappkit/{src => test}/NeonInvoker.spec.ts (62%) rename packages/neon-dappkit/{src => test}/NeonParser.spec.ts (99%) rename packages/neon-dappkit/{src => test}/NeonSigner.spec.ts (99%) create mode 100644 packages/neon-dappkit/test/helper.ts create mode 100644 packages/neon-dappkit/tsconfig.build.json diff --git a/common/changes/@cityofzion/neon-dappkit/CU-86dt58c0w_2024-05-22-16-09.json b/common/changes/@cityofzion/neon-dappkit/CU-86dt58c0w_2024-05-22-16-09.json new file mode 100644 index 0000000..9e6a565 --- /dev/null +++ b/common/changes/@cityofzion/neon-dappkit/CU-86dt58c0w_2024-05-22-16-09.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@cityofzion/neon-dappkit", + "comment": "", + "type": "none" + } + ], + "packageName": "@cityofzion/neon-dappkit" +} \ No newline at end of file diff --git a/packages/neon-dappkit/data/deployReturnMapTest.json b/packages/neon-dappkit/data/deployReturnMapTest.json new file mode 100644 index 0000000..40a5de8 --- /dev/null +++ b/packages/neon-dappkit/data/deployReturnMapTest.json @@ -0,0 +1,18 @@ +{ + "type": "Neo.Network.P2P.Payloads.Transaction", + "network": 42, + "hash": "0xd1e694bf2198ecccafa2abc09149394c0f523e5e70e8fdd5566f57ddc1c9588e", + "data": "AN4giAUq+ao7AAAAABA1GgAAAAAAIQEAAAENqWekAEMr8n+OjrRv6KxlnszeBAEA/T4CDbQBew0KICAgICJuYW1lIjogInRlc3RtYXAiLA0KICAgICJncm91cHMiOiBbXSwNCiAgICAiZmVhdHVyZXMiOiB7fSwNCiAgICAic3VwcG9ydGVkc3RhbmRhcmRzIjogW10sDQogICAgImFiaSI6IHsNCiAgICAgICAgIm1ldGhvZHMiOiBbDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgIm5hbWUiOiAibWFpbiIsDQogICAgICAgICAgICAgICAgInBhcmFtZXRlcnMiOiBbXSwNCiAgICAgICAgICAgICAgICAicmV0dXJudHlwZSI6ICJNYXAiLA0KICAgICAgICAgICAgICAgICJvZmZzZXQiOiAwLA0KICAgICAgICAgICAgICAgICJzYWZlIjogZmFsc2UNCiAgICAgICAgICAgIH0NCiAgICAgICAgXSwNCiAgICAgICAgImV2ZW50cyI6IFtdDQogICAgfSwNCiAgICAicGVybWlzc2lvbnMiOiBbXSwNCiAgICAidHJ1c3RzIjogW10sDQogICAgImV4dHJhIjogbnVsbA0KfQxfTkVGM25lbzMtYm9hIGJ5IENPWi0xLjIuMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABFXAQDIcGgMAWEU0GgdE9BoQOnpMLUSwB8MBmRlcGxveQwU/aP6Q0bqUyolj8SX3a3bZDfJ/f9BYn1bUg==", + "items": { + "0x04decc9e65ace86fb48e8e7ff22b4300a467a90d": { + "script": "DCEDWpKPIBY5IE4GtDaLGpM2VGKo67/wuIGBUbdPqrOithpBVuezJw==", + "parameters": [ + { + "type": "Signature", + "value": "sD38tAvGimlPGKrRqhXXLDiReAldfZeCdMlCjvWzhL4r0yN4fKi7NLZYBQI2PktWiujk6rsWq+jc4bK7lZbEjQ==" + } + ], + "signatures": {} + } + } +} diff --git a/packages/neon-dappkit/data/deployReturnTest.json b/packages/neon-dappkit/data/deployReturnTest.json new file mode 100644 index 0000000..fedc169 --- /dev/null +++ b/packages/neon-dappkit/data/deployReturnTest.json @@ -0,0 +1,18 @@ +{ + "type": "Neo.Network.P2P.Payloads.Transaction", + "network": 42, + "hash": "0x84683441127be6b55c6a368194a0cd6fa2d5537d157defc205cc7d9dcbb7a206", + "data": "AKRfOoQq+ao7AAAAAChkUAAAAAAAIQEAAAENqWekAEMr8n+OjrRv6KxlnszeBAEA/R0QDTsPew0KICAgICJuYW1lIjogInJldHVybl9zYW1lX3ZhbHVlcyIsDQogICAgImdyb3VwcyI6IFtdLA0KICAgICJmZWF0dXJlcyI6IHt9LA0KICAgICJzdXBwb3J0ZWRzdGFuZGFyZHMiOiBbXSwNCiAgICAiYWJpIjogew0KICAgICAgICAibWV0aG9kcyI6IFsNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAibmFtZSI6ICJuZWdhdGl2ZV9udW1iZXJzIiwNCiAgICAgICAgICAgICAgICAicGFyYW1ldGVycyI6IFtdLA0KICAgICAgICAgICAgICAgICJyZXR1cm50eXBlIjogIkFycmF5IiwNCiAgICAgICAgICAgICAgICAib2Zmc2V0IjogMCwNCiAgICAgICAgICAgICAgICAic2FmZSI6IGZhbHNlDQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJuYW1lIjogIm5lZ2F0aXZlX251bWJlciIsDQogICAgICAgICAgICAgICAgInBhcmFtZXRlcnMiOiBbXSwNCiAgICAgICAgICAgICAgICAicmV0dXJudHlwZSI6ICJJbnRlZ2VyIiwNCiAgICAgICAgICAgICAgICAib2Zmc2V0IjogMTAsDQogICAgICAgICAgICAgICAgInNhZmUiOiBmYWxzZQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAibmFtZSI6ICJwb3NpdGl2ZV9udW1iZXJzIiwNCiAgICAgICAgICAgICAgICAicGFyYW1ldGVycyI6IFtdLA0KICAgICAgICAgICAgICAgICJyZXR1cm50eXBlIjogIkFycmF5IiwNCiAgICAgICAgICAgICAgICAib2Zmc2V0IjogMTMsDQogICAgICAgICAgICAgICAgInNhZmUiOiBmYWxzZQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAibmFtZSI6ICJib29sX3RydWUiLA0KICAgICAgICAgICAgICAgICJwYXJhbWV0ZXJzIjogW10sDQogICAgICAgICAgICAgICAgInJldHVybnR5cGUiOiAiQm9vbGVhbiIsDQogICAgICAgICAgICAgICAgIm9mZnNldCI6IDIzLA0KICAgICAgICAgICAgICAgICJzYWZlIjogZmFsc2UNCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgIm5hbWUiOiAiYm9vbF9mYWxzZSIsDQogICAgICAgICAgICAgICAgInBhcmFtZXRlcnMiOiBbXSwNCiAgICAgICAgICAgICAgICAicmV0dXJudHlwZSI6ICJCb29sZWFuIiwNCiAgICAgICAgICAgICAgICAib2Zmc2V0IjogMjUsDQogICAgICAgICAgICAgICAgInNhZmUiOiBmYWxzZQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAibmFtZSI6ICJyZXR1cm5fc3RyIiwNCiAgICAgICAgICAgICAgICAicGFyYW1ldGVycyI6IFtdLA0KICAgICAgICAgICAgICAgICJyZXR1cm50eXBlIjogIlN0cmluZyIsDQogICAgICAgICAgICAgICAgIm9mZnNldCI6IDI3LA0KICAgICAgICAgICAgICAgICJzYWZlIjogZmFsc2UNCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgIm5hbWUiOiAicmV0dXJuX2J5dGVzIiwNCiAgICAgICAgICAgICAgICAicGFyYW1ldGVycyI6IFtdLA0KICAgICAgICAgICAgICAgICJyZXR1cm50eXBlIjogIkJ5dGVBcnJheSIsDQogICAgICAgICAgICAgICAgIm9mZnNldCI6IDUxLA0KICAgICAgICAgICAgICAgICJzYWZlIjogZmFsc2UNCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgIm5hbWUiOiAicmV0dXJuX3NhbWVfaW50IiwNCiAgICAgICAgICAgICAgICAicGFyYW1ldGVycyI6IFsNCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgIm5hbWUiOiAiaW50XyIsDQogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJJbnRlZ2VyIg0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgXSwNCiAgICAgICAgICAgICAgICAicmV0dXJudHlwZSI6ICJJbnRlZ2VyIiwNCiAgICAgICAgICAgICAgICAib2Zmc2V0IjogNzUsDQogICAgICAgICAgICAgICAgInNhZmUiOiBmYWxzZQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAibmFtZSI6ICJyZXR1cm5fc2FtZV9ib29sIiwNCiAgICAgICAgICAgICAgICAicGFyYW1ldGVycyI6IFsNCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgIm5hbWUiOiAiYm9vbF8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAiQm9vbGVhbiINCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIF0sDQogICAgICAgICAgICAgICAgInJldHVybnR5cGUiOiAiQm9vbGVhbiIsDQogICAgICAgICAgICAgICAgIm9mZnNldCI6IDgwLA0KICAgICAgICAgICAgICAgICJzYWZlIjogZmFsc2UNCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgIm5hbWUiOiAicmV0dXJuX3NhbWVfYnl0ZXMiLA0KICAgICAgICAgICAgICAgICJwYXJhbWV0ZXJzIjogWw0KICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICAibmFtZSI6ICJieXRlc18iLA0KICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAiQnl0ZUFycmF5Ig0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgXSwNCiAgICAgICAgICAgICAgICAicmV0dXJudHlwZSI6ICJCeXRlQXJyYXkiLA0KICAgICAgICAgICAgICAgICJvZmZzZXQiOiA4NSwNCiAgICAgICAgICAgICAgICAic2FmZSI6IGZhbHNlDQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJuYW1lIjogInJldHVybl9zYW1lX3N0ciIsDQogICAgICAgICAgICAgICAgInBhcmFtZXRlcnMiOiBbDQogICAgICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICJuYW1lIjogInN0cmluZyIsDQogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJTdHJpbmciDQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICBdLA0KICAgICAgICAgICAgICAgICJyZXR1cm50eXBlIjogIlN0cmluZyIsDQogICAgICAgICAgICAgICAgIm9mZnNldCI6IDkwLA0KICAgICAgICAgICAgICAgICJzYWZlIjogZmFsc2UNCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgIm5hbWUiOiAicmV0dXJuX3NhbWVfYXJyYXkiLA0KICAgICAgICAgICAgICAgICJwYXJhbWV0ZXJzIjogWw0KICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICAibmFtZSI6ICJhcnJheSIsDQogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJBcnJheSINCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIF0sDQogICAgICAgICAgICAgICAgInJldHVybnR5cGUiOiAiQXJyYXkiLA0KICAgICAgICAgICAgICAgICJvZmZzZXQiOiA5NSwNCiAgICAgICAgICAgICAgICAic2FmZSI6IGZhbHNlDQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJuYW1lIjogInJldHVybl9zYW1lX21hcCIsDQogICAgICAgICAgICAgICAgInBhcmFtZXRlcnMiOiBbDQogICAgICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICJuYW1lIjogIm1hcCIsDQogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJNYXAiDQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICBdLA0KICAgICAgICAgICAgICAgICJyZXR1cm50eXBlIjogIk1hcCIsDQogICAgICAgICAgICAgICAgIm9mZnNldCI6IDEwMCwNCiAgICAgICAgICAgICAgICAic2FmZSI6IGZhbHNlDQogICAgICAgICAgICB9DQogICAgICAgIF0sDQogICAgICAgICJldmVudHMiOiBbXQ0KICAgIH0sDQogICAgInBlcm1pc3Npb25zIjogW10sDQogICAgInRydXN0cyI6IFtdLA0KICAgICJleHRyYSI6IG51bGwNCn0Mt05FRjNuZW8zLWJvYSBieSBDT1otMS4yLjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABpAIUAnADsDxTAQACcQAB7AGQAFBEUwEAIQAlADBV0ZXN0aW5nIHN0cmluZyByZXR1cm5ADBV0ZXN0aW5nIHN0cmluZyByZXR1cm5AVwABeEBXAAF4QFcAAXhAVwABeEBXAAF4QFcAAXhA4p3GDRLAHwwGZGVwbG95DBT9o/pDRupTKiWPxJfdrdtkN8n9/0FifVtS", + "items": { + "0x04decc9e65ace86fb48e8e7ff22b4300a467a90d": { + "script": "DCEDWpKPIBY5IE4GtDaLGpM2VGKo67/wuIGBUbdPqrOithpBVuezJw==", + "parameters": [ + { + "type": "Signature", + "value": "NRVqK57ierLyrtBq+7pjWJc1VJu58+ca8lwpTzUNtab8aUYA58p0gAqssGzLOGn6EThehbNqln3KcweNt9z+UQ==" + } + ], + "signatures": {} + } + } +} diff --git a/packages/neon-dappkit/data/deployVerifiable.json b/packages/neon-dappkit/data/deployVerifiable.json new file mode 100644 index 0000000..6049d0c --- /dev/null +++ b/packages/neon-dappkit/data/deployVerifiable.json @@ -0,0 +1,18 @@ +{ + "type": "Neo.Network.P2P.Payloads.Transaction", + "network": 42, + "hash": "0xb3a65bd0a4e00dfe8461c7253d39630492fbdad3c1c325021b8dc484f5766f4f", + "data": "AGM8ucUgbuA7AAAAACBDMwAAAAAAQQsAAAENqWekAEMr8n+OjrRv6KxlnszeBAEA/agIDXoHew0KICAgICJuYW1lIjogInZlcmlmaWFibGUiLA0KICAgICJncm91cHMiOiBbXSwNCiAgICAiYWJpIjogew0KICAgICAgICAibWV0aG9kcyI6IFsNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAibmFtZSI6ICJoZWxsb193b3JsZCIsDQogICAgICAgICAgICAgICAgIm9mZnNldCI6IDAsDQogICAgICAgICAgICAgICAgInBhcmFtZXRlcnMiOiBbXSwNCiAgICAgICAgICAgICAgICAic2FmZSI6IGZhbHNlLA0KICAgICAgICAgICAgICAgICJyZXR1cm50eXBlIjogIlN0cmluZyINCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgIm5hbWUiOiAidmVyaWZ5IiwNCiAgICAgICAgICAgICAgICAib2Zmc2V0IjogMTYsDQogICAgICAgICAgICAgICAgInBhcmFtZXRlcnMiOiBbXSwNCiAgICAgICAgICAgICAgICAic2FmZSI6IGZhbHNlLA0KICAgICAgICAgICAgICAgICJyZXR1cm50eXBlIjogIkJvb2xlYW4iDQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJuYW1lIjogInVwZGF0ZSIsDQogICAgICAgICAgICAgICAgIm9mZnNldCI6IDEwMSwNCiAgICAgICAgICAgICAgICAicGFyYW1ldGVycyI6IFsNCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAiQnl0ZUFycmF5IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICJuYW1lIjogIm5lZiINCiAgICAgICAgICAgICAgICAgICAgfSwNCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAiU3RyaW5nIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICJuYW1lIjogIm1hbmlmZXN0Ig0KICAgICAgICAgICAgICAgICAgICB9LA0KICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJBbnkiLA0KICAgICAgICAgICAgICAgICAgICAgICAgIm5hbWUiOiAiZGF0YSINCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIF0sDQogICAgICAgICAgICAgICAgInNhZmUiOiBmYWxzZSwNCiAgICAgICAgICAgICAgICAicmV0dXJudHlwZSI6ICJWb2lkIg0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAibmFtZSI6ICJfZGVwbG95IiwNCiAgICAgICAgICAgICAgICAib2Zmc2V0IjogMTE1LA0KICAgICAgICAgICAgICAgICJwYXJhbWV0ZXJzIjogWw0KICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJBbnkiLA0KICAgICAgICAgICAgICAgICAgICAgICAgIm5hbWUiOiAiZGF0YSINCiAgICAgICAgICAgICAgICAgICAgfSwNCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAiQm9vbGVhbiIsDQogICAgICAgICAgICAgICAgICAgICAgICAibmFtZSI6ICJ1cGRhdGUiDQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICBdLA0KICAgICAgICAgICAgICAgICJzYWZlIjogZmFsc2UsDQogICAgICAgICAgICAgICAgInJldHVybnR5cGUiOiAiVm9pZCINCiAgICAgICAgICAgIH0NCiAgICAgICAgXSwNCiAgICAgICAgImV2ZW50cyI6IFtdDQogICAgfSwNCiAgICAicGVybWlzc2lvbnMiOiBbDQogICAgICAgIHsNCiAgICAgICAgICAgICJjb250cmFjdCI6ICIweGZmZmRjOTM3NjRkYmFkZGQ5N2M0OGYyNTJhNTNlYTQ2NDNmYWEzZmQiLA0KICAgICAgICAgICAgIm1ldGhvZHMiOiBbDQogICAgICAgICAgICAgICAgInVwZGF0ZSINCiAgICAgICAgICAgIF0NCiAgICAgICAgfQ0KICAgIF0sDQogICAgInRydXN0cyI6IFtdLA0KICAgICJmZWF0dXJlcyI6IHt9LA0KICAgICJzdXBwb3J0ZWRzdGFuZGFyZHMiOiBbXSwNCiAgICAiZXh0cmEiOiBudWxsDQp9DQIBTkVGM25lbzMtYm9hIGJ5IENPWi0xLjEuMQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH9o/pDRupTKiWPxJfdrdtkN8n9/wZ1cGRhdGUDAAAPAACVDA1IZWxsbywgV29ybGQhQAwFb3duZXJBm/ZnzkGSXegxStgmBUUMAErZISYsShC4OUrKABRLSy4eDBQAAAAAAAAAAAAAAAAAAAAAAAAAAFOfjYsiBEVF2yhKygAUszlB+CfsjEBXAAM0qCYIenl4NwAAQFcBAnmqJhxBLVEIMHBoE84MBW93bmVyQZv2Z85B5j8YhECyAglcEsAfDAZkZXBsb3kMFP2j+kNG6lMqJY/El92t22Q3yf3/QWJ9W1I=", + "items": { + "0x04decc9e65ace86fb48e8e7ff22b4300a467a90d": { + "script": "DCEDWpKPIBY5IE4GtDaLGpM2VGKo67/wuIGBUbdPqrOithpBVuezJw==", + "parameters": [ + { + "type": "Signature", + "value": "A7mWiXtx3pHRrhbdJmZewDvoos4O11H+Xf2gMEYcj9wZTq7BhGsXD3qmj010cAQFNPfYwF0BLEwiWy+LykTfeg==" + } + ], + "signatures": {} + } + } +} diff --git a/packages/neon-dappkit/data/givewallet1.json b/packages/neon-dappkit/data/givewallet1.json new file mode 100644 index 0000000..bb01ab8 --- /dev/null +++ b/packages/neon-dappkit/data/givewallet1.json @@ -0,0 +1,20 @@ +{ + "type": "Neo.Network.P2P.Payloads.Transaction", + "network": 42, + "hash": "0x073b10d38c7746dbc49ac68111620de07aefc90fb9099ff2127b49dad5078132", + "data": "AMMv98G0P5gAAAAAADTmEgAAAAAAQQsAAAHYzFqQTVJvyabKtVugLJpv54nJVgEAXwsDAOQLVAIAAAAMFA2pZ6QAQyvyf46OtG/orGWezN4EDBTYzFqQTVJvyabKtVugLJpv54nJVhTAHwwIdHJhbnNmZXIMFM924ovQBixKR47jVWEBExnzz6TSQWJ9W1I5", + "items": { + "0x56c989e76f9a2ca05bb5caa6c96f524d905accd8": { + "script": "EQwhArNiK/QBe9/jF8WK7V9MdT8ga324lgRvp9d0u8S/f43CEUGe0Nw6", + "parameters": [ + { + "type": "Signature", + "value": "FXFv4y0kiyi5UuQqEahGLqGkgaUj3ocz0VNr9ftSuBijHQQvGegcIgLisOPtVuEserMr4hTsOsbjXrMVsa9tDA==" + } + ], + "signatures": { + "02b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc2": "FXFv4y0kiyi5UuQqEahGLqGkgaUj3ocz0VNr9ftSuBijHQQvGegcIgLisOPtVuEserMr4hTsOsbjXrMVsa9tDA==" + } + } + } +} diff --git a/packages/neon-dappkit/data/givewallet2.json b/packages/neon-dappkit/data/givewallet2.json new file mode 100644 index 0000000..bcf56b3 --- /dev/null +++ b/packages/neon-dappkit/data/givewallet2.json @@ -0,0 +1,20 @@ +{ + "type": "Neo.Network.P2P.Payloads.Transaction", + "network": 42, + "hash": "0x28e2233a460fcb5a1a62e008b8fe59102f68348f3b0b51394f60d9ef4d41d58c", + "data": "AKEnb/y0P5gAAAAAADTmEgAAAAAAQQsAAAHYzFqQTVJvyabKtVugLJpv54nJVgEAXwsDAOQLVAIAAAAMFG39lqnMYENP1ggtinWrW58yP1f0DBTYzFqQTVJvyabKtVugLJpv54nJVhTAHwwIdHJhbnNmZXIMFM924ovQBixKR47jVWEBExnzz6TSQWJ9W1I5", + "items": { + "0x56c989e76f9a2ca05bb5caa6c96f524d905accd8": { + "script": "EQwhArNiK/QBe9/jF8WK7V9MdT8ga324lgRvp9d0u8S/f43CEUGe0Nw6", + "parameters": [ + { + "type": "Signature", + "value": "tpPHZyEHhoOq7g2LC9C5udqP4wyG2QUmOxmphkjgbZ5sX2Wv0ggY86O3XyO13D8TSl9ZQHXhbnu39YNbmb4AJw==" + } + ], + "signatures": { + "02b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc2": "tpPHZyEHhoOq7g2LC9C5udqP4wyG2QUmOxmphkjgbZ5sX2Wv0ggY86O3XyO13D8TSl9ZQHXhbnu39YNbmb4AJw==" + } + } + } +} diff --git a/packages/neon-dappkit/data/protocol.unit_testnet.single.yml b/packages/neon-dappkit/data/protocol.unit_testnet.single.yml index 3ebfe0a..dedcf80 100644 --- a/packages/neon-dappkit/data/protocol.unit_testnet.single.yml +++ b/packages/neon-dappkit/data/protocol.unit_testnet.single.yml @@ -1,20 +1,20 @@ ProtocolConfiguration: Magic: 42 MaxTraceableBlocks: 200000 - TimePerBlock: 300ms + InitialGASSupply: 5200000000 + TimePerBlock: 500ms MemPoolSize: 100 StandbyCommittee: - 02b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc2 ValidatorsCount: 1 VerifyTransactions: true - P2PSigExtensions: true + P2PSigExtensions: false Hardforks: Aspidochelone: 25 ApplicationConfiguration: SkipBlockVerification: false # LogPath could be set up in case you need stdout logs to some proper file. - # LogPath: "./log/neogo.log" DBConfiguration: Type: 'inmemory' #other options: 'inmemory','boltdb' # DB type options. Uncomment those you need in case you want to switch DB type. @@ -42,7 +42,7 @@ ApplicationConfiguration: MaxGasInvoke: 15 Enabled: true Addresses: - - '127.0.0.1:50012' + - '127.0.0.1:30222' EnableCORSWorkaround: false Prometheus: Enabled: false #since it's not useful for unit tests. diff --git a/packages/neon-dappkit/data/wallet1_solo.json b/packages/neon-dappkit/data/wallet1_solo.json index 4a284a2..27de2bd 100644 --- a/packages/neon-dappkit/data/wallet1_solo.json +++ b/packages/neon-dappkit/data/wallet1_solo.json @@ -16,25 +16,34 @@ "deployed": false }, "lock": false, - "isDefault": false + "isDefault": true }, { - "address": "NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq", + "address": "NfgHwwTi3wHAS8aFAN243C5vGbkYDpqLHP", "key": "6PYM8VdX3hY4B51UJxmm8D41RQMbpJT8aYHibyQ67gjkUPmvQgu51Y5UQR", "label": "", "contract": { - "script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFEGe0Nw6", + "script": "EQwhArNiK/QBe9/jF8WK7V9MdT8ga324lgRvp9d0u8S/f43CEUGe0Nw6", "parameters": [ { "name": "parameter0", "type": "Signature" - }, - { - "name": "parameter1", - "type": "Signature" - }, + } + ], + "deployed": false + }, + "lock": false, + "isDefault": false + }, + { + "address": "NMACuhqEaNAeDSQVipcUPYiJ9TVgVyUxGV", + "key": "6PYLyTFiWAHEivtab5dMWorwiNaczcbFRbxcqAuBWVyGLtFSsbFZycEZVu", + "label": "account1", + "contract": { + "script": "DCEDWpKPIBY5IE4GtDaLGpM2VGKo67/wuIGBUbdPqrOithpBVuezJw==", + "parameters": [ { - "name": "parameter2", + "name": "parameter0", "type": "Signature" } ], diff --git a/packages/neon-dappkit/package.json b/packages/neon-dappkit/package.json index e0e2bb2..952f4d6 100644 --- a/packages/neon-dappkit/package.json +++ b/packages/neon-dappkit/package.json @@ -8,11 +8,11 @@ "/dist" ], "scripts": { - "build": "tsc", + "build": "tsc -p tsconfig.build.json", "lint": "eslint .", "format": "eslint --fix", - "test": "ts-node test/setup-neo-go.ts && ts-mocha --reporter json > ../../mocha-results.json src/**/*.spec.ts", - "test-print": "ts-node test/setup-neo-go.ts && ts-mocha src/**/*.spec.ts", + "test": "ts-node test/setup-neo-go.ts && ts-mocha --reporter json > ../../mocha-results.json test/**/*.spec.ts", + "test-print": "ts-node test/setup-neo-go.ts && ts-mocha test/**/*.spec.ts", "coverage": "nyc pnpm test" }, "dependencies": { diff --git a/packages/neon-dappkit/src/NeonEventListener.spec.ts b/packages/neon-dappkit/test/NeonEventListener.spec.ts similarity index 83% rename from packages/neon-dappkit/src/NeonEventListener.spec.ts rename to packages/neon-dappkit/test/NeonEventListener.spec.ts index 9868e19..0d05bd5 100644 --- a/packages/neon-dappkit/src/NeonEventListener.spec.ts +++ b/packages/neon-dappkit/test/NeonEventListener.spec.ts @@ -1,6 +1,5 @@ import { ChildProcess, spawn } from 'child_process' -import { NeonEventListener, NeonInvoker, NeonParser } from './index' -import * as path from 'path' +import { NeonEventListener, NeonInvoker, NeonParser } from '../src/index' import assert from 'assert' import { ContractInvocationMulti, @@ -10,52 +9,29 @@ import { TypeChecker, } from '@cityofzion/neon-dappkit-types' import { wallet } from '@cityofzion/neon-core' - -function wait(ms: number) { - return new Promise((resolve) => { - setTimeout(resolve, ms) - }) -} - -function neoGoPath() { - return path.resolve(path.join(__dirname, '..', 'neogo', 'neogo')) -} - -function getDataDir() { - return path.resolve(path.join(__dirname, '..', 'data')) -} +import { + wait, + neoGoPath, + getDataDir, + transferInvocation, + waitTime, + rpcAddress, + gasScriptHash, + neonEventListenerOptions, +} from './helper' describe('NeonEventListener', function () { this.timeout(60000) let childProcess: ChildProcess - const rpcAddress = 'http://127.0.0.1:50012' - const eventListener = new NeonEventListener(rpcAddress, { - waitForApplicationLog: { maxAttempts: 10, waitMs: 100 }, - waitForEventMs: 100, - }) - const gasScriptHash = '0xd2a4cff31913016155e38e474a2c06d08be276cf' + const eventListener = new NeonEventListener(rpcAddress, neonEventListenerOptions) let accountWithGas: wallet.Account - const waitTime = 900 - function transferInvocation( + function gasTransferInvocation( sender: wallet.Account, receiver: wallet.Account, amount: string, ): ContractInvocationMulti { - return { - invocations: [ - { - scriptHash: gasScriptHash, - operation: 'transfer', - args: [ - { type: 'Hash160', value: sender.address }, - { type: 'Hash160', value: receiver.address }, - { type: 'Integer', value: amount }, - { type: 'String', value: 'test' }, - ], - }, - ], - } + return transferInvocation(gasScriptHash, sender, receiver, amount) } beforeEach(async function () { @@ -73,6 +49,8 @@ describe('NeonEventListener', function () { await wallet.decrypt('6PYM8VdX3hY4B51UJxmm8D41RQMbpJT8aYHibyQ67gjkUPmvQgu51Y5UQR', 'one', { n: 2, r: 1, p: 1 }), ) + await wait(waitTime) + return true }) @@ -102,7 +80,7 @@ describe('NeonEventListener', function () { const neoInvoker = await NeonInvoker.init({ rpcAddress, account: sender }) - const txId = await neoInvoker.invokeFunction(transferInvocation(sender, receiver, '100')) + const txId = await neoInvoker.invokeFunction(gasTransferInvocation(sender, receiver, '100')) assert(txId, 'Transaction ID should be returned') const notification = await eventPromise @@ -141,7 +119,7 @@ describe('NeonEventListener', function () { const neoInvoker = await NeonInvoker.init({ rpcAddress, account: sender }) - const txId = await neoInvoker.invokeFunction(transferInvocation(sender, receiver, '100')) + const txId = await neoInvoker.invokeFunction(gasTransferInvocation(sender, receiver, '100')) assert(txId, 'Transaction ID should be returned') const notification1 = await eventPromise1 @@ -160,7 +138,7 @@ describe('NeonEventListener', function () { const neoInvoker = await NeonInvoker.init({ rpcAddress, account: sender }) - const txId = await neoInvoker.invokeFunction(transferInvocation(sender, receiver, '100')) + const txId = await neoInvoker.invokeFunction(gasTransferInvocation(sender, receiver, '100')) assert(txId, 'Transaction ID should be returned') await wait(waitTime) @@ -177,7 +155,7 @@ describe('NeonEventListener', function () { const neoInvoker = await NeonInvoker.init({ rpcAddress, account: sender }) - const txId = await neoInvoker.invokeFunction(transferInvocation(sender, receiver, '100')) + const txId = await neoInvoker.invokeFunction(gasTransferInvocation(sender, receiver, '100')) assert(txId, 'Transaction ID should be returned') await wait(waitTime) @@ -203,7 +181,7 @@ describe('NeonEventListener', function () { const neoInvoker = await NeonInvoker.init({ rpcAddress, account: sender }) - const txId = await neoInvoker.invokeFunction(transferInvocation(sender, receiver, '100')) + const txId = await neoInvoker.invokeFunction(gasTransferInvocation(sender, receiver, '100')) assert(txId, 'Transaction ID should be returned') await assert.rejects(async () => eventPromise) @@ -225,14 +203,14 @@ describe('NeonEventListener', function () { const neoInvoker = await NeonInvoker.init({ rpcAddress, account: sender }) - let txId = await neoInvoker.invokeFunction(transferInvocation(sender, receiver, '100')) + let txId = await neoInvoker.invokeFunction(gasTransferInvocation(sender, receiver, '100')) assert(txId, 'Transaction ID should be returned') await wait(waitTime) assert(called === 1, 'Callback should be called once') eventListener.removeEventListener(gasScriptHash, eventName, callBack) - txId = await neoInvoker.invokeFunction(transferInvocation(sender, receiver, '100')) + txId = await neoInvoker.invokeFunction(gasTransferInvocation(sender, receiver, '100')) assert(txId, 'Transaction ID should be returned') await wait(waitTime) @@ -255,14 +233,14 @@ describe('NeonEventListener', function () { const neoInvoker = await NeonInvoker.init({ rpcAddress, account: sender }) - let txId = await neoInvoker.invokeFunction(transferInvocation(sender, receiver, '100')) + let txId = await neoInvoker.invokeFunction(gasTransferInvocation(sender, receiver, '100')) assert(txId, 'Transaction ID should be returned') await wait(waitTime) assert(called === 1, 'Callback should be called once') eventListener.removeAllEventListenersOfContract(gasScriptHash) - txId = await neoInvoker.invokeFunction(transferInvocation(sender, receiver, '100')) + txId = await neoInvoker.invokeFunction(gasTransferInvocation(sender, receiver, '100')) assert(txId, 'Transaction ID should be returned') await wait(waitTime) @@ -285,14 +263,14 @@ describe('NeonEventListener', function () { const neoInvoker = await NeonInvoker.init({ rpcAddress, account: sender }) - let txId = await neoInvoker.invokeFunction(transferInvocation(sender, receiver, '100')) + let txId = await neoInvoker.invokeFunction(gasTransferInvocation(sender, receiver, '100')) assert(txId, 'Transaction ID should be returned') await wait(waitTime) assert(called === 1, 'Callback should be called once') eventListener.removeAllEventListenersOfEvent(gasScriptHash, eventName) - txId = await neoInvoker.invokeFunction(transferInvocation(sender, receiver, '100')) + txId = await neoInvoker.invokeFunction(gasTransferInvocation(sender, receiver, '100')) assert(txId, 'Transaction ID should be returned') await wait(waitTime) @@ -304,7 +282,7 @@ describe('NeonEventListener', function () { const receiver = new wallet.Account() const neoInvoker = await NeonInvoker.init({ rpcAddress, account: sender }) - const txId = await neoInvoker.invokeFunction(transferInvocation(sender, receiver, '100')) + const txId = await neoInvoker.invokeFunction(gasTransferInvocation(sender, receiver, '100')) const applicationLog = await eventListener.waitForApplicationLog(txId) @@ -334,7 +312,7 @@ describe('NeonEventListener', function () { const receiver = new wallet.Account() const neoInvoker = await NeonInvoker.init({ rpcAddress, account: sender }) - const txId = await neoInvoker.invokeFunction(transferInvocation(sender, receiver, '100')) + const txId = await neoInvoker.invokeFunction(gasTransferInvocation(sender, receiver, '100')) const fastEventListener = new NeonEventListener(rpcAddress, { waitForApplicationLog: { maxAttempts: 1, waitMs: 10 }, @@ -348,7 +326,7 @@ describe('NeonEventListener', function () { const receiver = new wallet.Account() const neoInvoker = await NeonInvoker.init({ rpcAddress, account: sender }) - const txId = await neoInvoker.invokeFunction(transferInvocation(sender, receiver, '100')) + const txId = await neoInvoker.invokeFunction(gasTransferInvocation(sender, receiver, '100')) const applicationLog = await eventListener.waitForApplicationLog(txId) eventListener.confirmHalt(applicationLog) @@ -375,12 +353,12 @@ describe('NeonEventListener', function () { const receiver = new wallet.Account() const neoInvoker = await NeonInvoker.init({ rpcAddress, account: sender }) - const txId = await neoInvoker.invokeFunction(transferInvocation(sender, receiver, '100')) + const txId = await neoInvoker.invokeFunction(gasTransferInvocation(sender, receiver, '100')) const applicationLog = await eventListener.waitForApplicationLog(txId) eventListener.confirmStackTrue(applicationLog) - const txIdFalse = await neoInvoker.invokeFunction(transferInvocation(sender, receiver, '-100')) + const txIdFalse = await neoInvoker.invokeFunction(gasTransferInvocation(sender, receiver, '-100')) const applicationLogFalse = await eventListener.waitForApplicationLog(txIdFalse) await assert.rejects(async () => { @@ -402,7 +380,7 @@ describe('NeonEventListener', function () { const receiver = new wallet.Account() const neoInvoker = await NeonInvoker.init({ rpcAddress, account: sender }) - const txId = await neoInvoker.invokeFunction(transferInvocation(sender, receiver, '100')) + const txId = await neoInvoker.invokeFunction(gasTransferInvocation(sender, receiver, '100')) const applicationLog = await eventListener.waitForApplicationLog(txId) const notificationState = eventListener.getNotificationState(applicationLog, { @@ -437,14 +415,14 @@ describe('NeonEventListener', function () { const receiver = new wallet.Account() const neoInvoker = await NeonInvoker.init({ rpcAddress, account: sender }) - const txId = await neoInvoker.invokeFunction(transferInvocation(sender, receiver, '100')) + const txId = await neoInvoker.invokeFunction(gasTransferInvocation(sender, receiver, '100')) const applicationLog = await eventListener.waitForApplicationLog(txId) eventListener.confirmTransaction(applicationLog) eventListener.confirmTransaction(applicationLog, { contract: gasScriptHash, eventname: 'Transfer' }) eventListener.confirmTransaction(applicationLog, { contract: gasScriptHash, eventname: 'Transfer' }, true) - const txIdFalse = await neoInvoker.invokeFunction(transferInvocation(sender, receiver, '-100')) + const txIdFalse = await neoInvoker.invokeFunction(gasTransferInvocation(sender, receiver, '-100')) const applicationLogFalse = await eventListener.waitForApplicationLog(txIdFalse) eventListener.confirmTransaction(applicationLogFalse) diff --git a/packages/neon-dappkit/src/NeonInvoker.spec.ts b/packages/neon-dappkit/test/NeonInvoker.spec.ts similarity index 62% rename from packages/neon-dappkit/src/NeonInvoker.spec.ts rename to packages/neon-dappkit/test/NeonInvoker.spec.ts index e6509ee..9687ae5 100644 --- a/packages/neon-dappkit/src/NeonInvoker.spec.ts +++ b/packages/neon-dappkit/test/NeonInvoker.spec.ts @@ -1,73 +1,93 @@ +import { ChildProcess, spawn, execSync } from 'child_process' import { ContractInvocationMulti } from '@cityofzion/neon-dappkit-types' -import { NeonInvoker, NeonParser, TypeChecker } from './index' -import { wallet, tx } from '@cityofzion/neon-js' +import { NeonEventListener, NeonInvoker, NeonParser, TypeChecker } from '../src/index' import assert from 'assert' +import * as path from 'path' +import { tx } from '@cityofzion/neon-js' +import { wallet } from '@cityofzion/neon-core' +import { + wait, + neoGoPath, + getDataDir, + getBalance, + toDecimal, + transferInvocation, + rpcAddress, + gasScriptHash, + waitTime, + neonEventListenerOptions, + neoScriptHash, +} from './helper' -async function getBalance(invoker: NeonInvoker, address: string) { - const payerBalanceResp = await invoker.testInvoke({ - invocations: [ - { - operation: 'balanceOf', - scriptHash: '0xd2a4cff31913016155e38e474a2c06d08be276cf', - args: [{ value: address, type: 'Hash160' }], - }, - ], - }) - return NeonParser.parseRpcResponse(payerBalanceResp.stack[0]) / Math.pow(10, 8) -} +describe('NeonInvoker', function () { + this.timeout(60000) + let childProcess: ChildProcess + let account1: wallet.Account + let account2: wallet.Account + const neonEventListener = new NeonEventListener(rpcAddress, neonEventListenerOptions) + const verifiableContract = '0x1b0146e719219b77e70b654aeb23f82b25f8abca' + const testReturnContract = '0x5d564a6ee553234ff7a32c7cc2e188d3086d4892' + const testReturnMapContract = '0x3b2244fc8c13644048040c8e4aa6562365658def' + + beforeEach(async function () { + const neoGo = neoGoPath() + const dataDir = getDataDir() + + childProcess = spawn( + neoGo, + ['node', '--config-file', `${dataDir}/protocol.unit_testnet.single.yml`, '--relative-path', dataDir], + {}, + ) + await wait(waitTime) -function wait(ms: number) { - return new Promise((resolve) => { - setTimeout(resolve, ms) - }) -} + account1 = new wallet.Account('c7134d6fd8e73d819e82755c64c93788d8db0961929e025a53363c4cc02a6962') + account2 = new wallet.Account('450d6c2a04b5b470339a745427bae6828400cf048400837d73c415063835e005') -function toDecimal(num: number, decimal: number) { - return num / 10 ** decimal -} + // Giving 100 GAS to account1 and account2 + execSync(`${neoGo} util sendtx -r ${rpcAddress} ${path.resolve(path.join(getDataDir(), 'givewallet1.json'))}`) + execSync(`${neoGo} util sendtx -r ${rpcAddress} ${path.resolve(path.join(getDataDir(), 'givewallet2.json'))}`) -describe('NeonInvoker', function () { - this.timeout(60000) + await wait(waitTime) + + // Deploying smart contracts + execSync( + `${neoGo} util sendtx -r ${rpcAddress} ${path.resolve(path.join(getDataDir(), 'deployVerifiable.json'))}`, + ).toString() + execSync( + `${neoGo} util sendtx -r ${rpcAddress} ${path.resolve(path.join(getDataDir(), 'deployReturnTest.json'))}`, + ).toString() + execSync( + `${neoGo} util sendtx -r ${rpcAddress} ${path.resolve(path.join(getDataDir(), 'deployReturnMapTest.json'))}`, + ).toString() + + await wait(waitTime) + + return true + }) + + afterEach('Tear down', async function () { + return childProcess.kill() + }) it('does invokeFunction', async () => { - const account = new wallet.Account('3bd06d95e9189385851aa581d182f25de34af759cf7f883af57030303ded52b8') const invoker = await NeonInvoker.init({ - rpcAddress: NeonInvoker.TESTNET, - account, + rpcAddress, + account: account1, }) + const receiver = new wallet.Account() - const txId = await invoker.invokeFunction({ - invocations: [ - { - scriptHash: '0xd2a4cff31913016155e38e474a2c06d08be276cf', - operation: 'transfer', - args: [ - { type: 'Hash160', value: account.address }, - { type: 'Hash160', value: 'NbnjKGMBJzJ6j5PHeYhjJDaQ5Vy5UYu4Fv' }, - { type: 'Integer', value: '100000000' }, - { type: 'Array', value: [] }, - ], - }, - ], - signers: [ - { - account: account.scriptHash, - scopes: tx.WitnessScope.CalledByEntry, - rules: [], - }, - ], - }) + const txId = await invoker.invokeFunction(transferInvocation(gasScriptHash, account1, receiver, '100')) assert(txId.length > 0, 'has txId') - await wait(15000) + await wait(waitTime) }) it('does invokeFunction with signingCallback', async () => { - const publicAccount = new wallet.Account('02eecb8c0c3ae4e3c65457581c8c8dc0ecf52f74953166ce84d3c5b67a42a1ee73') - const privateAccount = new wallet.Account('3bd06d95e9189385851aa581d182f25de34af759cf7f883af57030303ded52b8') + const privateAccount = account1 + const publicAccount = new wallet.Account(privateAccount.publicKey) const invoker = await NeonInvoker.init({ - rpcAddress: NeonInvoker.TESTNET, + rpcAddress, signingCallback: async (transaction, details) => { const hex = NeonParser.numToHex(details.network, 4, true) + NeonParser.reverseHex(transaction.hash()) return wallet.sign(hex, privateAccount.privateKey) @@ -76,18 +96,7 @@ describe('NeonInvoker', function () { }) const txId = await invoker.invokeFunction({ - invocations: [ - { - scriptHash: '0xd2a4cff31913016155e38e474a2c06d08be276cf', - operation: 'transfer', - args: [ - { type: 'Hash160', value: publicAccount.address }, - { type: 'Hash160', value: 'NbnjKGMBJzJ6j5PHeYhjJDaQ5Vy5UYu4Fv' }, - { type: 'Integer', value: '100000000' }, - { type: 'Array', value: [] }, - ], - }, - ], + ...transferInvocation(gasScriptHash, publicAccount, new wallet.Account(), '100'), signers: [ { account: publicAccount.scriptHash, @@ -98,33 +107,23 @@ describe('NeonInvoker', function () { }) assert(txId.length > 0, 'has txId') - await wait(15000) + await wait(waitTime) }) it('can sign and invoke using different NeonInvokers/accounts', async () => { - const accountPayer = new wallet.Account('fb1f57cc1347ae5b6251dc8bae761362d2ecaafec4c87f4dc9e97fef6dd75014') // NbnjKGMBJzJ6j5PHeYhjJDaQ5Vy5UYu4Fv - const accountOwner = new wallet.Account('3bd06d95e9189385851aa581d182f25de34af759cf7f883af57030303ded52b8') // NhGomBpYnKXArr55nHRQ5rzy79TwKVXZbr + const accountPayer = account1 + const accountOwner = account2 // TEST WITH BOTH ACCOUNTS ON THE SAME INVOKER const invokerBoth = await NeonInvoker.init({ - rpcAddress: NeonInvoker.TESTNET, + rpcAddress, account: [accountPayer, accountOwner], }) const txBoth = await invokerBoth.invokeFunction({ - invocations: [ - { - scriptHash: '0xd2a4cff31913016155e38e474a2c06d08be276cf', - operation: 'transfer', - args: [ - { type: 'Hash160', value: accountOwner.address }, // owner is sending to payer but the payer is paying for the tx - { type: 'Hash160', value: accountPayer.address }, - { type: 'Integer', value: '100000000' }, - { type: 'Array', value: [] }, - ], - }, - ], + // owner is sending GAS to payer, but the payer is paying for the tx + ...transferInvocation(gasScriptHash, accountOwner, accountPayer, '100'), signers: [ { account: accountPayer.scriptHash, @@ -139,36 +138,27 @@ describe('NeonInvoker', function () { assert(txBoth.length > 0, 'has txId') - await wait(15000) + await wait(waitTime) // TEST WITH EACH ACCOUNT ON A DIFFERENT INVOKER const invokerPayer = await NeonInvoker.init({ - rpcAddress: NeonInvoker.TESTNET, + rpcAddress, account: accountPayer, }) const invokerOwner = await NeonInvoker.init({ - rpcAddress: NeonInvoker.TESTNET, + rpcAddress, account: accountOwner, }) const payerBalance = await getBalance(invokerPayer, accountPayer.address) const ownerBalance = await getBalance(invokerOwner, accountOwner.address) + const amount = 50000000 const bt = await invokerPayer.signTransaction({ - invocations: [ - { - scriptHash: '0xd2a4cff31913016155e38e474a2c06d08be276cf', - operation: 'transfer', - args: [ - { type: 'Hash160', value: accountOwner.address }, // owner is sending to payer but the payer is paying for the tx - { type: 'Hash160', value: accountPayer.address }, - { type: 'Integer', value: '100000000' }, - { type: 'Array', value: [] }, - ], - }, - ], + // owner is sending GAS to payer, but the payer is paying for the tx + ...transferInvocation(gasScriptHash, accountOwner, accountPayer, amount.toString()), signers: [ { account: accountPayer.scriptHash, @@ -185,32 +175,34 @@ describe('NeonInvoker', function () { assert(txId.length > 0, 'has txId') - await wait(15000) + await wait(waitTime) + + const payerBalanceAfter = await getBalance(invokerPayer, accountPayer.address) + const ownerBalanceAfter = await getBalance(invokerOwner, accountOwner.address) - const payerBalance2 = await getBalance(invokerPayer, accountPayer.address) - const ownerBalance2 = await getBalance(invokerOwner, accountOwner.address) + const totalFees = Number(bt.systemFee) + Number(bt.networkFee) assert( - payerBalance2 > payerBalance + 0.8, - `payer balance (${payerBalance2}) increased by almost 1 (was ${payerBalance})`, + payerBalance - totalFees + amount === payerBalanceAfter, + `payer balance (was ${payerBalance}) should be ${payerBalance - totalFees + amount} but is ${payerBalanceAfter}`, ) - assert( - payerBalance2 < payerBalance + 1, - `payer balance (${payerBalance2}) increased by almost 1 (was ${payerBalance})`, + assert.equal( + ownerBalanceAfter, + ownerBalance - amount, + `owner balance (was ${ownerBalance}) should be ${ownerBalance - totalFees + amount} but is ${ownerBalanceAfter}`, ) - assert.equal(ownerBalance2, ownerBalance - 1, 'owner balance decreased by 1') - await wait(15000) + await wait(waitTime) }) it('can sign and invoke with signingCallback using different NeonInvokers/accounts', async () => { - const accountSignCallback = new wallet.Account('02eecb8c0c3ae4e3c65457581c8c8dc0ecf52f74953166ce84d3c5b67a42a1ee73') - const privateAccount = new wallet.Account('3bd06d95e9189385851aa581d182f25de34af759cf7f883af57030303ded52b8') + const privateAccount = account1 + const accountSignCallback = new wallet.Account(account1.publicKey) - const accountSignPrivKey = new wallet.Account('fb1f57cc1347ae5b6251dc8bae761362d2ecaafec4c87f4dc9e97fef6dd75014') // NbnjKGMBJzJ6j5PHeYhjJDaQ5Vy5UYu4Fv + const accountSignPrivKey = account2 const invokerSignCallback = await NeonInvoker.init({ - rpcAddress: NeonInvoker.TESTNET, + rpcAddress, signingCallback: async (transaction, details) => { const hex = NeonParser.numToHex(details.network, 4, true) + NeonParser.reverseHex(transaction.hash()) return wallet.sign(hex, privateAccount.privateKey) @@ -219,23 +211,12 @@ describe('NeonInvoker', function () { }) const invokerSignPrivKey = await NeonInvoker.init({ - rpcAddress: NeonInvoker.TESTNET, + rpcAddress, account: accountSignPrivKey, }) let bt = await invokerSignCallback.signTransaction({ - invocations: [ - { - scriptHash: '0xd2a4cff31913016155e38e474a2c06d08be276cf', - operation: 'transfer', - args: [ - { type: 'Hash160', value: accountSignCallback.address }, - { type: 'Hash160', value: accountSignPrivKey.address }, - { type: 'Integer', value: '100000000' }, - { type: 'Array', value: [] }, - ], - }, - ], + ...transferInvocation(gasScriptHash, accountSignCallback, accountSignPrivKey, '100000000'), signers: [ { account: accountSignCallback.scriptHash, @@ -252,21 +233,10 @@ describe('NeonInvoker', function () { assert(txId.length > 0, 'has txId') - await wait(15000) + await wait(waitTime) bt = await invokerSignPrivKey.signTransaction({ - invocations: [ - { - scriptHash: '0xd2a4cff31913016155e38e474a2c06d08be276cf', - operation: 'transfer', - args: [ - { type: 'Hash160', value: accountSignPrivKey.address }, - { type: 'Hash160', value: accountSignCallback.address }, - { type: 'Integer', value: '100000000' }, - { type: 'Array', value: [] }, - ], - }, - ], + ...transferInvocation(gasScriptHash, accountSignPrivKey, accountSignCallback, '100000000'), signers: [ { account: accountSignPrivKey.scriptHash, @@ -283,21 +253,25 @@ describe('NeonInvoker', function () { assert(txId.length > 0, 'has txId') - await wait(15000) + const appLog = await neonEventListener.waitForApplicationLog(txId) + assert( + appLog.executions[0].stack[0].value === true, + `transfer was not successful (${appLog.executions[0].stack[0].value})`, + ) }) it('add accounts and witnesses to verify smart contracts', async () => { - const account = new wallet.Account('3bd06d95e9189385851aa581d182f25de34af759cf7f883af57030303ded52b8') + const account = account1 const invoker = await NeonInvoker.init({ - rpcAddress: NeonInvoker.TESTNET, + rpcAddress, account, }) // A smart contract that always return True on verify - const verifyTrueSmartContract = '0x7aa88cc764b80cae2267d4fdf63cd09f7e9baeba' + const verifyTrueSmartContract = verifiableContract // NeoToken smart contract, we are not verified - const verifyFalseSmartContract = '0xef4073a0f2b305a38ec4050e4d3d28bc40ea63f5' + const verifyFalseSmartContract = neoScriptHash const txIdVerifyTrue = await invoker.invokeFunction({ invocations: [ @@ -317,6 +291,8 @@ describe('NeonInvoker', function () { scopes: 'CalledByEntry', }, ], + // There is currently a problem with the networkfee when using a contract as a signer, so some extra GAS will be used https://github.com/neo-project/neo/issues/2805 + extraNetworkFee: 200000, }) assert(txIdVerifyTrue.length > 0, 'has txId') @@ -341,39 +317,26 @@ describe('NeonInvoker', function () { }, ], }), - { - message: /^Inventory verification failed/, - }, ) }) it("can throw an error if the signed transaction doesn't match the invocation", async () => { - const accountPayer = new wallet.Account('fb1f57cc1347ae5b6251dc8bae761362d2ecaafec4c87f4dc9e97fef6dd75014') // NbnjKGMBJzJ6j5PHeYhjJDaQ5Vy5UYu4Fv - const accountOwner = new wallet.Account('3bd06d95e9189385851aa581d182f25de34af759cf7f883af57030303ded52b8') // NhGomBpYnKXArr55nHRQ5rzy79TwKVXZbr + const accountPayer = account1 + const accountOwner = account2 const invokerPayer = await NeonInvoker.init({ - rpcAddress: NeonInvoker.TESTNET, + rpcAddress, account: accountPayer, }) const invokerOwner = await NeonInvoker.init({ - rpcAddress: NeonInvoker.TESTNET, + rpcAddress, account: accountOwner, }) const bt = await invokerPayer.signTransaction({ - invocations: [ - { - scriptHash: '0xd2a4cff31913016155e38e474a2c06d08be276cf', - operation: 'transfer', - args: [ - { type: 'Hash160', value: accountOwner.address }, // owner is sending to payer but the payer is paying for the tx - { type: 'Hash160', value: accountPayer.address }, - { type: 'Integer', value: '100000000' }, - { type: 'Array', value: [] }, - ], - }, - ], + // owner is sending to payer but the payer is paying for the tx + ...transferInvocation(gasScriptHash, accountOwner, accountPayer, '100000000'), signers: [ { account: accountPayer.scriptHash, @@ -402,18 +365,13 @@ describe('NeonInvoker', function () { }, ], }), - { - name: 'Error', - message: - 'The script in the BuiltTransaction is not the same as the one generated from the ContractInvocationMulti', - }, ) }) it('does calculateFee', async () => { - const account = new wallet.Account('3bd06d95e9189385851aa581d182f25de34af759cf7f883af57030303ded52b8') + const account = account1 const invoker = await NeonInvoker.init({ - rpcAddress: NeonInvoker.TESTNET, + rpcAddress, account, }) @@ -454,8 +412,14 @@ describe('NeonInvoker', function () { ...param, }) - assert(Number(networkFeeOverridden) === toDecimal(20000, 8), 'has networkFee overridden') - assert(Number(systemFeeOverridden) === toDecimal(10000, 8), 'has systemFee overridden') + assert( + parseFloat(networkFeeOverridden) === toDecimal(20000, 8), + `networkFee override is not equal (${parseFloat(networkFeeOverridden)} !== ${toDecimal(20000, 8)})`, + ) + assert( + parseFloat(systemFeeOverridden) === toDecimal(10000, 8), + `systemFee override is not equal (${parseFloat(systemFeeOverridden)} !== ${toDecimal(10000, 8)})`, + ) const { networkFee: networkFeeExtra, systemFee: systemFeeExtra } = await invoker.calculateFee({ extraNetworkFee: 20000, @@ -463,13 +427,24 @@ describe('NeonInvoker', function () { ...param, }) - assert(Number(networkFeeExtra) === Number(networkFee) + toDecimal(20000, 8), 'has networkFee overridden') - assert(Number(systemFeeExtra) === Number(systemFee) + toDecimal(10000, 8), 'has systemFee overridden') + assert( + parseFloat(networkFeeExtra).toFixed(8) === (parseFloat(networkFee) + toDecimal(20000, 8)).toFixed(8), + `extra networkFee is not equal (${parseFloat(networkFeeExtra).toFixed(8)} !== ${( + parseFloat(networkFee) + toDecimal(20000, 8) + ).toFixed(8)})`, + ) + + assert( + parseFloat(systemFeeExtra).toFixed(8) === (parseFloat(systemFee) + toDecimal(10000, 8)).toFixed(8), + `extra systemFee is not equal (${parseFloat(systemFeeExtra).toFixed(8)} !== ${( + parseFloat(systemFee) + toDecimal(10000, 8) + ).toFixed(8)})`, + ) }) it('does testInvoke', async () => { const invoker = await NeonInvoker.init({ - rpcAddress: NeonInvoker.TESTNET, + rpcAddress, }) const resp = await invoker.testInvoke({ @@ -491,7 +466,7 @@ describe('NeonInvoker', function () { it('can throw an error if testInvoke state is FAULT', async () => { const invoker = await NeonInvoker.init({ - rpcAddress: NeonInvoker.TESTNET, + rpcAddress, }) await assert.rejects( @@ -508,28 +483,23 @@ describe('NeonInvoker', function () { }, ], }), - { - name: 'Error', - message: - 'Execution state is FAULT. Exception: Method "transfer" with 3 parameter(s) doesn\'t exist in the contract 0xd2a4cff31913016155e38e474a2c06d08be276cf.', - }, ) }) it('handles integer return', async () => { const invoker = await NeonInvoker.init({ - rpcAddress: NeonInvoker.TESTNET, + rpcAddress, }) const resp = await invoker.testInvoke({ invocations: [ { - scriptHash: '0x7346e59b3b3516467390a11c390679ab46b37af3', + scriptHash: testReturnContract, operation: 'negative_number', args: [], }, { - scriptHash: '0x7346e59b3b3516467390a11c390679ab46b37af3', + scriptHash: testReturnContract, operation: 'return_same_int', args: [{ type: 'Integer', value: '1234' }], }, @@ -552,28 +522,28 @@ describe('NeonInvoker', function () { it('handles boolean return', async () => { const invoker = await NeonInvoker.init({ - rpcAddress: NeonInvoker.TESTNET, + rpcAddress, }) const resp = await invoker.testInvoke({ invocations: [ { - scriptHash: '0x7346e59b3b3516467390a11c390679ab46b37af3', + scriptHash: testReturnContract, operation: 'bool_true', args: [], }, { - scriptHash: '0x7346e59b3b3516467390a11c390679ab46b37af3', + scriptHash: testReturnContract, operation: 'bool_false', args: [], }, { - scriptHash: '0x7346e59b3b3516467390a11c390679ab46b37af3', + scriptHash: testReturnContract, operation: 'return_same_bool', args: [{ type: 'Boolean', value: true }], }, { - scriptHash: '0x7346e59b3b3516467390a11c390679ab46b37af3', + scriptHash: testReturnContract, operation: 'return_same_bool', args: [{ type: 'Boolean', value: false }], }, @@ -605,28 +575,28 @@ describe('NeonInvoker', function () { it('handles boolean return (again)', async () => { const invoker = await NeonInvoker.init({ - rpcAddress: NeonInvoker.TESTNET, + rpcAddress, }) const resp = await invoker.testInvoke({ invocations: [ { - scriptHash: '0x7346e59b3b3516467390a11c390679ab46b37af3', + scriptHash: testReturnContract, operation: 'bool_true', args: [], }, { - scriptHash: '0x7346e59b3b3516467390a11c390679ab46b37af3', + scriptHash: testReturnContract, operation: 'bool_false', args: [], }, { - scriptHash: '0x7346e59b3b3516467390a11c390679ab46b37af3', + scriptHash: testReturnContract, operation: 'return_same_bool', args: [{ type: 'Boolean', value: true }], }, { - scriptHash: '0x7346e59b3b3516467390a11c390679ab46b37af3', + scriptHash: testReturnContract, operation: 'return_same_bool', args: [{ type: 'Boolean', value: false }], }, @@ -658,13 +628,13 @@ describe('NeonInvoker', function () { it('handles array return', async () => { const invoker = await NeonInvoker.init({ - rpcAddress: NeonInvoker.TESTNET, + rpcAddress, }) const resp = await invoker.testInvoke({ invocations: [ { - scriptHash: '0x7346e59b3b3516467390a11c390679ab46b37af3', + scriptHash: testReturnContract, operation: 'positive_numbers', args: [], }, @@ -698,18 +668,18 @@ describe('NeonInvoker', function () { it('handles bytestring return', async () => { const invoker = await NeonInvoker.init({ - rpcAddress: NeonInvoker.TESTNET, + rpcAddress, }) const resp = await invoker.testInvoke({ invocations: [ { - scriptHash: '0x7346e59b3b3516467390a11c390679ab46b37af3', + scriptHash: testReturnContract, operation: 'return_str', args: [], }, { - scriptHash: '0x7346e59b3b3516467390a11c390679ab46b37af3', + scriptHash: testReturnContract, operation: 'return_bytes', args: [], }, @@ -732,13 +702,13 @@ describe('NeonInvoker', function () { it('handles array return (again)', async () => { const invoker = await NeonInvoker.init({ - rpcAddress: NeonInvoker.TESTNET, + rpcAddress, }) const resp = await invoker.testInvoke({ invocations: [ { - scriptHash: '0x7346e59b3b3516467390a11c390679ab46b37af3', + scriptHash: testReturnContract, operation: 'positive_numbers', args: [], }, @@ -772,13 +742,13 @@ describe('NeonInvoker', function () { it('handles map return', async () => { const invoker = await NeonInvoker.init({ - rpcAddress: NeonInvoker.TESTNET, + rpcAddress, }) const resp = await invoker.testInvoke({ invocations: [ { - scriptHash: '0x8b43ab0c83b7d12cf35a0e780072bc314a688796', + scriptHash: testReturnMapContract, operation: 'main', args: [], }, diff --git a/packages/neon-dappkit/src/NeonParser.spec.ts b/packages/neon-dappkit/test/NeonParser.spec.ts similarity index 99% rename from packages/neon-dappkit/src/NeonParser.spec.ts rename to packages/neon-dappkit/test/NeonParser.spec.ts index 07d5422..a83c1ff 100644 --- a/packages/neon-dappkit/src/NeonParser.spec.ts +++ b/packages/neon-dappkit/test/NeonParser.spec.ts @@ -1,4 +1,4 @@ -import { NeonParser } from '.' +import { NeonParser } from '../src' import { describe, it } from 'mocha' import * as assert from 'assert' import { RpcResponseStackItem } from '@cityofzion/neon-dappkit-types' diff --git a/packages/neon-dappkit/src/NeonSigner.spec.ts b/packages/neon-dappkit/test/NeonSigner.spec.ts similarity index 99% rename from packages/neon-dappkit/src/NeonSigner.spec.ts rename to packages/neon-dappkit/test/NeonSigner.spec.ts index 0d4c1b4..6481100 100644 --- a/packages/neon-dappkit/src/NeonSigner.spec.ts +++ b/packages/neon-dappkit/test/NeonSigner.spec.ts @@ -1,4 +1,4 @@ -import { NeonSigner, SignMessageVersion } from './index' +import { NeonSigner, SignMessageVersion } from '../src/index' import { wallet } from '@cityofzion/neon-js' import assert from 'assert' diff --git a/packages/neon-dappkit/test/helper.ts b/packages/neon-dappkit/test/helper.ts new file mode 100644 index 0000000..3ceeda6 --- /dev/null +++ b/packages/neon-dappkit/test/helper.ts @@ -0,0 +1,66 @@ +import { ContractInvocationMulti } from '@cityofzion/neon-dappkit-types' +import { NeonInvoker, NeonParser } from '../src/index' +import * as path from 'path' +import { wallet } from '@cityofzion/neon-core' + +export const rpcAddress = 'http://127.0.0.1:30222' +export const gasScriptHash = '0xd2a4cff31913016155e38e474a2c06d08be276cf' +export const neoScriptHash = '0xef4073a0f2b305a38ec4050e4d3d28bc40ea63f5' +export const waitTime = 1000 +export const neonEventListenerOptions = { + waitForApplicationLog: { maxAttempts: 10, waitMs: 100 }, + waitForEventMs: 100, +} + +export function wait(ms: number) { + return new Promise((resolve) => { + setTimeout(resolve, ms) + }) +} + +export function neoGoPath() { + return path.resolve(path.join(__dirname, '..', 'neogo', 'neogo')) +} + +export function getDataDir() { + return path.resolve(path.join(__dirname, '..', 'data')) +} + +export function toDecimal(num: number, decimal: number) { + return num / 10 ** decimal +} + +export function transferInvocation( + smartContract: string, + sender: wallet.Account, + receiver: wallet.Account, + amount: string, +): ContractInvocationMulti { + return { + invocations: [ + { + scriptHash: smartContract, + operation: 'transfer', + args: [ + { type: 'Hash160', value: sender.address }, + { type: 'Hash160', value: receiver.address }, + { type: 'Integer', value: amount }, + { type: 'String', value: 'test' }, + ], + }, + ], + } +} + +export async function getBalance(invoker: NeonInvoker, address: string) { + const payerBalanceResp = await invoker.testInvoke({ + invocations: [ + { + operation: 'balanceOf', + scriptHash: '0xd2a4cff31913016155e38e474a2c06d08be276cf', + args: [{ value: address, type: 'Hash160' }], + }, + ], + }) + return NeonParser.parseRpcResponse(payerBalanceResp.stack[0]) +} diff --git a/packages/neon-dappkit/test/setup-neo-go.ts b/packages/neon-dappkit/test/setup-neo-go.ts index aeec3f5..04b3e91 100644 --- a/packages/neon-dappkit/test/setup-neo-go.ts +++ b/packages/neon-dappkit/test/setup-neo-go.ts @@ -19,7 +19,7 @@ async function installNeoGo(): Promise { return goCompilerExecutablePath } - const version = '0.105.1' + const version = '0.106.0' const arch = process.arch let archType = 'arm64' diff --git a/packages/neon-dappkit/tsconfig.build.json b/packages/neon-dappkit/tsconfig.build.json new file mode 100644 index 0000000..2772261 --- /dev/null +++ b/packages/neon-dappkit/tsconfig.build.json @@ -0,0 +1,4 @@ +{ + "extends": "./tsconfig.json", + "exclude": ["test"] +} diff --git a/packages/neon-dappkit/tsconfig.json b/packages/neon-dappkit/tsconfig.json index eae38ce..ead3ee3 100644 --- a/packages/neon-dappkit/tsconfig.json +++ b/packages/neon-dappkit/tsconfig.json @@ -3,6 +3,6 @@ "compilerOptions": { "outDir": "./dist" }, - "include": ["src"], + "include": ["src", "test"], "exclude": ["node_modules"] }