-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' of https://github.com/XP-NETWORK/xp-decentralized…
- Loading branch information
Showing
6 changed files
with
549 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import { CasperClient } from "casper-js-sdk"; | ||
|
||
export const sleep = (ms: number) => { | ||
return new Promise((resolve) => setTimeout(resolve, ms)); | ||
}; | ||
export const getDeploy = async (client: CasperClient, deployHash: string) => { | ||
let i = 300; | ||
while (i !== 0) { | ||
try { | ||
const [_, raw] = await client.getDeploy(deployHash); | ||
//@ts-ignore | ||
if (raw.execution_results.length !== 0) { | ||
// @ts-ignore | ||
if (raw.execution_results[0].result.Success) { | ||
return raw; | ||
} else { | ||
// @ts-ignore | ||
throw Error( | ||
"Contract execution: " + | ||
// @ts-ignore | ||
raw.execution_results[0].result.Failure.error_message, | ||
); | ||
} | ||
} else { | ||
i--; | ||
await sleep(4000); | ||
continue; | ||
} | ||
} catch (e: any) { | ||
console.log(e.message); | ||
if (e.message.match(/(deploy not known|no such deploy)/gim)) { | ||
i--; | ||
await sleep(4000); | ||
continue; | ||
} else { | ||
throw e; | ||
} | ||
} | ||
} | ||
throw Error("Timeout after " + i + "s. Something's wrong"); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,199 @@ | ||
import { CEP78Client } from "casper-cep78-js-client"; | ||
import { | ||
CLAccountHash, | ||
CLByteArray, | ||
CLPublicKey, | ||
CLString, | ||
CasperClient, | ||
Contracts, | ||
DeployUtil, | ||
PurseIdentifier, | ||
} from "casper-js-sdk"; | ||
import { getDeploy } from "./get-deploy"; | ||
import { TCasperHandler, TCasperParams } from "./types"; | ||
|
||
export function casperHandler({ | ||
rpc, | ||
identifier, | ||
network, | ||
bridge, | ||
storage, | ||
}: TCasperParams): TCasperHandler { | ||
const cc = new CasperClient(rpc); | ||
|
||
// biome-ignore lint/suspicious/noExplicitAny: <explanation> | ||
async function signWithCasperWallet(sender: any, deploy: DeployUtil.Deploy) { | ||
const address = await sender.getActivePublicKey(); | ||
const signedDeployJson = await sender.sign( | ||
JSON.stringify(DeployUtil.deployToJson(deploy)), | ||
address, | ||
); | ||
|
||
const signedDeploy = DeployUtil.setSignature( | ||
deploy, | ||
signedDeployJson.signature, | ||
CLPublicKey.fromHex(address), | ||
); | ||
|
||
const res = await cc.putDeploy(signedDeploy).catch((e) => { | ||
console.log(e, "e in signWithCasperWallet"); | ||
return ""; | ||
}); | ||
|
||
res && (await getDeploy(cc, res)); | ||
return res; | ||
} | ||
|
||
return { | ||
async getBalance(signer) { | ||
const pubk = await signer.getActivePublicKey(); | ||
const balance = await cc.nodeClient.queryBalance( | ||
PurseIdentifier.MainPurseUnderPublicKey, | ||
pubk, | ||
); | ||
return balance.toBigInt(); | ||
}, | ||
deployNftCollection(signer, da, ga) { | ||
unimplemented("deploy nft collection", signer, da, ga); | ||
}, | ||
async nftData(tokenId, contract) { | ||
const ctr = new Contracts.Contract(cc); | ||
ctr.setContractHash(`hash-${contract}`); | ||
|
||
const cn = await ctr.queryContractData(["collection_name"]); | ||
const cs = await ctr.queryContractData(["collection_symbol"]); | ||
const md = ((await ctr | ||
.queryContractDictionary("metadata_raw", tokenId) | ||
.catch(() => { | ||
console.log( | ||
`Failed to get raw metadata for ${contract} - ${tokenId}`, | ||
); | ||
return undefined; | ||
})) || | ||
(await ctr | ||
.queryContractDictionary("metadata_custom_validated", tokenId) | ||
.catch(() => { | ||
console.log( | ||
`Failed to get custom validated metadata for ${contract} - ${tokenId}`, | ||
); | ||
throw new Error( | ||
`Failed to get metadata for ${contract} - ${tokenId}`, | ||
); | ||
}))) as CLString; | ||
|
||
return { | ||
metadata: md.data, | ||
name: cn, | ||
royalty: 0n, | ||
symbol: cs, | ||
}; | ||
}, | ||
identifier, | ||
getProvider() { | ||
return cc; | ||
}, | ||
decodeLockedEvent(txHash) { | ||
unimplemented("decode tx hash", txHash); | ||
}, | ||
claimNft(signer, claimData, sig, extraArgs) { | ||
unimplemented("claim nft", signer, claimData, sig, extraArgs); | ||
}, | ||
getValidatorCount() { | ||
unimplemented(); | ||
}, | ||
lockNft( | ||
signer, | ||
sourceNft, | ||
destinationChain, | ||
to, | ||
tokenId, | ||
metaDataUri, | ||
extraArgs, | ||
) { | ||
unimplemented( | ||
"lock nft", | ||
signer, | ||
sourceNft, | ||
destinationChain, | ||
tokenId, | ||
metaDataUri, | ||
extraArgs, | ||
to, | ||
); | ||
}, | ||
async mintNft(signer, ma) { | ||
const nft = new CEP78Client(rpc, network); | ||
nft.setContractHash(ma.contract); | ||
const deploy = nft.mint( | ||
{ | ||
meta: { | ||
uri: ma.uri, | ||
}, | ||
owner: ma.owner, | ||
collectionName: ma.collectionName, | ||
}, | ||
{ | ||
useSessionCode: false, | ||
}, | ||
"1000000000", | ||
CLPublicKey.fromFormattedString(await signer.getActivePublicKey()), | ||
); | ||
if (isBrowser()) { | ||
return signWithCasperWallet(signer, deploy); | ||
} | ||
|
||
const signed = await signer.sign( | ||
DeployUtil.deployToJson(deploy), | ||
await signer.getActivePublicKey(), | ||
); | ||
return DeployUtil.deployFromJson(signed).unwrap().send(rpc); | ||
}, | ||
getStorageContract() { | ||
return storage; | ||
}, | ||
validateAddress(hex) { | ||
try { | ||
CLAccountHash.fromFormattedString(hex); | ||
return Promise.resolve(true); | ||
} catch (e) { | ||
return Promise.resolve(false); | ||
} | ||
}, | ||
transform(input) { | ||
unimplemented("Transform", input); | ||
}, | ||
async approveNft(signer, tokenId, contract, _) { | ||
const cep78Client = new CEP78Client(rpc, network); | ||
cep78Client.setContractHash(contract); | ||
const deploy = cep78Client.approve( | ||
{ | ||
operator: new CLByteArray(Buffer.from(bridge.split("-")[1], "hex")), | ||
// tokenHash: tokenHash, | ||
tokenId: tokenId, | ||
}, | ||
"2000000000", | ||
CLPublicKey.fromHex(await signer.getActivePublicKey()), | ||
); | ||
|
||
if (isBrowser()) { | ||
return signWithCasperWallet(signer, deploy); | ||
} | ||
|
||
const signed = await signer.sign( | ||
DeployUtil.deployToJson(deploy), | ||
await signer.getActivePublicKey(), | ||
); | ||
const dep = cc.deployFromJson(signed).unwrap(); | ||
return await cc.putDeploy(dep); | ||
}, | ||
}; | ||
} | ||
|
||
function unimplemented(msg?: string, ...args: unknown[]): never { | ||
throw new Error(`Unimplemented: ${msg}. ${JSON.stringify(args)}`); | ||
} | ||
|
||
function isBrowser() { | ||
//@ts-ignore | ||
return window !== undefined; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import { CasperClient } from "casper-js-sdk"; | ||
import { CasperLabsHelper } from "casper-js-sdk/dist/@types/casperlabsSigner"; | ||
import { BridgeStorage } from "../../contractsTypes/evm"; | ||
import { DeployNFTCollection, MintNft, TSingularNftChain } from "../types"; | ||
|
||
export type TCasperMintArgs = { | ||
contract: `hash-${string}`; | ||
name: string; | ||
uri: string; | ||
owner: string; | ||
collectionName?: string; | ||
}; | ||
|
||
export type CasperSigner = CasperLabsHelper; | ||
|
||
export type TClaimData = { | ||
destinationUserAddress: string; | ||
name: string; | ||
uri: string; | ||
royaltyPercentage: bigint; | ||
royaltyReceiver: string; | ||
fee: bigint; | ||
destination_chain: string; | ||
source_chain: string; | ||
source_nft_contract_address: string; | ||
token_id: bigint; | ||
transaction_hash: string; | ||
nft_type: string; | ||
metadata: string; | ||
symbol: string; | ||
amount: bigint; | ||
}; | ||
|
||
export type TCasperHandler = TSingularNftChain< | ||
CasperSigner, | ||
TClaimData, | ||
never, | ||
string, | ||
CasperClient | ||
> & | ||
MintNft<CasperSigner, TCasperMintArgs, never, string> & | ||
DeployNFTCollection< | ||
CasperSigner, | ||
{ name: string; symbol: string }, | ||
never, | ||
string | ||
>; | ||
|
||
export type TCasperParams = { | ||
bridge: string; | ||
rpc: string; | ||
storage: BridgeStorage; | ||
identifier: string; | ||
network: string; | ||
}; |
Oops, something went wrong.