Last active
January 5, 2024 12:11
-
-
Save shekohex/8a1f3088a6df88275312bc30905c2ba0 to your computer and use it in GitHub Desktop.
Testing Pallet claims Native
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
import "npm:@webb-tools/tangle-substrate-types@^0.5.1"; | |
import { ApiPromise, WsProvider } from "npm:@polkadot/[email protected]"; | |
import { Keyring } from "npm:@polkadot/[email protected]"; | |
import { | |
hexToU8a, | |
stringToU8a, | |
u8aToHex, | |
u8aToString, | |
} from "npm:@polkadot/[email protected]"; | |
import { decodeAddress, keccakAsU8a } from "npm:@polkadot/[email protected]"; | |
enum HexType { | |
EVM = "EVM", | |
Native = "Native", | |
} | |
const TANGLE_RPC_ENDPOINT = "ws://127.0.0.1:9944"; | |
const RECIPIENT = "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty"; | |
const RECIPIENT_TYPE = HexType.Native; | |
const SIGNER_PRIVATE_KEY = | |
"0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"; | |
const SIGNER_TYPE = HexType.Native; | |
const SIGNATURE_TYPE = HexType.Native; | |
if (import.meta.main) { | |
console.log(`Initializing API with Tangle endpoint: ${TANGLE_RPC_ENDPOINT}`); | |
const wsProvider = new WsProvider(TANGLE_RPC_ENDPOINT); | |
const apiPromise = await ApiPromise.create({ | |
provider: wsProvider, | |
noInitWarn: true, | |
}); | |
const keyring = new Keyring({ type: "sr25519" }); | |
const wallet = keyring.addFromUri(SIGNER_PRIVATE_KEY); | |
const signer = wallet.address; | |
console.log(`Using Wallet: ${wallet.address}`); | |
const prefix = apiPromise.consts.claims.prefix.toU8a(true); | |
// TODO: fetch statement from chain | |
const statement = stringToU8a(getStatement("Regular")); | |
const message = toAsciiHex(decodeAddress(RECIPIENT)); | |
console.log(`Message: ${u8aToHex(message)}`); | |
const payload = new Uint8Array( | |
prefix.length | |
+ message.length | |
+ statement.length | |
); | |
payload.set(prefix); | |
payload.set(message, prefix.length); | |
payload.set(statement, prefix.length + message.length); | |
const polkadotJsPrefix = stringToU8a("<Bytes>"); | |
const polkadotJsSuffix = stringToU8a("</Bytes>"); | |
const msgHash = keccakAsU8a(payload); | |
const fullPayload = new Uint8Array( | |
polkadotJsPrefix.length | |
+ msgHash.length | |
+ polkadotJsSuffix.length | |
); | |
fullPayload.set(polkadotJsPrefix); | |
fullPayload.set(msgHash, polkadotJsPrefix.length); | |
fullPayload.set(polkadotJsSuffix, polkadotJsPrefix.length + msgHash.length); | |
console.log(`Signing payload: ${u8aToString(fullPayload)}`); | |
const signature = wallet.sign(fullPayload); | |
console.log(`Signature: ${signature}`); | |
console.log(`Calling tx.claims.claim`); | |
const tx = apiPromise.tx.claims.claimAttest( | |
{ [RECIPIENT_TYPE]: RECIPIENT }, // destAccount | |
{ [SIGNER_TYPE]: signer }, // signer | |
{ [SIGNATURE_TYPE]: signature }, // signataure | |
getStatement("Regular"), | |
); | |
console.log(`Sending transaction with args ${tx.args.toString()}`); | |
await tx | |
.send((result) => { | |
const status = result.status; | |
const events = result.events.filter( | |
({ event: { section } }) => section === "system", | |
); | |
if (status.isInBlock || status.isFinalized) { | |
for (const event of events) { | |
const { | |
event: { data, method }, | |
} = event; | |
const [dispatchError] = data as any; | |
if (method === "ExtrinsicFailed") { | |
let message = dispatchError.type; | |
if (dispatchError.isModule) { | |
try { | |
const mod = dispatchError.asModule; | |
const error = dispatchError.registry.findMetaError(mod); | |
message = `${error.section}.${error.name}`; | |
} catch (error) { | |
console.error(`Error message: ${message}`); | |
console.error(error); | |
} | |
} else if (dispatchError.isToken) { | |
message = `${dispatchError.type}.${dispatchError.asToken.type}`; | |
} | |
console.error(`Error message: ${message}`); | |
} else if (method === "ExtrinsicSuccess" && status.isFinalized) { | |
// Resolve with the block hash | |
console.log( | |
`Transaction included at blockHash ${status.asFinalized.toString()}`, | |
); | |
} | |
} | |
} | |
}) | |
.catch(async (error) => { | |
console.error(error); | |
await apiPromise.disconnect(); | |
Deno.exit(1); | |
}); | |
} | |
type StatementKind = "Regular" | "Safe"; | |
function getStatement(kind: StatementKind): string { | |
switch (kind) { | |
case "Regular": | |
return "I hereby agree to the terms of the statement whose sha2256sum is 5627de05cfe235cd4ffa0d6375c8a5278b89cc9b9e75622fa2039f4d1b43dadf. (This may be found at the URL: https://statement.tangle.tools/airdrop-statement.html)"; | |
case "Safe": | |
return "I hereby agree to the terms of the statement whose sha2256sum is 7eae145b00c1912c8b01674df5df4ad9abcf6d18ea3f33d27eb6897a762f4273. (This may be found at the URL: https://https://statement.tangle.tools/safe-claim-statement)"; | |
} | |
} | |
function toAsciiHex(str: Uint8Array): Uint8Array { | |
const arr: number[] = []; | |
const pushNibble = (c: number) => | |
arr.push( | |
c < 10 | |
? c + 48 // 0 | |
: 97 - 10 + c, // a | |
); | |
for (let i = 0, strLen = str.length; i < strLen; i++) { | |
pushNibble(str[i] / 16); | |
pushNibble(str[i] % 16); | |
} | |
return new Uint8Array(arr); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment