Skip to content

Instantly share code, notes, and snippets.

@shekohex
Last active January 5, 2024 12:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shekohex/8a1f3088a6df88275312bc30905c2ba0 to your computer and use it in GitHub Desktop.
Save shekohex/8a1f3088a6df88275312bc30905c2ba0 to your computer and use it in GitHub Desktop.
Testing Pallet claims Native
import "npm:@webb-tools/tangle-substrate-types@^0.5.1";
import { ApiPromise, WsProvider } from "npm:@polkadot/api@10.9.1";
import { Keyring } from "npm:@polkadot/keyring@12.6.2";
import {
hexToU8a,
stringToU8a,
u8aToHex,
u8aToString,
} from "npm:@polkadot/util@12.6.2";
import { decodeAddress, keccakAsU8a } from "npm:@polkadot/util-crypto@12.6.2";
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