From f08f674596727f086adbec728200d9099e5b1d82 Mon Sep 17 00:00:00 2001 From: Taylor Hulsmans Date: Mon, 4 Sep 2023 21:24:13 +0200 Subject: [PATCH] run cowsay from obsidian --- artifacts/ExampleClient.json | 236 +++++++++++++++++++++++ components/hooks/useExampleClient.tsx | 0 components/views/ReactView.tsx | 4 +- esbuild.config.mjs | 4 + main.tsx | 258 +++++++++++++++++++++++-- package-lock.json | 260 +++++++++++++++++++------- package.json | 3 + tsconfig.json | 2 + utils/canvas-internal.ts | 76 ++++++++ utils/canvas-util.ts | 50 +++++ utils/utils.ts | 10 + 11 files changed, 818 insertions(+), 85 deletions(-) create mode 100644 artifacts/ExampleClient.json create mode 100644 components/hooks/useExampleClient.tsx create mode 100644 utils/canvas-internal.ts create mode 100644 utils/canvas-util.ts create mode 100644 utils/utils.ts diff --git a/artifacts/ExampleClient.json b/artifacts/ExampleClient.json new file mode 100644 index 0000000..4d4bc8c --- /dev/null +++ b/artifacts/ExampleClient.json @@ -0,0 +1,236 @@ +{ + "address": "0x59f1F1e6ca5C3ddB64E8dbBEa12f31D9236d7e64", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "jobID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "cid", + "type": "string" + } + ], + "name": "ReceivedJobResults", + "type": "event" + }, + { + "inputs": [], + "name": "_contractAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fetchAllResults", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "jobID", + "type": "uint256" + }, + { + "internalType": "string", + "name": "cid", + "type": "string" + }, + { + "internalType": "string", + "name": "httpString", + "type": "string" + } + ], + "internalType": "struct ExampleClient.Result[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lilypadFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_jobID", + "type": "uint256" + }, + { + "internalType": "string", + "name": "_cid", + "type": "string" + } + ], + "name": "receiveJobResults", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "results", + "outputs": [ + { + "internalType": "uint256", + "name": "jobID", + "type": "uint256" + }, + { + "internalType": "string", + "name": "cid", + "type": "string" + }, + { + "internalType": "string", + "name": "httpString", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "sayWhat", + "type": "string" + } + ], + "name": "runCowsay", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "params", + "type": "string" + } + ], + "name": "runModule", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "prompt", + "type": "string" + } + ], + "name": "runSDXL", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "prompt", + "type": "string" + } + ], + "name": "runStablediffusion", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_fee", + "type": "uint256" + } + ], + "name": "setLilypadFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x6080604052600280553480156200001557600080fd5b50604051620018253803806200182583398181016040528101906200003b91906200019f565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603620000ad576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000a49062000258565b60405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506200027a565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062000167826200013a565b9050919050565b62000179816200015a565b81146200018557600080fd5b50565b60008151905062000199816200016e565b92915050565b600060208284031215620001b857620001b762000135565b5b6000620001c88482850162000188565b91505092915050565b600082825260208201905092915050565b7f4e616976654578616d706c6573436c69656e743a20636f6e747261637420636160008201527f6e6e6f74206265207a65726f2061646472657373000000000000000000000000602082015250565b600062000240603483620001d1565b91506200024d82620001e2565b604082019050919050565b60006020820190508181036000830152620002738162000231565b9050919050565b61159b806200028a6000396000f3fe6080604052600436106100915760003560e01c8063bd37d3a511610059578063bd37d3a514610189578063cabc00d1146101b2578063e1dc7a20146101e2578063e7ec0c4a1461020d578063ef2e09111461023d57610091565b80631b0c27da1461009657806337988767146100d557806347906229146101005780634c8f4468146101305780637a49436214610160575b600080fd5b3480156100a257600080fd5b506100bd60048036038101906100b89190610a49565b610268565b6040516100cc93929190610b15565b60405180910390f35b3480156100e157600080fd5b506100ea6103b2565b6040516100f79190610b9b565b60405180910390f35b61011a60048036038101906101159190610ceb565b6103d6565b6040516101279190610d63565b60405180910390f35b61014a60048036038101906101459190610d7e565b6104f9565b6040516101579190610d63565b60405180910390f35b34801561016c57600080fd5b5061018760048036038101906101829190610e27565b6105b9565b005b34801561019557600080fd5b506101b060048036038101906101ab9190610a49565b6106e2565b005b6101cc60048036038101906101c79190610d7e565b6106ec565b6040516101d99190610d63565b60405180910390f35b3480156101ee57600080fd5b506101f76107ac565b6040516102049190610d63565b60405180910390f35b61022760048036038101906102229190610d7e565b6107b2565b6040516102349190610d63565b60405180910390f35b34801561024957600080fd5b50610252610872565b60405161025f9190610ff9565b60405180910390f35b6003818154811061027857600080fd5b90600052602060002090600302016000915090508060000154908060010180546102a19061104a565b80601f01602080910402602001604051908101604052809291908181526020018280546102cd9061104a565b801561031a5780601f106102ef5761010080835404028352916020019161031a565b820191906000526020600020905b8154815290600101906020018083116102fd57829003601f168201915b50505050509080600201805461032f9061104a565b80601f016020809104026020016040519081016040528092919081815260200182805461035b9061104a565b80156103a85780601f1061037d576101008083540402835291602001916103a8565b820191906000526020600020905b81548152906001019060200180831161038b57829003601f168201915b5050505050905083565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000670de0b6b3a76400006002546103ee91906110aa565b34146040516020016103ff90611143565b6040516020818303038152906040529061044f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104469190611158565b60405180910390fd5b50600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637ce7b1793485856040518463ffffffff1660e01b81526004016104ae92919061117a565b60206040518083038185885af11580156104cc573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906104f191906111c6565b905092915050565b6000670de0b6b3a764000060025461051191906110aa565b341460405160200161052290611143565b60405160208183030381529060405290610572576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105699190611158565b60405180910390fd5b506105b26040518060400160405280601281526020017f7364786c3a76302e392d6c696c79706164310000000000000000000000000000815250836103d6565b9050919050565b6000604051806060016040528085815260200184848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505081526020018484604051602001610629929190611264565b604051602081830303815290604052815250905060038190806001815401808255809150506001900390600052602060002090600302016000909190919091506000820151816000015560208201518160010190816106889190611434565b50604082015181600201908161069e9190611434565b5050507f22a1da116916c27b56df667a04ad3d734585a27bad5e29cc1e4aeef61f6f1ed38484846040516106d493929190611533565b60405180910390a150505050565b8060028190555050565b6000670de0b6b3a764000060025461070491906110aa565b341460405160200161071590611143565b60405160208183030381529060405290610765576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161075c9190611158565b60405180910390fd5b506107a56040518060400160405280600d81526020017f636f777361793a76302e302e3100000000000000000000000000000000000000815250836103d6565b9050919050565b60025481565b6000670de0b6b3a76400006002546107ca91906110aa565b34146040516020016107db90611143565b6040516020818303038152906040529061082b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108229190611158565b60405180910390fd5b5061086b6040518060400160405280601781526020017f737461626c655f646966667573696f6e3a76302e302e31000000000000000000815250836103d6565b9050919050565b60606003805480602002602001604051908101604052809291908181526020016000905b828210156109f65783829060005260206000209060030201604051806060016040529081600082015481526020016001820180546108d39061104a565b80601f01602080910402602001604051908101604052809291908181526020018280546108ff9061104a565b801561094c5780601f106109215761010080835404028352916020019161094c565b820191906000526020600020905b81548152906001019060200180831161092f57829003601f168201915b505050505081526020016002820180546109659061104a565b80601f01602080910402602001604051908101604052809291908181526020018280546109919061104a565b80156109de5780601f106109b3576101008083540402835291602001916109de565b820191906000526020600020905b8154815290600101906020018083116109c157829003601f168201915b50505050508152505081526020019060010190610896565b50505050905090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b610a2681610a13565b8114610a3157600080fd5b50565b600081359050610a4381610a1d565b92915050565b600060208284031215610a5f57610a5e610a09565b5b6000610a6d84828501610a34565b91505092915050565b610a7f81610a13565b82525050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610abf578082015181840152602081019050610aa4565b60008484015250505050565b6000601f19601f8301169050919050565b6000610ae782610a85565b610af18185610a90565b9350610b01818560208601610aa1565b610b0a81610acb565b840191505092915050565b6000606082019050610b2a6000830186610a76565b8181036020830152610b3c8185610adc565b90508181036040830152610b508184610adc565b9050949350505050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610b8582610b5a565b9050919050565b610b9581610b7a565b82525050565b6000602082019050610bb06000830184610b8c565b92915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610bf882610acb565b810181811067ffffffffffffffff82111715610c1757610c16610bc0565b5b80604052505050565b6000610c2a6109ff565b9050610c368282610bef565b919050565b600067ffffffffffffffff821115610c5657610c55610bc0565b5b610c5f82610acb565b9050602081019050919050565b82818337600083830152505050565b6000610c8e610c8984610c3b565b610c20565b905082815260208101848484011115610caa57610ca9610bbb565b5b610cb5848285610c6c565b509392505050565b600082601f830112610cd257610cd1610bb6565b5b8135610ce2848260208601610c7b565b91505092915050565b60008060408385031215610d0257610d01610a09565b5b600083013567ffffffffffffffff811115610d2057610d1f610a0e565b5b610d2c85828601610cbd565b925050602083013567ffffffffffffffff811115610d4d57610d4c610a0e565b5b610d5985828601610cbd565b9150509250929050565b6000602082019050610d786000830184610a76565b92915050565b600060208284031215610d9457610d93610a09565b5b600082013567ffffffffffffffff811115610db257610db1610a0e565b5b610dbe84828501610cbd565b91505092915050565b600080fd5b600080fd5b60008083601f840112610de757610de6610bb6565b5b8235905067ffffffffffffffff811115610e0457610e03610dc7565b5b602083019150836001820283011115610e2057610e1f610dcc565b5b9250929050565b600080600060408486031215610e4057610e3f610a09565b5b6000610e4e86828701610a34565b935050602084013567ffffffffffffffff811115610e6f57610e6e610a0e565b5b610e7b86828701610dd1565b92509250509250925092565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b610ebc81610a13565b82525050565b600082825260208201905092915050565b6000610ede82610a85565b610ee88185610ec2565b9350610ef8818560208601610aa1565b610f0181610acb565b840191505092915050565b6000606083016000830151610f246000860182610eb3565b5060208301518482036020860152610f3c8282610ed3565b91505060408301518482036040860152610f568282610ed3565b9150508091505092915050565b6000610f6f8383610f0c565b905092915050565b6000602082019050919050565b6000610f8f82610e87565b610f998185610e92565b935083602082028501610fab85610ea3565b8060005b85811015610fe75784840389528151610fc88582610f63565b9450610fd383610f77565b925060208a01995050600181019050610faf565b50829750879550505050505092915050565b600060208201905081810360008301526110138184610f84565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061106257607f821691505b6020821081036110755761107461101b565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006110b582610a13565b91506110c083610a13565b92508282026110ce81610a13565b915082820484148315176110e5576110e461107b565b5b5092915050565b600081905092915050565b7f5061796d656e74206f6620322045746865722069732072657175697265640000600082015250565b600061112d601e836110ec565b9150611138826110f7565b601e82019050919050565b600061114e82611120565b9150819050919050565b600060208201905081810360008301526111728184610adc565b905092915050565b600060408201905081810360008301526111948185610adc565b905081810360208301526111a88184610adc565b90509392505050565b6000815190506111c081610a1d565b92915050565b6000602082840312156111dc576111db610a09565b5b60006111ea848285016111b1565b91505092915050565b7f68747470733a2f2f697066732e696f2f697066732f0000000000000000000000600082015250565b60006112296015836110ec565b9150611234826111f3565b601582019050919050565b600061124b83856110ec565b9350611258838584610c6c565b82840190509392505050565b600061126f8261121c565b915061127c82848661123f565b91508190509392505050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026112ea7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826112ad565b6112f486836112ad565b95508019841693508086168417925050509392505050565b6000819050919050565b600061133161132c61132784610a13565b61130c565b610a13565b9050919050565b6000819050919050565b61134b83611316565b61135f61135782611338565b8484546112ba565b825550505050565b600090565b611374611367565b61137f818484611342565b505050565b5b818110156113a35761139860008261136c565b600181019050611385565b5050565b601f8211156113e8576113b981611288565b6113c28461129d565b810160208510156113d1578190505b6113e56113dd8561129d565b830182611384565b50505b505050565b600082821c905092915050565b600061140b600019846008026113ed565b1980831691505092915050565b600061142483836113fa565b9150826002028217905092915050565b61143d82610a85565b67ffffffffffffffff81111561145657611455610bc0565b5b611460825461104a565b61146b8282856113a7565b600060209050601f83116001811461149e576000841561148c578287015190505b6114968582611418565b8655506114fe565b601f1984166114ac86611288565b60005b828110156114d4578489015182556001820191506020850194506020810190506114af565b868310156114f157848901516114ed601f8916826113fa565b8355505b6001600288020188555050505b505050505050565b60006115128385610a90565b935061151f838584610c6c565b61152883610acb565b840190509392505050565b60006040820190506115486000830186610a76565b818103602083015261155b818486611506565b905094935050505056fea2646970667358221220b54e5c1f3b6b61986572c44c35332b4f3a38c7c50b40395bfb8c7976110962d164736f6c63430008130033", + "deployedBytecode": "0x6080604052600436106100915760003560e01c8063bd37d3a511610059578063bd37d3a514610189578063cabc00d1146101b2578063e1dc7a20146101e2578063e7ec0c4a1461020d578063ef2e09111461023d57610091565b80631b0c27da1461009657806337988767146100d557806347906229146101005780634c8f4468146101305780637a49436214610160575b600080fd5b3480156100a257600080fd5b506100bd60048036038101906100b89190610a49565b610268565b6040516100cc93929190610b15565b60405180910390f35b3480156100e157600080fd5b506100ea6103b2565b6040516100f79190610b9b565b60405180910390f35b61011a60048036038101906101159190610ceb565b6103d6565b6040516101279190610d63565b60405180910390f35b61014a60048036038101906101459190610d7e565b6104f9565b6040516101579190610d63565b60405180910390f35b34801561016c57600080fd5b5061018760048036038101906101829190610e27565b6105b9565b005b34801561019557600080fd5b506101b060048036038101906101ab9190610a49565b6106e2565b005b6101cc60048036038101906101c79190610d7e565b6106ec565b6040516101d99190610d63565b60405180910390f35b3480156101ee57600080fd5b506101f76107ac565b6040516102049190610d63565b60405180910390f35b61022760048036038101906102229190610d7e565b6107b2565b6040516102349190610d63565b60405180910390f35b34801561024957600080fd5b50610252610872565b60405161025f9190610ff9565b60405180910390f35b6003818154811061027857600080fd5b90600052602060002090600302016000915090508060000154908060010180546102a19061104a565b80601f01602080910402602001604051908101604052809291908181526020018280546102cd9061104a565b801561031a5780601f106102ef5761010080835404028352916020019161031a565b820191906000526020600020905b8154815290600101906020018083116102fd57829003601f168201915b50505050509080600201805461032f9061104a565b80601f016020809104026020016040519081016040528092919081815260200182805461035b9061104a565b80156103a85780601f1061037d576101008083540402835291602001916103a8565b820191906000526020600020905b81548152906001019060200180831161038b57829003601f168201915b5050505050905083565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000670de0b6b3a76400006002546103ee91906110aa565b34146040516020016103ff90611143565b6040516020818303038152906040529061044f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104469190611158565b60405180910390fd5b50600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637ce7b1793485856040518463ffffffff1660e01b81526004016104ae92919061117a565b60206040518083038185885af11580156104cc573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906104f191906111c6565b905092915050565b6000670de0b6b3a764000060025461051191906110aa565b341460405160200161052290611143565b60405160208183030381529060405290610572576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105699190611158565b60405180910390fd5b506105b26040518060400160405280601281526020017f7364786c3a76302e392d6c696c79706164310000000000000000000000000000815250836103d6565b9050919050565b6000604051806060016040528085815260200184848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505081526020018484604051602001610629929190611264565b604051602081830303815290604052815250905060038190806001815401808255809150506001900390600052602060002090600302016000909190919091506000820151816000015560208201518160010190816106889190611434565b50604082015181600201908161069e9190611434565b5050507f22a1da116916c27b56df667a04ad3d734585a27bad5e29cc1e4aeef61f6f1ed38484846040516106d493929190611533565b60405180910390a150505050565b8060028190555050565b6000670de0b6b3a764000060025461070491906110aa565b341460405160200161071590611143565b60405160208183030381529060405290610765576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161075c9190611158565b60405180910390fd5b506107a56040518060400160405280600d81526020017f636f777361793a76302e302e3100000000000000000000000000000000000000815250836103d6565b9050919050565b60025481565b6000670de0b6b3a76400006002546107ca91906110aa565b34146040516020016107db90611143565b6040516020818303038152906040529061082b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108229190611158565b60405180910390fd5b5061086b6040518060400160405280601781526020017f737461626c655f646966667573696f6e3a76302e302e31000000000000000000815250836103d6565b9050919050565b60606003805480602002602001604051908101604052809291908181526020016000905b828210156109f65783829060005260206000209060030201604051806060016040529081600082015481526020016001820180546108d39061104a565b80601f01602080910402602001604051908101604052809291908181526020018280546108ff9061104a565b801561094c5780601f106109215761010080835404028352916020019161094c565b820191906000526020600020905b81548152906001019060200180831161092f57829003601f168201915b505050505081526020016002820180546109659061104a565b80601f01602080910402602001604051908101604052809291908181526020018280546109919061104a565b80156109de5780601f106109b3576101008083540402835291602001916109de565b820191906000526020600020905b8154815290600101906020018083116109c157829003601f168201915b50505050508152505081526020019060010190610896565b50505050905090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b610a2681610a13565b8114610a3157600080fd5b50565b600081359050610a4381610a1d565b92915050565b600060208284031215610a5f57610a5e610a09565b5b6000610a6d84828501610a34565b91505092915050565b610a7f81610a13565b82525050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610abf578082015181840152602081019050610aa4565b60008484015250505050565b6000601f19601f8301169050919050565b6000610ae782610a85565b610af18185610a90565b9350610b01818560208601610aa1565b610b0a81610acb565b840191505092915050565b6000606082019050610b2a6000830186610a76565b8181036020830152610b3c8185610adc565b90508181036040830152610b508184610adc565b9050949350505050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610b8582610b5a565b9050919050565b610b9581610b7a565b82525050565b6000602082019050610bb06000830184610b8c565b92915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610bf882610acb565b810181811067ffffffffffffffff82111715610c1757610c16610bc0565b5b80604052505050565b6000610c2a6109ff565b9050610c368282610bef565b919050565b600067ffffffffffffffff821115610c5657610c55610bc0565b5b610c5f82610acb565b9050602081019050919050565b82818337600083830152505050565b6000610c8e610c8984610c3b565b610c20565b905082815260208101848484011115610caa57610ca9610bbb565b5b610cb5848285610c6c565b509392505050565b600082601f830112610cd257610cd1610bb6565b5b8135610ce2848260208601610c7b565b91505092915050565b60008060408385031215610d0257610d01610a09565b5b600083013567ffffffffffffffff811115610d2057610d1f610a0e565b5b610d2c85828601610cbd565b925050602083013567ffffffffffffffff811115610d4d57610d4c610a0e565b5b610d5985828601610cbd565b9150509250929050565b6000602082019050610d786000830184610a76565b92915050565b600060208284031215610d9457610d93610a09565b5b600082013567ffffffffffffffff811115610db257610db1610a0e565b5b610dbe84828501610cbd565b91505092915050565b600080fd5b600080fd5b60008083601f840112610de757610de6610bb6565b5b8235905067ffffffffffffffff811115610e0457610e03610dc7565b5b602083019150836001820283011115610e2057610e1f610dcc565b5b9250929050565b600080600060408486031215610e4057610e3f610a09565b5b6000610e4e86828701610a34565b935050602084013567ffffffffffffffff811115610e6f57610e6e610a0e565b5b610e7b86828701610dd1565b92509250509250925092565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b610ebc81610a13565b82525050565b600082825260208201905092915050565b6000610ede82610a85565b610ee88185610ec2565b9350610ef8818560208601610aa1565b610f0181610acb565b840191505092915050565b6000606083016000830151610f246000860182610eb3565b5060208301518482036020860152610f3c8282610ed3565b91505060408301518482036040860152610f568282610ed3565b9150508091505092915050565b6000610f6f8383610f0c565b905092915050565b6000602082019050919050565b6000610f8f82610e87565b610f998185610e92565b935083602082028501610fab85610ea3565b8060005b85811015610fe75784840389528151610fc88582610f63565b9450610fd383610f77565b925060208a01995050600181019050610faf565b50829750879550505050505092915050565b600060208201905081810360008301526110138184610f84565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061106257607f821691505b6020821081036110755761107461101b565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006110b582610a13565b91506110c083610a13565b92508282026110ce81610a13565b915082820484148315176110e5576110e461107b565b5b5092915050565b600081905092915050565b7f5061796d656e74206f6620322045746865722069732072657175697265640000600082015250565b600061112d601e836110ec565b9150611138826110f7565b601e82019050919050565b600061114e82611120565b9150819050919050565b600060208201905081810360008301526111728184610adc565b905092915050565b600060408201905081810360008301526111948185610adc565b905081810360208301526111a88184610adc565b90509392505050565b6000815190506111c081610a1d565b92915050565b6000602082840312156111dc576111db610a09565b5b60006111ea848285016111b1565b91505092915050565b7f68747470733a2f2f697066732e696f2f697066732f0000000000000000000000600082015250565b60006112296015836110ec565b9150611234826111f3565b601582019050919050565b600061124b83856110ec565b9350611258838584610c6c565b82840190509392505050565b600061126f8261121c565b915061127c82848661123f565b91508190509392505050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026112ea7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826112ad565b6112f486836112ad565b95508019841693508086168417925050509392505050565b6000819050919050565b600061133161132c61132784610a13565b61130c565b610a13565b9050919050565b6000819050919050565b61134b83611316565b61135f61135782611338565b8484546112ba565b825550505050565b600090565b611374611367565b61137f818484611342565b505050565b5b818110156113a35761139860008261136c565b600181019050611385565b5050565b601f8211156113e8576113b981611288565b6113c28461129d565b810160208510156113d1578190505b6113e56113dd8561129d565b830182611384565b50505b505050565b600082821c905092915050565b600061140b600019846008026113ed565b1980831691505092915050565b600061142483836113fa565b9150826002028217905092915050565b61143d82610a85565b67ffffffffffffffff81111561145657611455610bc0565b5b611460825461104a565b61146b8282856113a7565b600060209050601f83116001811461149e576000841561148c578287015190505b6114968582611418565b8655506114fe565b601f1984166114ac86611288565b60005b828110156114d4578489015182556001820191506020850194506020810190506114af565b868310156114f157848901516114ed601f8916826113fa565b8355505b6001600288020188555050505b505050505050565b60006115128385610a90565b935061151f838584610c6c565b61152883610acb565b840190509392505050565b60006040820190506115486000830186610a76565b818103602083015261155b818486611506565b905094935050505056fea2646970667358221220b54e5c1f3b6b61986572c44c35332b4f3a38c7c50b40395bfb8c7976110962d164736f6c63430008130033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/components/hooks/useExampleClient.tsx b/components/hooks/useExampleClient.tsx new file mode 100644 index 0000000..e69de29 diff --git a/components/views/ReactView.tsx b/components/views/ReactView.tsx index 5ae9e49..40f3265 100644 --- a/components/views/ReactView.tsx +++ b/components/views/ReactView.tsx @@ -1,8 +1,10 @@ import { useApp } from 'components/hooks/useApp'; + export const ReactView = () => { const { vault } = useApp(); console.log('hello react') - return (

vault name: {vault.getName()}

); + return (

vault name: {vault.getName()}

); + }; \ No newline at end of file diff --git a/esbuild.config.mjs b/esbuild.config.mjs index 7bad251..2e66c47 100644 --- a/esbuild.config.mjs +++ b/esbuild.config.mjs @@ -1,6 +1,7 @@ import esbuild from "esbuild"; import process from "process"; import builtins from "builtin-modules"; +import { polyfillNode } from "esbuild-plugin-polyfill-node"; const banner = `/* @@ -38,6 +39,9 @@ const context = await esbuild.context({ sourcemap: prod ? false : "inline", treeShaking: true, outfile: "main.js", + plugins: [ + polyfillNode({}) + ] }); if (prod) { diff --git a/main.tsx b/main.tsx index c69e6aa..61fbc51 100644 --- a/main.tsx +++ b/main.tsx @@ -1,27 +1,56 @@ -import { App, Editor, MarkdownView, Modal, Notice, Plugin, PluginSettingTab, Setting, ItemView, WorkspaceLeaf } from 'obsidian'; +import { App, TFile, Editor, MarkdownView, Modal, Notice, Plugin, PluginSettingTab, Setting, ItemView, WorkspaceLeaf } from 'obsidian'; +import { AllCanvasNodeData } from 'obsidian/canvas' +import { CanvasView, addEdge } from './utils/canvas-util' + +import { Canvas, CanvasNode, CreateNodeOptions } from './utils/canvas-internal' import { ReactView } from './components/views/ReactView' import { createContext, StrictMode, useContext } from "react"; import { createRoot, Root } from 'react-dom/client' import { AppContext } from 'components/context/context'; const VIEW_TYPE_EXAMPLE = "example-view"; - - +import { ethers, Signer, Provider, JsonRpcProvider, Wallet } from 'ethers'; +import ExampleClient from './artifacts/ExampleClient.json' +interface ChainConfig { + name: string; + rpcUrl: string; + chainId: number; +} // Remember to rename these classes and interfaces! interface ObsidianLilypadSettings { - mySetting: string; + privateKey: string; + chain: ChainConfig } const DEFAULT_SETTINGS: ObsidianLilypadSettings = { - mySetting: 'default' + privateKey: '', + chain: { + name: 'lilypad', + rpcUrl: 'http://testnet.lilypadnetwork.org:8545', + chainId: 1337 + } } export default class ObsidianLilypad extends Plugin { settings: ObsidianLilypadSettings; + unloaded = false + provider: Provider + wallet: Wallet + signer: Signer + exampleClient: ethers.Contract + logDebug: (...args: unknown[]) => void = () => { } async onload() { await this.loadSettings(); + this.provider = new JsonRpcProvider(this.settings.chain.rpcUrl) + if (this.settings.privateKey) { + this.wallet = new Wallet(this.settings.privateKey, this.provider) + this.signer = this.wallet.connect(this.provider) + this.exampleClient = new ethers.Contract(ExampleClient.address, ExampleClient.abi, this.signer) + } else { + console.log('no private key detected, web3 not enabled') + } // This creates an icon in the left ribbon. const ribbonIconEl = this.addRibbonIcon('dice', 'Obsidian Lilypad', (evt: MouseEvent) => { @@ -37,21 +66,13 @@ export default class ObsidianLilypad extends Plugin { // This adds a simple command that can be triggered anywhere this.addCommand({ - id: 'open-sample-modal-simple', - name: 'Open sample modal (simple)', + id: 'runCowsay', + name: 'execute the cowsay program through a smart contract', callback: () => { - new SampleModal(this.app).open(); - } - }); - // This adds an editor command that can perform some operation on the current editor instance - this.addCommand({ - id: 'sample-editor-command', - name: 'Sample editor command', - editorCallback: (editor: Editor, view: MarkdownView) => { - console.log(editor.getSelection()); - editor.replaceSelection('Sample Editor Command'); + this.runCowsay() } }); + // This adds a complex command that can check whether the current state of the app allows execution of the command this.addCommand({ id: 'open-sample-modal-complex', @@ -88,6 +109,74 @@ export default class ObsidianLilypad extends Plugin { onunload() { } + async runCowsay() { + if (this.unloaded) return + + this.logDebug("Running Cowsay") + + const canvas = this.getActiveCanvas() + if (!canvas) { + this.logDebug('No active canvas') + return + } + const selection = canvas.selection + if (selection?.size !== 1) return + const values = Array.from(selection.values()) + const node = values[0] + if (node) { + await canvas.requestSave() + await sleep(200) + + const settings = this.settings + + const nodeData = node.getData() + let nodeText = await getNodeText(node) || '' + if (nodeText.length == 0) { + this.logDebug('no node Text found') + return + } + + const created = createNode(canvas, node, + { + text: `Calling Lilpad Cowsay with ${nodeText}`, + size: { height: placeholderNoteHeight } + }, + { + color: assistantColor, + chat_role: 'assistant' + } + ) + + try { + + const tx = await this.exampleClient.runCowsay( + nodeText, { + value: ethers.parseUnits('2', 'ether') + } + ) + + console.log('tx', tx) + created.setText(`success! tx hash: ${tx.hash}, fetching ipfs.io cid`) + + const res = await this.exampleClient.fetchAllResults() + console.log(res) + created.setText(`${res}`) + + + } catch (e) { + created.setText(`error :( ${e}`) + this.logDebug(`e: ${e}`) + } + + + + } + } + getActiveCanvas() { + const maybeCanvasView = this.app.workspace.getActiveViewOfType(ItemView) as CanvasView | null + return maybeCanvasView ? maybeCanvasView['canvas'] : null + } + async loadSettings() { this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); @@ -98,6 +187,28 @@ export default class ObsidianLilypad extends Plugin { } } +async function getNodeText(node: CanvasNode) { + const nodeData = node.getData() + switch (nodeData.type) { + case 'text': + return nodeData.text + case 'file': + return readFile(nodeData.file) + } +} + +async function readFile(path: string) { + const file = this.app.vault.getAbstractFileByPath(path) + if (file instanceof TFile) { + const body = await app.vault.read(file) + return `## ${file.basename}\n${body}` + } +} +const calcHeight = (options: { parentHeight: number, text: string }) => { + const calcTextHeight = Math.round(textPaddingHeight + pxPerLine * options.text.length / (minWidth / pxPerChar)) + return Math.max(options.parentHeight, calcTextHeight) +} + class SampleModal extends Modal { constructor(app: App) { super(app); @@ -132,9 +243,9 @@ class ObsidianLilypadSettingTab extends PluginSettingTab { .setDesc('It\'s a secret') .addText(text => text .setPlaceholder('Enter your Ethereum Private Key') - .setValue(this.plugin.settings.mySetting) + .setValue(this.plugin.settings.privateKey) .onChange(async (value) => { - this.plugin.settings.mySetting = value; + this.plugin.settings.privateKey = value; await this.plugin.saveSettings(); })); } @@ -170,4 +281,113 @@ class ExampleView extends ItemView { async onClose() { this.root?.unmount(); } +} +const minWidth = 360 + +/** + * Assumed pixel width per character + */ +const pxPerChar = 5 + +/** + * Assumed pixel height per line + */ +const pxPerLine = 28 + +/** + * Assumed height of top + bottom text area padding + */ +const textPaddingHeight = 12 + +/** + * Color for assistant notes: 6 == purple + */ +const assistantColor = "6" + +/** + * Margin between new notes + */ +const newNoteMargin = 60 + +/** + * Min height of new notes + */ +const minHeight = 60 + +/** + * Height to use for new empty note + */ +const emptyNoteHeight = 100 + +/** + * Height to use for placeholder note + */ +const placeholderNoteHeight = 60 + +const randomHexString = (len: number) => { + const t = [] + for (let n = 0; n < len; n++) { + t.push((16 * Math.random() | 0).toString(16)) + } + return t.join("") +} +const createNode = ( + canvas: Canvas, + parentNode: CanvasNode, + nodeOptions: CreateNodeOptions, + nodeData?: Partial +) => { + if (!canvas) { + throw new Error('Invalid arguments') + } + + const { text } = nodeOptions + const width = nodeOptions?.size?.width || Math.max(minWidth, parentNode?.width) + const height = nodeOptions?.size?.height + || Math.max(minHeight, (parentNode && calcHeight({ text, parentHeight: parentNode.height }))) + + const siblings = parent && canvas.getEdgesForNode(parentNode) + .filter(n => n.from.node.id == parentNode.id) + .map(e => e.to.node) + const siblingsRight = siblings && siblings.reduce((right, sib) => Math.max(right, sib.x + sib.width), 0) + const priorSibling = siblings[siblings.length - 1] + + // Position left at right of prior sibling, otherwise aligned with parent + const x = siblingsRight ? siblingsRight + newNoteMargin : parentNode.x + + // Position top at prior sibling top, otherwise offset below parent + const y = (priorSibling + ? priorSibling.y + : (parentNode.y + parentNode.height + newNoteMargin)) + // Using position=left, y value is treated as vertical center + + height * 0.5 + + const newNode = canvas.createTextNode( + { + pos: { x, y }, + position: 'left', + size: { height, width }, + text, + focus: false + } + ) + + if (nodeData) { + newNode.setData(nodeData) + } + + canvas.deselectAll() + canvas.addNode(newNode) + + addEdge(canvas, randomHexString(16), { + fromOrTo: "from", + side: "bottom", + node: parentNode, + }, { + fromOrTo: "to", + side: "top", + node: newNode, + }) + + return newNode } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index c401b22..34c3989 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,9 @@ "version": "1.0.0", "license": "MIT", "dependencies": { + "esbuild-plugin-polyfill-node": "^0.3.0", + "ethers": "^6.7.1", + "eventemitter3": "^5.0.1", "react": "^18.2.0", "react-dom": "^18.2.0" }, @@ -36,6 +39,11 @@ "node": ">=0.10.0" } }, + "node_modules/@adraffy/ens-normalize": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.9.2.tgz", + "integrity": "sha512-0h+FrQDqe2Wn+IIGFkTCd4aAwTJ+7834Ek1COohCyV26AXhwQ7WQaz+4F/nLOeVl/3BtWHOHLPsq46V8YB46Eg==" + }, "node_modules/@chainsafe/as-sha256": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/@chainsafe/as-sha256/-/as-sha256-0.3.1.tgz", @@ -88,7 +96,6 @@ "cpu": [ "arm" ], - "dev": true, "optional": true, "os": [ "android" @@ -104,7 +111,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "android" @@ -120,7 +126,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "android" @@ -136,7 +141,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "darwin" @@ -152,7 +156,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "darwin" @@ -168,7 +171,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "freebsd" @@ -184,7 +186,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "freebsd" @@ -200,7 +201,6 @@ "cpu": [ "arm" ], - "dev": true, "optional": true, "os": [ "linux" @@ -216,7 +216,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -232,7 +231,6 @@ "cpu": [ "ia32" ], - "dev": true, "optional": true, "os": [ "linux" @@ -248,7 +246,6 @@ "cpu": [ "loong64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -264,7 +261,6 @@ "cpu": [ "mips64el" ], - "dev": true, "optional": true, "os": [ "linux" @@ -280,7 +276,6 @@ "cpu": [ "ppc64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -296,7 +291,6 @@ "cpu": [ "riscv64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -312,7 +306,6 @@ "cpu": [ "s390x" ], - "dev": true, "optional": true, "os": [ "linux" @@ -328,7 +321,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -344,7 +336,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "netbsd" @@ -360,7 +351,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "openbsd" @@ -376,7 +366,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "sunos" @@ -392,7 +381,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "win32" @@ -408,7 +396,6 @@ "cpu": [ "ia32" ], - "dev": true, "optional": true, "os": [ "win32" @@ -424,7 +411,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "win32" @@ -805,6 +791,12 @@ "scrypt-js": "3.0.1" } }, + "node_modules/@ethersproject/json-wallets/node_modules/aes-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", + "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", + "dev": true + }, "node_modules/@ethersproject/keccak256": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", @@ -1251,6 +1243,11 @@ "dev": true, "peer": true }, + "node_modules/@jspm/core": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@jspm/core/-/core-2.0.1.tgz", + "integrity": "sha512-Lg3PnLp0QXpxwLIAuuJboLeRaIhrgJjeuh797QADg3xz8wGLugQOS5DpsE8A6i6Adgzf+bacllkKZG3J0tGfDw==" + }, "node_modules/@metamask/eth-sig-util": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz", @@ -1283,7 +1280,6 @@ "version": "1.7.1", "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.7.1.tgz", "integrity": "sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==", - "dev": true, "funding": [ { "type": "individual", @@ -1367,6 +1363,54 @@ "setimmediate": "^1.0.5" } }, + "node_modules/@nomicfoundation/ethereumjs-block/node_modules/ethers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", + "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abi": "5.7.0", + "@ethersproject/abstract-provider": "5.7.0", + "@ethersproject/abstract-signer": "5.7.0", + "@ethersproject/address": "5.7.0", + "@ethersproject/base64": "5.7.0", + "@ethersproject/basex": "5.7.0", + "@ethersproject/bignumber": "5.7.0", + "@ethersproject/bytes": "5.7.0", + "@ethersproject/constants": "5.7.0", + "@ethersproject/contracts": "5.7.0", + "@ethersproject/hash": "5.7.0", + "@ethersproject/hdnode": "5.7.0", + "@ethersproject/json-wallets": "5.7.0", + "@ethersproject/keccak256": "5.7.0", + "@ethersproject/logger": "5.7.0", + "@ethersproject/networks": "5.7.1", + "@ethersproject/pbkdf2": "5.7.0", + "@ethersproject/properties": "5.7.0", + "@ethersproject/providers": "5.7.2", + "@ethersproject/random": "5.7.0", + "@ethersproject/rlp": "5.7.0", + "@ethersproject/sha2": "5.7.0", + "@ethersproject/signing-key": "5.7.0", + "@ethersproject/solidity": "5.7.0", + "@ethersproject/strings": "5.7.0", + "@ethersproject/transactions": "5.7.0", + "@ethersproject/units": "5.7.0", + "@ethersproject/wallet": "5.7.0", + "@ethersproject/web": "5.7.1", + "@ethersproject/wordlists": "5.7.0" + } + }, "node_modules/@nomicfoundation/ethereumjs-blockchain": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-7.0.2.tgz", @@ -1570,6 +1614,54 @@ "setimmediate": "^1.0.5" } }, + "node_modules/@nomicfoundation/ethereumjs-statemanager/node_modules/ethers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", + "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abi": "5.7.0", + "@ethersproject/abstract-provider": "5.7.0", + "@ethersproject/abstract-signer": "5.7.0", + "@ethersproject/address": "5.7.0", + "@ethersproject/base64": "5.7.0", + "@ethersproject/basex": "5.7.0", + "@ethersproject/bignumber": "5.7.0", + "@ethersproject/bytes": "5.7.0", + "@ethersproject/constants": "5.7.0", + "@ethersproject/contracts": "5.7.0", + "@ethersproject/hash": "5.7.0", + "@ethersproject/hdnode": "5.7.0", + "@ethersproject/json-wallets": "5.7.0", + "@ethersproject/keccak256": "5.7.0", + "@ethersproject/logger": "5.7.0", + "@ethersproject/networks": "5.7.1", + "@ethersproject/pbkdf2": "5.7.0", + "@ethersproject/properties": "5.7.0", + "@ethersproject/providers": "5.7.2", + "@ethersproject/random": "5.7.0", + "@ethersproject/rlp": "5.7.0", + "@ethersproject/sha2": "5.7.0", + "@ethersproject/signing-key": "5.7.0", + "@ethersproject/solidity": "5.7.0", + "@ethersproject/strings": "5.7.0", + "@ethersproject/transactions": "5.7.0", + "@ethersproject/units": "5.7.0", + "@ethersproject/wallet": "5.7.0", + "@ethersproject/web": "5.7.1", + "@ethersproject/wordlists": "5.7.0" + } + }, "node_modules/@nomicfoundation/ethereumjs-trie": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-6.0.2.tgz", @@ -2459,10 +2551,9 @@ } }, "node_modules/aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", - "dev": true + "version": "4.0.0-beta.5", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz", + "integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==" }, "node_modules/agent-base": { "version": "6.0.2", @@ -3199,7 +3290,6 @@ "version": "0.17.3", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.3.tgz", "integrity": "sha512-9n3AsBRe6sIyOc6kmoXg2ypCLgf3eZSraWFRpnkto+svt8cZNuKTkb1bhQcitBcvIqjNiK7K0J3KPmwGSfkA8g==", - "dev": true, "hasInstallScript": true, "bin": { "esbuild": "bin/esbuild" @@ -3232,6 +3322,18 @@ "@esbuild/win32-x64": "0.17.3" } }, + "node_modules/esbuild-plugin-polyfill-node": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/esbuild-plugin-polyfill-node/-/esbuild-plugin-polyfill-node-0.3.0.tgz", + "integrity": "sha512-SHG6CKUfWfYyYXGpW143NEZtcVVn8S/WHcEOxk62LuDXnY4Zpmc+WmxJKN6GMTgTClXJXhEM5KQlxKY6YjbucQ==", + "dependencies": { + "@jspm/core": "^2.0.1", + "import-meta-resolve": "^3.0.0" + }, + "peerDependencies": { + "esbuild": "*" + } + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -3550,14 +3652,13 @@ } }, "node_modules/ethers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", - "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", - "dev": true, + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.7.1.tgz", + "integrity": "sha512-qX5kxIFMfg1i+epfgb0xF4WM7IqapIIu50pOJ17aebkxxa4BacW5jFrQRmCJpDEg2ZK2oNtR5QjrQ1WDBF29dA==", "funding": [ { "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + "url": "https://github.com/sponsors/ethers-io/" }, { "type": "individual", @@ -3565,36 +3666,52 @@ } ], "dependencies": { - "@ethersproject/abi": "5.7.0", - "@ethersproject/abstract-provider": "5.7.0", - "@ethersproject/abstract-signer": "5.7.0", - "@ethersproject/address": "5.7.0", - "@ethersproject/base64": "5.7.0", - "@ethersproject/basex": "5.7.0", - "@ethersproject/bignumber": "5.7.0", - "@ethersproject/bytes": "5.7.0", - "@ethersproject/constants": "5.7.0", - "@ethersproject/contracts": "5.7.0", - "@ethersproject/hash": "5.7.0", - "@ethersproject/hdnode": "5.7.0", - "@ethersproject/json-wallets": "5.7.0", - "@ethersproject/keccak256": "5.7.0", - "@ethersproject/logger": "5.7.0", - "@ethersproject/networks": "5.7.1", - "@ethersproject/pbkdf2": "5.7.0", - "@ethersproject/properties": "5.7.0", - "@ethersproject/providers": "5.7.2", - "@ethersproject/random": "5.7.0", - "@ethersproject/rlp": "5.7.0", - "@ethersproject/sha2": "5.7.0", - "@ethersproject/signing-key": "5.7.0", - "@ethersproject/solidity": "5.7.0", - "@ethersproject/strings": "5.7.0", - "@ethersproject/transactions": "5.7.0", - "@ethersproject/units": "5.7.0", - "@ethersproject/wallet": "5.7.0", - "@ethersproject/web": "5.7.1", - "@ethersproject/wordlists": "5.7.0" + "@adraffy/ens-normalize": "1.9.2", + "@noble/hashes": "1.1.2", + "@noble/secp256k1": "1.7.1", + "@types/node": "18.15.13", + "aes-js": "4.0.0-beta.5", + "tslib": "2.4.0", + "ws": "8.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/ethers/node_modules/@noble/hashes": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.1.2.tgz", + "integrity": "sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/ethers/node_modules/@types/node": { + "version": "18.15.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.13.tgz", + "integrity": "sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==" + }, + "node_modules/ethers/node_modules/ws": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", + "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, "node_modules/ethjs-util": { @@ -3611,6 +3728,11 @@ "npm": ">=3" } }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" + }, "node_modules/evp_bytestokey": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", @@ -4303,6 +4425,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/import-meta-resolve": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-3.0.0.tgz", + "integrity": "sha512-4IwhLhNNA8yy445rPjD/lWh++7hMDOml2eHtd58eG7h+qK3EryMuuRbsHGPikCoAgIkkDnckKfWSk2iDla/ejg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -5835,8 +5966,7 @@ "node_modules/tslib": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", - "dev": true + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" }, "node_modules/tsort": { "version": "0.0.1", diff --git a/package.json b/package.json index 0321fd4..93996e5 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,9 @@ "typescript": "4.7.4" }, "dependencies": { + "esbuild-plugin-polyfill-node": "^0.3.0", + "ethers": "^6.7.1", + "eventemitter3": "^5.0.1", "react": "^18.2.0", "react-dom": "^18.2.0" } diff --git a/tsconfig.json b/tsconfig.json index 227d943..0eca524 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,8 @@ { "compilerOptions": { "jsx": "react-jsx", + "resolveJsonModule": true, + "esModuleInterop": true, "baseUrl": ".", "inlineSourceMap": true, "inlineSources": true, diff --git a/utils/canvas-internal.ts b/utils/canvas-internal.ts new file mode 100644 index 0000000..0f4cf33 --- /dev/null +++ b/utils/canvas-internal.ts @@ -0,0 +1,76 @@ +import { App } from 'obsidian' +import { AllCanvasNodeData, CanvasData } from 'obsidian/canvas' + +export interface CanvasNode { + id: string + app: App + canvas: Canvas + child: Partial + color: string + containerEl: HTMLElement + containerBlockerEl: HTMLElement + contentEl: HTMLElement + destroyted: boolean + height: number + initialized: boolean + isContentMounted: boolean + isEditing: boolean + nodeEl: HTMLElement + placeholderEl: HTMLElement + renderedZIndex: number + resizeDirty: boolean + text: string + unknownData: Record + width: number + x: number + y: number + zIndex: number + convertToFile(): Promise + focus(): void + getData(): AllCanvasNodeData + initialize(): void + moveAndResize(options: MoveAndResizeOptions): void + render(): void + setData(data: Partial): void + setText(text: string): Promise + showMenu(): void + startEditing(): void +} + +export interface MoveAndResizeOptions { + x?: number, y?: number, width?: number, height?: number +} + +export interface CanvasEdge { + from: { + node: CanvasNode + } + to: { + node: CanvasNode + } +} + +export interface Canvas { + edges: CanvasEdge[] + selection: Set + nodes: CanvasNode[] + wrapperEl: HTMLElement | null + addNode(node: CanvasNode): void + createTextNode(options: CreateNodeOptions): CanvasNode + deselectAll(): void + getData(): CanvasData + getEdgesForNode(node: CanvasNode): CanvasEdge[] + importData(data: { nodes: object[], edges: object[] }): void + removeNode(node: CanvasNode): void + requestFrame(): Promise + requestSave(): Promise + selectOnly(node: CanvasNode, startEditing: boolean): void +} + +export interface CreateNodeOptions { + text: string, + pos?: { x: number, y: number } + position?: 'left' | 'right' | 'top' | 'bottom', + size?: { height?: number, width?: number }, + focus?: boolean +} \ No newline at end of file diff --git a/utils/canvas-util.ts b/utils/canvas-util.ts new file mode 100644 index 0000000..10cf9fb --- /dev/null +++ b/utils/canvas-util.ts @@ -0,0 +1,50 @@ +import { ItemView } from 'obsidian' +import { Canvas } from './canvas-internal' + +interface CanvasEdge { + fromOrTo: string + side: string, + node: CanvasElement, +} + +interface CanvasElement { + id: string +} + +export type CanvasView = ItemView & { + canvas: Canvas +} + +/** + * Add edge entry to canvas. + */ +export const addEdge = (canvas: Canvas, edgeID: string, fromEdge: CanvasEdge, toEdge: CanvasEdge) => { + if (!canvas) return + + const data = canvas.getData() + + if (!data) return + + canvas.importData({ + "edges": [ + ...data.edges, + { "id": edgeID, "fromNode": fromEdge.node.id, "fromSide": fromEdge.side, "toNode": toEdge.node.id, "toSide": toEdge.side } + ], + "nodes": data.nodes, + }) + + canvas.requestFrame() +} + +/** + * Trap exception and write to console.error. + */ +export function trapError(fn: (...params: unknown[]) => T) { + return (...params: unknown[]) => { + try { + return fn(...params) + } catch (e) { + console.error(e) + } + } +} \ No newline at end of file diff --git a/utils/utils.ts b/utils/utils.ts new file mode 100644 index 0000000..98b1d9f --- /dev/null +++ b/utils/utils.ts @@ -0,0 +1,10 @@ +/** + * Generate a string of random hexadecimal chars + */ +export const randomHexString = (len: number) => { + const t = [] + for (let n = 0; n < len; n++) { + t.push((16 * Math.random() | 0).toString(16)) + } + return t.join("") +} \ No newline at end of file