From 6428d3e5b24c9b9d3f7fa2b8d610c84c731f027e Mon Sep 17 00:00:00 2001 From: Hunter Cote Date: Thu, 17 Oct 2024 18:11:53 -0400 Subject: [PATCH 1/3] add features (xchain tx, chainId selector) --- package.json | 1 + src/App.tsx | 336 ++++++++++++++++++++++++++++++++++++++++++--------- src/magic.ts | 27 +++-- src/utils.ts | 10 +- yarn.lock | 249 ++------------------------------------ 5 files changed, 309 insertions(+), 314 deletions(-) diff --git a/package.json b/package.json index 5bd4b52..48571a6 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "dependencies": { "@kadena/client": "^1.14.0", "@kadena/pactjs": "^0.4.3", + "@kadena/types": "^0.7.0", "@magic-ext/kadena": "^0.2.0", "@types/jest": "^27.0.1", "@types/node": "^16.7.13", diff --git a/src/App.tsx b/src/App.tsx index 64fa04e..f3954b0 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,38 +1,51 @@ -import { addSignatures, Pact } from "@kadena/client"; +import { addSignatures, ITransactionDescriptor, Pact, readKeyset } from "@kadena/client"; import { PactNumber } from "@kadena/pactjs"; import { MagicUserMetadata } from "magic-sdk"; import { useEffect, useState } from "react"; -import { magic } from "./magic"; -import { chainId, kadenaClient, networkId } from "./utils"; +import { createMagic } from "./magic"; +import { getKadenaClient, DEFAULT_CHAIN_ID, NETWORK_ID } from "./utils"; import { ReactComponent as ExternalLinkSVG } from "./external-link.svg"; +import { ChainId, ICommand, IPactDecimal, IUnsignedCommand } from '@kadena/types'; import "./App.css"; type AccountName = `k:${string}`; function App() { + const [magic, setMagic] = useState(createMagic()); + const [selectedChainId, setSelectedChainId] = useState(DEFAULT_CHAIN_ID); + + // User const [email, setEmail] = useState(""); const [isLoggedIn, setIsLoggedIn] = useState(false); - const [userMetadata, setUserMetadata] = useState(); - + const [userInfo, setUserInfo] = useState(); const [balance, setBalance] = useState(0); + // Same Chain Transaction const [disabled, setDisabled] = useState(false); const [toAccount, setToAccount] = useState(""); const [sendAmount, setSendAmount] = useState(""); + // Cross Chain Transaction + const [xDisabled, setXDisabled] = useState(false); + const [xToAccount, setXToAccount] = useState(""); + const [xSendAmount, setXSendAmount] = useState(""); + const [xChainId, setXChainId] = useState(''); + useEffect(() => { - magic.user.isLoggedIn().then(async (magicIsLoggedIn) => { - setIsLoggedIn(magicIsLoggedIn); - console.log("magicIsLoggedIn", magicIsLoggedIn); - if (magicIsLoggedIn) { - try { + const initAppState = async () => { + try { + const magicIsLoggedIn = await magic.user.isLoggedIn(); + console.log("magicIsLoggedIn", magicIsLoggedIn); + setIsLoggedIn(magicIsLoggedIn); + if (magicIsLoggedIn) { const userInfo = await getUserInfo(); getBalance(userInfo.publicAddress as AccountName); - } catch (error) { - console.error(error); } + } catch (error) { + console.error(error); } - }).catch(console.error); + }; + initAppState(); }, []); const login = async () => { @@ -47,82 +60,147 @@ function App() { } }; + const logout = async () => { + try { + await magic.user.logout(); + setIsLoggedIn(false); + } catch (error) { + console.error(error); + } + }; + const getUserInfo = async () => { - const metadata = await magic.user.getInfo(); - console.log("metadata", metadata); - setUserMetadata(metadata); - return metadata; + const user = await magic.user.getInfo(); + console.log("user", user); + setUserInfo(user); + return user; }; const getBalance = async (accountName: AccountName) => { + const kadenaClient = getKadenaClient(selectedChainId); try { const transaction = Pact.builder .execution((Pact.modules as any).coin["get-balance"](accountName)) - .setMeta({ chainId }) + .setMeta({ chainId: selectedChainId }) .createTransaction(); - const res = await kadenaClient.local(transaction, { preflight: false }); - if (res.result.status === "failure") { - console.error('Failed to get balance:', res.result.error); + const { result } = await kadenaClient.dirtyRead(transaction); + if (result.status === "failure") { + console.error('Failed to get balance:', result.error); setBalance(0); return; } - setBalance((res.result as any).data as number); + setBalance((result as any).data as number); } catch (error) { console.error("Failed to get balance:", error); } }; - const logout = async () => { + const handleChainIdChange = (cid: ChainId) => { + setSelectedChainId(cid); + setMagic(createMagic(cid)); + } + + const getAccountDetails = async (account: AccountName) => { + const kadenaClient = getKadenaClient(selectedChainId); try { - await magic.user.logout(); - setIsLoggedIn(false); + const transaction = Pact.builder + .execution((Pact.modules as any).coin.details(account)) + .setMeta({ chainId: selectedChainId }) + .setNetworkId(NETWORK_ID) + .createTransaction(); + const { result } = await kadenaClient.dirtyRead(transaction); + if (result.status === "failure") { + console.error((result.error as any).message); + return false; + } else { + console.log(result.data); + return true; + } } catch (error) { - console.error(error); + console.error("Failed to get account details", error); } }; - const handleSendTransaction = async () => { - if (!userMetadata?.publicAddress) return; - setDisabled(true); - - const senderPublicKey = userMetadata.publicAddress.substring(2); - const receiverPublicKey = toAccount.substring(2); - const amount = new PactNumber(sendAmount).toPactDecimal(); + const buildTransferTransaction = (from: AccountName, to: AccountName, amount: IPactDecimal) => { + const senderPublicKey = from.substring(2); + const receiverPublicKey = to.substring(2); + return Pact.builder + .execution((Pact.modules as any).coin.transfer(from, to, amount)) + .addData("receiverKeyset", { + keys: [receiverPublicKey], + pred: "keys-all", + }) + .addSigner(senderPublicKey, (withCapability: any) => [ + withCapability("coin.GAS"), + withCapability( + "coin.TRANSFER", + from, + toAccount, + amount + ), + ]) + .setMeta({ chainId: selectedChainId, senderAccount: from }) + .setNetworkId(NETWORK_ID) + .createTransaction(); + }; - const transaction = Pact.builder - .execution((Pact.modules as any).coin.transfer(userMetadata.publicAddress, toAccount, amount)) + const buildTransferCreateTransaction = (from: AccountName, to: AccountName, amount: IPactDecimal) => { + const senderPublicKey = from.substring(2); + const receiverPublicKey = to.substring(2); + return Pact.builder + .execution((Pact.modules as any).coin["transfer-create"]( + from, + to, + '(read-keyset "receiverKeyset")', + amount + )) .addData("receiverKeyset", { keys: [receiverPublicKey], pred: "keys-all", }) - .addSigner(senderPublicKey, (withCapability) => [ + .addSigner(senderPublicKey, (withCapability: any) => [ withCapability("coin.GAS"), withCapability( "coin.TRANSFER", - userMetadata.publicAddress, + from, toAccount, amount ), ]) - .setMeta({ chainId, senderAccount: userMetadata.publicAddress }) - .setNetworkId(networkId) + .setMeta({ chainId: selectedChainId, senderAccount: from }) + .setNetworkId(NETWORK_ID) .createTransaction(); + } + const handleSendTransaction = async () => { + if (!userInfo?.publicAddress) return; + setDisabled(true); + const kadenaClient = getKadenaClient(selectedChainId); try { - console.log("unsigned transaction", transaction); + const accountExists = await getAccountDetails(toAccount as AccountName); + const amount = new PactNumber(sendAmount).toPactDecimal(); + + let transaction: IUnsignedCommand; + + if (accountExists) { + transaction = await buildTransferTransaction(userInfo.publicAddress as AccountName, toAccount as AccountName, amount); + } else { + transaction = await buildTransferCreateTransaction(userInfo.publicAddress as AccountName, toAccount as AccountName, amount); + } + + console.log(accountExists ? 'account exists, sending `transfer` tx' : 'account does not exist, sending `transfer-create` tx'); const signature = await magic.kadena.signTransaction(transaction.hash); - console.log("signature", signature); const signedTx = addSignatures(transaction, signature); console.log("signed transaction", signedTx); - const transactionDescriptor = await kadenaClient.submit(signedTx); + const transactionDescriptor = await kadenaClient.submit(signedTx as ICommand); console.log("broadcasting transaction...", transactionDescriptor); - const response = await kadenaClient.listen(transactionDescriptor); + const { result } = await kadenaClient.listen(transactionDescriptor); setDisabled(false); - if (response.result.status === "failure") { - console.error(response.result.error); + if (result.status === "failure") { + console.error(result.error); } else { - getBalance(userMetadata.publicAddress as AccountName); - console.log(response.result); + console.log(result); + getBalance(userInfo.publicAddress as AccountName); } } catch (error) { console.error("Failed to send transaction", error); @@ -130,6 +208,111 @@ function App() { } }; + const handleSendXTransactionStart = async () => { + if (!userInfo?.publicAddress) return; + setXDisabled(true); + const kadenaClient = getKadenaClient(selectedChainId); + const amount = new PactNumber(xSendAmount).toPactDecimal(); + const senderPublicKey = userInfo?.publicAddress.substring(2); + const receiverPublicKey = xToAccount.substring(2); + + let transaction = Pact.builder + .execution( + (Pact.modules as any).coin.defpact['transfer-crosschain']( + userInfo.publicAddress, + xToAccount, + readKeyset('receiver-guard'), + xChainId, + amount, + ), + ) + .addSigner(senderPublicKey, (signFor: any) => [ + signFor('coin.GAS'), + signFor( + 'coin.TRANSFER_XCHAIN', + userInfo.publicAddress, + xToAccount, + amount, + xChainId, + ), + ]) + .addKeyset('receiver-guard', 'keys-all', receiverPublicKey) + .setMeta({ chainId: selectedChainId, senderAccount: userInfo.publicAddress }) + .setNetworkId(NETWORK_ID) + .createTransaction(); + + try { + const signature = await magic.kadena.signTransaction(transaction.hash); + const signedTx = addSignatures(transaction, signature); + console.log("signed transaction", signedTx); + const transactionDescriptor = await kadenaClient.submit(signedTx as ICommand); + console.log("broadcasting transaction...", transactionDescriptor); + const { result } = await kadenaClient.listen(transactionDescriptor); + if (result.status === "failure") { + console.error(result.error); + } else { + console.log('Transaction start result: success!', result); + getBalance(userInfo.publicAddress as AccountName); + await handleSendXTransactionFinish(transactionDescriptor); + } + } catch (error) { + console.error("Failed to send transaction", error); + setXDisabled(false); + } + }; + + const handleSendXTransactionFinish = async (transactionDescriptor: ITransactionDescriptor) => { + if (!userInfo?.publicAddress) return; + const kadenaClientStartingChain = getKadenaClient(selectedChainId); + const kadenaClientTargetChain = getKadenaClient(xChainId as ChainId); + try { + console.log('fetching proof for cross-chain transaction...'); + const proof = await kadenaClientStartingChain.pollCreateSpv(transactionDescriptor, xChainId as ChainId); + const status = await kadenaClientStartingChain.listen(transactionDescriptor); + console.log('status', status); + const pactId = status.continuation?.pactId ?? ''; + + const continuationTransaction = Pact.builder + .continuation({ + pactId, + proof, + rollback: false, + step: 1, + }) + .setNetworkId(NETWORK_ID) + .setMeta({ + chainId: xChainId as ChainId, + senderAccount: 'kadena-xchain-gas', + gasLimit: 850, // maximum value + }) + .createTransaction(); + const continuationTxDescriptor = await kadenaClientTargetChain.submit(continuationTransaction as ICommand); + console.log('broadcasting continuation transaction...', continuationTxDescriptor); + const { result } = await kadenaClientTargetChain.listen(continuationTxDescriptor); + setXDisabled(false); + if (result.status === "failure") { + console.error(result.error); + } else { + console.log('Transaction continuation result: success!', result); + } + } catch (error) { + setXDisabled(false); + console.error("Failed to complete cross-chain transaction", error); + } + }; + + const ChainIdSelector = () => { + return ( + + ); + }; + return (
{!isLoggedIn ? ( @@ -137,30 +320,44 @@ function App() {

Please sign up or login

setEmail(event.target.value)} + value={email} + onChange={(event) => setEmail(event.target.value)} />
) : (
-

Current user: {userMetadata?.email}

+

Current user: {userInfo?.email}

+
+

Select Chain ID

+ +

Kadena Account

+ +
+
+

Balance

Balance: {balance} KDA
+
-

Send Kadena

+

Send Kadena (same chain)

setToAccount(event.target.value)} + onChange={(event) => setToAccount(event.target.value)} /> setSendAmount(event.target.value)} + onChange={(event) => setSendAmount(event.target.value)} />
+
+

Cross Chain Transfer

+ setXToAccount(event.target.value)} + /> + setXSendAmount(event.target.value)} + /> + setXChainId(event.target.value)} + /> + +
)} diff --git a/src/magic.ts b/src/magic.ts index bf504a8..b258fb1 100644 --- a/src/magic.ts +++ b/src/magic.ts @@ -1,15 +1,18 @@ import { Magic } from 'magic-sdk'; import { KadenaExtension } from '@magic-ext/kadena' -import { chainId, rpcUrl, networkId } from './utils'; +import { getRpcUrl, DEFAULT_CHAIN_ID, NETWORK_ID } from './utils'; +import { ChainId } from '@kadena/types'; -export const magic = new Magic('pk_live_FAE58C542213B8AF', { - extensions: [ - new KadenaExtension({ - rpcUrl, - chainId, - networkId, - network: 'testnet', - createAccountsOnChain: false, - }), - ], -}); \ No newline at end of file +export const createMagic = (chainId?: ChainId) => { + return new Magic('pk_live_FAE58C542213B8AF', { + extensions: [ + new KadenaExtension({ + rpcUrl: getRpcUrl(chainId), + chainId: chainId || DEFAULT_CHAIN_ID, + networkId: NETWORK_ID, + network: 'testnet', + createAccountsOnChain: true, + }), + ], + }) +} \ No newline at end of file diff --git a/src/utils.ts b/src/utils.ts index 72681ac..59be418 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,7 +1,7 @@ -import { createClient } from "@kadena/client"; +import { ChainId, createClient } from "@kadena/client"; -export const chainId = '1'; -export const networkId = 'testnet04'; -export const rpcUrl = `https://api.testnet.chainweb.com/chainweb/0.0/${networkId}/chain/${chainId}/pact`; +export const DEFAULT_CHAIN_ID = '1'; +export const NETWORK_ID = 'testnet04'; -export const kadenaClient = createClient(rpcUrl); \ No newline at end of file +export const getRpcUrl = (chainId?: ChainId) => `https://api.testnet.chainweb.com/chainweb/0.0/${NETWORK_ID}/chain/${chainId || DEFAULT_CHAIN_ID}/pact`; +export const getKadenaClient = (chainId?: ChainId) => createClient(getRpcUrl(chainId || DEFAULT_CHAIN_ID)); diff --git a/yarn.lock b/yarn.lock index e3384a0..f0aee62 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,11 +2,6 @@ # yarn lockfile v1 -"@adobe/css-tools@^4.0.1": - version "4.4.0" - resolved "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.0.tgz" - integrity sha512-Ff9+ksdQQB3rMncgqDK78uLznstjyfIf2Arnh22pW8kBpLs6rpKDwgnZT46hin5Hl1WzazzK64DOrhSwYpS7bQ== - "@alloc/quick-lru@^5.2.0": version "5.2.0" resolved "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz" @@ -1108,7 +1103,7 @@ resolved "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz" integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== -"@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.3", "@babel/runtime@^7.8.4": version "7.25.6" resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz" integrity sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ== @@ -1506,13 +1501,6 @@ "@types/node" "*" jest-mock "^27.5.1" -"@jest/expect-utils@^29.7.0": - version "29.7.0" - resolved "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz" - integrity sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA== - dependencies: - jest-get-type "^29.6.3" - "@jest/fake-timers@^27.5.1": version "27.5.1" resolved "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz" @@ -1572,13 +1560,6 @@ dependencies: "@sinclair/typebox" "^0.24.1" -"@jest/schemas@^29.6.3": - version "29.6.3" - resolved "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz" - integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA== - dependencies: - "@sinclair/typebox" "^0.27.8" - "@jest/source-map@^27.5.1": version "27.5.1" resolved "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz" @@ -1662,18 +1643,6 @@ "@types/yargs" "^17.0.8" chalk "^4.0.0" -"@jest/types@^29.6.3": - version "29.6.3" - resolved "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz" - integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw== - dependencies: - "@jest/schemas" "^29.6.3" - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^3.0.0" - "@types/node" "*" - "@types/yargs" "^17.0.8" - chalk "^4.0.0" - "@jridgewell/gen-mapping@^0.3.2", "@jridgewell/gen-mapping@^0.3.5": version "0.3.5" resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz" @@ -1751,6 +1720,11 @@ dependencies: bignumber.js "^9.1.2" +"@kadena/types@^0.7.0": + version "0.7.0" + resolved "https://registry.yarnpkg.com/@kadena/types/-/types-0.7.0.tgz#de61e69e6defec6284d47ce00b22a76fa7ad0aba" + integrity sha512-CDPuIcF/AyhqXawfIlqel3kew8UA6rEBX81PMltN8eqaVS9nXTvA1SbU6d9qzFPzEgynoJ5N3QZht8BCr2oFVQ== + "@leichtgewicht/ip-codec@^2.0.1": version "2.0.5" resolved "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz" @@ -1975,11 +1949,6 @@ resolved "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz" integrity sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA== -"@sinclair/typebox@^0.27.8": - version "0.27.8" - resolved "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz" - integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== - "@sinonjs/commons@^1.7.0": version "1.8.6" resolved "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz" @@ -2241,51 +2210,6 @@ "@svgr/plugin-svgo" "^5.5.0" loader-utils "^2.0.0" -"@testing-library/dom@^8.5.0": - version "8.20.1" - resolved "https://registry.npmjs.org/@testing-library/dom/-/dom-8.20.1.tgz" - integrity sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/runtime" "^7.12.5" - "@types/aria-query" "^5.0.1" - aria-query "5.1.3" - chalk "^4.1.0" - dom-accessibility-api "^0.5.9" - lz-string "^1.5.0" - pretty-format "^27.0.2" - -"@testing-library/jest-dom@^5.14.1": - version "5.17.0" - resolved "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz" - integrity sha512-ynmNeT7asXyH3aSVv4vvX4Rb+0qjOhdNHnO/3vuZNqPmhDpV/+rCSGwQ7bLcmU2cJ4dvoheIO85LQj0IbJHEtg== - dependencies: - "@adobe/css-tools" "^4.0.1" - "@babel/runtime" "^7.9.2" - "@types/testing-library__jest-dom" "^5.9.1" - aria-query "^5.0.0" - chalk "^3.0.0" - css.escape "^1.5.1" - dom-accessibility-api "^0.5.6" - lodash "^4.17.15" - redent "^3.0.0" - -"@testing-library/react@^13.0.0": - version "13.4.0" - resolved "https://registry.npmjs.org/@testing-library/react/-/react-13.4.0.tgz" - integrity sha512-sXOGON+WNTh3MLE9rve97ftaZukN3oNf2KjDy7YTx6hcTO2uuLHuCGynMDhFwGw/jYf4OJ2Qk0i4i79qMNNkyw== - dependencies: - "@babel/runtime" "^7.12.5" - "@testing-library/dom" "^8.5.0" - "@types/react-dom" "^18.0.0" - -"@testing-library/user-event@^13.2.1": - version "13.5.0" - resolved "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz" - integrity sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg== - dependencies: - "@babel/runtime" "^7.12.5" - "@tootallnate/once@1": version "1.1.2" resolved "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz" @@ -2296,11 +2220,6 @@ resolved "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz" integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== -"@types/aria-query@^5.0.1": - version "5.0.4" - resolved "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz" - integrity sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw== - "@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14": version "7.20.5" resolved "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz" @@ -2459,14 +2378,6 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/jest@*": - version "29.5.13" - resolved "https://registry.npmjs.org/@types/jest/-/jest-29.5.13.tgz" - integrity sha512-wd+MVEZCHt23V0/L642O5APvspWply/rGY5BcW4SUETo2UzPU3Z26qr8jC2qxpimI2jjx9h7+2cj2FwIr01bXg== - dependencies: - expect "^29.0.0" - pretty-format "^29.0.0" - "@types/jest@^27.0.1": version "27.5.2" resolved "https://registry.npmjs.org/@types/jest/-/jest-27.5.2.tgz" @@ -2626,13 +2537,6 @@ resolved "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz" integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw== -"@types/testing-library__jest-dom@^5.9.1": - version "5.14.9" - resolved "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.9.tgz" - integrity sha512-FSYhIjFlfOpGSRyVoMBMuS3ws5ehFQODymf3vlI7U1K8c7PHwWwFY7VREfmsuzHSOnoKs/9/Y983ayOs7eRzqw== - dependencies: - "@types/jest" "*" - "@types/trusted-types@^2.0.2": version "2.0.7" resolved "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz" @@ -3279,18 +3183,13 @@ argparse@^2.0.1: resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== -aria-query@5.1.3, aria-query@~5.1.3: +aria-query@~5.1.3: version "5.1.3" resolved "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz" integrity sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ== dependencies: deep-equal "^2.0.5" -aria-query@^5.0.0: - version "5.3.2" - resolved "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz" - integrity sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw== - array-buffer-byte-length@^1.0.0, array-buffer-byte-length@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz" @@ -3895,14 +3794,6 @@ chalk@^2.4.1, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz" - integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.2: version "4.1.2" resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" @@ -4373,11 +4264,6 @@ css-what@^6.0.1: resolved "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz" integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== -css.escape@^1.5.1: - version "1.5.1" - resolved "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz" - integrity sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg== - cssdb@^7.1.0: version "7.11.2" resolved "https://registry.npmjs.org/cssdb/-/cssdb-7.11.2.tgz" @@ -4697,11 +4583,6 @@ diff-sequences@^27.5.1: resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz" integrity sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ== -diff-sequences@^29.6.3: - version "29.6.3" - resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz" - integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q== - dir-glob@^3.0.1: version "3.0.1" resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" @@ -4735,11 +4616,6 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" -dom-accessibility-api@^0.5.6, dom-accessibility-api@^0.5.9: - version "0.5.16" - resolved "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz" - integrity sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg== - dom-converter@^0.2.0: version "0.2.0" resolved "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz" @@ -5590,17 +5466,6 @@ expect@^27.5.1: jest-matcher-utils "^27.5.1" jest-message-util "^27.5.1" -expect@^29.0.0: - version "29.7.0" - resolved "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz" - integrity sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw== - dependencies: - "@jest/expect-utils" "^29.7.0" - jest-get-type "^29.6.3" - jest-matcher-utils "^29.7.0" - jest-message-util "^29.7.0" - jest-util "^29.7.0" - express@^4.17.3: version "4.21.0" resolved "https://registry.npmjs.org/express/-/express-4.21.0.tgz" @@ -6429,11 +6294,6 @@ imurmurhash@^0.1.4: resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== -indent-string@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz" - integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== - inflight@^1.0.4: version "1.0.6" resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" @@ -6953,16 +6813,6 @@ jest-diff@^27.5.1: jest-get-type "^27.5.1" pretty-format "^27.5.1" -jest-diff@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz" - integrity sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw== - dependencies: - chalk "^4.0.0" - diff-sequences "^29.6.3" - jest-get-type "^29.6.3" - pretty-format "^29.7.0" - jest-docblock@^27.5.1: version "27.5.1" resolved "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz" @@ -7011,11 +6861,6 @@ jest-get-type@^27.5.1: resolved "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz" integrity sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw== -jest-get-type@^29.6.3: - version "29.6.3" - resolved "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz" - integrity sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw== - jest-haste-map@^27.5.1: version "27.5.1" resolved "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz" @@ -7077,16 +6922,6 @@ jest-matcher-utils@^27.0.0, jest-matcher-utils@^27.5.1: jest-get-type "^27.5.1" pretty-format "^27.5.1" -jest-matcher-utils@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz" - integrity sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g== - dependencies: - chalk "^4.0.0" - jest-diff "^29.7.0" - jest-get-type "^29.6.3" - pretty-format "^29.7.0" - jest-message-util@^27.5.1: version "27.5.1" resolved "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz" @@ -7117,21 +6952,6 @@ jest-message-util@^28.1.3: slash "^3.0.0" stack-utils "^2.0.3" -jest-message-util@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz" - integrity sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w== - dependencies: - "@babel/code-frame" "^7.12.13" - "@jest/types" "^29.6.3" - "@types/stack-utils" "^2.0.0" - chalk "^4.0.0" - graceful-fs "^4.2.9" - micromatch "^4.0.4" - pretty-format "^29.7.0" - slash "^3.0.0" - stack-utils "^2.0.3" - jest-mock@^27.5.1: version "27.5.1" resolved "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz" @@ -7295,18 +7115,6 @@ jest-util@^28.1.3: graceful-fs "^4.2.9" picomatch "^2.2.3" -jest-util@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz" - integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA== - dependencies: - "@jest/types" "^29.6.3" - "@types/node" "*" - chalk "^4.0.0" - ci-info "^3.2.0" - graceful-fs "^4.2.9" - picomatch "^2.2.3" - jest-validate@^27.5.1: version "27.5.1" resolved "https://registry.npmjs.org/jest-validate/-/jest-validate-27.5.1.tgz" @@ -7744,7 +7552,7 @@ lodash.uniq@^4.5.0: resolved "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz" integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ== -lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7.0: +lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7.0: version "4.17.21" resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -7775,11 +7583,6 @@ lru-cache@^5.1.1: dependencies: yallist "^3.0.2" -lz-string@^1.5.0: - version "1.5.0" - resolved "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz" - integrity sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ== - magic-sdk@^28.12.0: version "28.12.0" resolved "https://registry.yarnpkg.com/magic-sdk/-/magic-sdk-28.12.0.tgz#0b4fd132c54f46bbade7935e00b7b468188f7ce9" @@ -7926,11 +7729,6 @@ min-document@^2.19.0: dependencies: dom-walk "^0.1.0" -min-indent@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz" - integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== - mini-css-extract-plugin@^2.4.5: version "2.9.1" resolved "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.1.tgz" @@ -9193,7 +8991,7 @@ pretty-error@^4.0.0: lodash "^4.17.20" renderkid "^3.0.0" -pretty-format@^27.0.0, pretty-format@^27.0.2, pretty-format@^27.5.1: +pretty-format@^27.0.0, pretty-format@^27.5.1: version "27.5.1" resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz" integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ== @@ -9212,15 +9010,6 @@ pretty-format@^28.1.3: ansi-styles "^5.0.0" react-is "^18.0.0" -pretty-format@^29.0.0, pretty-format@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz" - integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ== - dependencies: - "@jest/schemas" "^29.6.3" - ansi-styles "^5.0.0" - react-is "^18.0.0" - process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz" @@ -9543,14 +9332,6 @@ recursive-readdir@^2.2.2: dependencies: minimatch "^3.0.5" -redent@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz" - integrity sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg== - dependencies: - indent-string "^4.0.0" - strip-indent "^3.0.0" - reflect.getprototypeof@^1.0.4: version "1.0.6" resolved "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz" @@ -10411,13 +10192,6 @@ strip-hex-prefix@1.0.0: dependencies: is-hex-prefixed "1.0.0" -strip-indent@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz" - integrity sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ== - dependencies: - min-indent "^1.0.0" - strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" @@ -11122,11 +10896,6 @@ wbuf@^1.1.0, wbuf@^1.7.3: dependencies: minimalistic-assert "^1.0.0" -web-vitals@^2.1.0: - version "2.1.4" - resolved "https://registry.npmjs.org/web-vitals/-/web-vitals-2.1.4.tgz" - integrity sha512-sVWcwhU5mX6crfI5Vd2dC4qchyTqxV8URinzt25XqVh+bHEPGH4C3NPrNionCP7Obx59wrYEbNlw4Z8sjALzZg== - web3-core-helpers@1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.5.2.tgz#b6bd5071ca099ba3f92dfafb552eed2b70af2795" From 4b09e5e06975daacad3bb0bf7cde965e9ea08815 Mon Sep 17 00:00:00 2001 From: Hunter Cote Date: Fri, 18 Oct 2024 16:29:29 -0400 Subject: [PATCH 2/3] cleanup --- README.md | 4 +++ src/App.tsx | 87 ++++++++++++++++++++++++---------------------------- src/utils.ts | 2 +- 3 files changed, 45 insertions(+), 48 deletions(-) diff --git a/README.md b/README.md index e69de29..cf611e7 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,4 @@ +### Example Kadena + +- [demo app](https://codesandbox.io/p/sandbox/github/magiclabs/example-kadena) +- [docs](https://magic.link/docs/blockchains/other-chains/other/kadena) \ No newline at end of file diff --git a/src/App.tsx b/src/App.tsx index f3954b0..482516a 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -27,7 +27,6 @@ function App() { // Cross Chain Transaction const [xDisabled, setXDisabled] = useState(false); - const [xToAccount, setXToAccount] = useState(""); const [xSendAmount, setXSendAmount] = useState(""); const [xChainId, setXChainId] = useState(''); @@ -83,13 +82,13 @@ function App() { .execution((Pact.modules as any).coin["get-balance"](accountName)) .setMeta({ chainId: selectedChainId }) .createTransaction(); - const { result } = await kadenaClient.dirtyRead(transaction); - if (result.status === "failure") { - console.error('Failed to get balance:', result.error); + const response = await kadenaClient.dirtyRead(transaction); + if (response.result.status === "failure") { + console.error('Failed to get balance:', response.result.error); setBalance(0); return; } - setBalance((result as any).data as number); + setBalance((response.result as any).data as number); } catch (error) { console.error("Failed to get balance:", error); } @@ -108,16 +107,17 @@ function App() { .setMeta({ chainId: selectedChainId }) .setNetworkId(NETWORK_ID) .createTransaction(); - const { result } = await kadenaClient.dirtyRead(transaction); - if (result.status === "failure") { - console.error((result.error as any).message); + const response = await kadenaClient.dirtyRead(transaction); + if (response.result.status === "failure") { + console.error((response.result.error as any).message); return false; } else { - console.log(result.data); + console.log(response.result.data); return true; } } catch (error) { - console.error("Failed to get account details", error); + console.error(`Failed to get balance for ${account} on chain ${selectedChainId}`); + console.error(error); } }; @@ -194,12 +194,12 @@ function App() { console.log("signed transaction", signedTx); const transactionDescriptor = await kadenaClient.submit(signedTx as ICommand); console.log("broadcasting transaction...", transactionDescriptor); - const { result } = await kadenaClient.listen(transactionDescriptor); + const response = await kadenaClient.listen(transactionDescriptor); setDisabled(false); - if (result.status === "failure") { - console.error(result.error); + if (response.result.status === "failure") { + console.error(response.result.error); } else { - console.log(result); + console.log('transaction success! response:', response); getBalance(userInfo.publicAddress as AccountName); } } catch (error) { @@ -213,14 +213,14 @@ function App() { setXDisabled(true); const kadenaClient = getKadenaClient(selectedChainId); const amount = new PactNumber(xSendAmount).toPactDecimal(); - const senderPublicKey = userInfo?.publicAddress.substring(2); - const receiverPublicKey = xToAccount.substring(2); + const senderPublicKey = userInfo.publicAddress.substring(2); + const receiverPublicKey = userInfo.publicAddress.substring(2); let transaction = Pact.builder .execution( (Pact.modules as any).coin.defpact['transfer-crosschain']( userInfo.publicAddress, - xToAccount, + userInfo.publicAddress, readKeyset('receiver-guard'), xChainId, amount, @@ -231,7 +231,7 @@ function App() { signFor( 'coin.TRANSFER_XCHAIN', userInfo.publicAddress, - xToAccount, + userInfo.publicAddress, amount, xChainId, ), @@ -247,11 +247,11 @@ function App() { console.log("signed transaction", signedTx); const transactionDescriptor = await kadenaClient.submit(signedTx as ICommand); console.log("broadcasting transaction...", transactionDescriptor); - const { result } = await kadenaClient.listen(transactionDescriptor); - if (result.status === "failure") { - console.error(result.error); + const response = await kadenaClient.listen(transactionDescriptor); + if (response.result.status === "failure") { + console.error(response.result.error); } else { - console.log('Transaction start result: success!', result); + console.log('transaction start success! response:', response); getBalance(userInfo.publicAddress as AccountName); await handleSendXTransactionFinish(transactionDescriptor); } @@ -288,12 +288,12 @@ function App() { .createTransaction(); const continuationTxDescriptor = await kadenaClientTargetChain.submit(continuationTransaction as ICommand); console.log('broadcasting continuation transaction...', continuationTxDescriptor); - const { result } = await kadenaClientTargetChain.listen(continuationTxDescriptor); + const response = await kadenaClientTargetChain.listen(continuationTxDescriptor); setXDisabled(false); - if (result.status === "failure") { - console.error(result.error); + if (response.result.status === "failure") { + console.error(response.result.error); } else { - console.log('Transaction continuation result: success!', result); + console.log('transaction continuation success! response:', response); } } catch (error) { setXDisabled(false); @@ -303,13 +303,16 @@ function App() { const ChainIdSelector = () => { return ( - +
+ + +
); }; @@ -320,7 +323,6 @@ function App() {

Please sign up or login

setEmail(event.target.value)} @@ -334,8 +336,9 @@ function App() {
-

Select Chain ID

+

Network Details

+
Network: {NETWORK_ID}

Kadena Account

@@ -351,10 +354,7 @@ function App() { -
-
-

Balance

-
Balance: {balance} KDA
+
Balance: {balance} KDA
@@ -390,14 +390,7 @@ function App() {
-

Cross Chain Transfer

- setXToAccount(event.target.value)} - /> +

Send Kadena (cross chain)

`https://api.testnet.chainweb.com/chainweb/0.0/${NETWORK_ID}/chain/${chainId || DEFAULT_CHAIN_ID}/pact`; From 4188c4ccf6d7f001bc3f221903908a4349ed8bbb Mon Sep 17 00:00:00 2001 From: Hunter Cote Date: Fri, 18 Oct 2024 16:45:28 -0400 Subject: [PATCH 3/3] spacing --- src/magic.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/magic.ts b/src/magic.ts index b258fb1..440f95e 100644 --- a/src/magic.ts +++ b/src/magic.ts @@ -15,4 +15,4 @@ export const createMagic = (chainId?: ChainId) => { }), ], }) -} \ No newline at end of file +}