-
-
Save besated/55e6d443acaf026729a92ab567953c44 to your computer and use it in GitHub Desktop.
This file contains hidden or 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 secp256k1 from "secp256k1"; | |
import { createPublicClient, createWalletClient, hexToNumber, http, numberToHex, parseSignature, toHex } from "viem"; | |
import { privateKeyToAccount, generatePrivateKey } from "viem/accounts"; | |
import { seiTestnet } from "viem/chains"; | |
import { ADDRESS_PRECOMPILE_ABI, ADDRESS_PRECOMPILE_ADDRESS } from '@sei-js/evm' | |
// replace pk | |
const PRIVATE_KEY = ""; | |
const publicClient = createPublicClient({ | |
chain: seiTestnet, | |
transport: http(), | |
}); | |
const client = createWalletClient({ | |
chain: seiTestnet, | |
transport: http(), | |
}); | |
interface AssociateRequest { | |
r: string; | |
s: string; | |
v: string; | |
custom_message: string; | |
} | |
interface AssociateRequestSchema { | |
Method: 'sei_associate'; | |
Parameters: [request: AssociateRequest]; | |
ReturnType: null; | |
} | |
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); | |
// Associate account using signed message | |
const associate = async () => { | |
const account = privateKeyToAccount(PRIVATE_KEY); | |
const newPk = generatePrivateKey(); | |
const newAccount = privateKeyToAccount(newPk); | |
// Sign a message | |
const message = "associate" | |
const signature = await newAccount.signMessage({ message }); | |
const parsedSignature = parseSignature(signature); | |
const messageLength = Buffer.from(message, 'utf8').length; | |
const signedMessage = `\x19Ethereum Signed Message:\n${messageLength}${message}`; | |
const response = await client.writeContract({ | |
account, | |
address: ADDRESS_PRECOMPILE_ADDRESS, | |
abi: ADDRESS_PRECOMPILE_ABI, | |
functionName: "associate", | |
args: [numberToHex(Number(parsedSignature.v)-27), parsedSignature.r, parsedSignature.s, signedMessage], | |
gasPrice: BigInt(100_000_000_000), // 100 GWEI | |
}); | |
console.log(response); | |
// Get evm address after association | |
await sleep(3000); // Sometimes it fails if you query it immeditely bc RPC nodes are behind | |
const evmAddress = await publicClient.readContract({ | |
address: ADDRESS_PRECOMPILE_ADDRESS, | |
abi: ADDRESS_PRECOMPILE_ABI, | |
functionName: "getSeiAddr", | |
args: [newAccount.address], | |
}); | |
console.log(evmAddress); | |
}; | |
// Associate account using public key | |
const associateViaPubkey = async () => { | |
const account = privateKeyToAccount(PRIVATE_KEY); | |
const newPk = generatePrivateKey(); | |
const newAccount = privateKeyToAccount(newPk); | |
// compress pubkey | |
const publicKeyBuffer = Buffer.from(newAccount.publicKey.slice(2), "hex"); | |
const compressedPubKey = secp256k1.publicKeyConvert(publicKeyBuffer, true); | |
// console.log(newAccount.publicKey, toHex(compressedPublicKey)); | |
const response = await client.writeContract({ | |
account, | |
address: ADDRESS_PRECOMPILE_ADDRESS, | |
abi: ADDRESS_PRECOMPILE_ABI, | |
functionName: "associatePubKey", | |
args: [Buffer.from(compressedPubKey).toString("hex")], | |
gasPrice: BigInt(100_000_000_000), // 100 GWEI | |
}); | |
console.log(response); | |
// Get evm address after association | |
await sleep(3000); // Sometimes it fails if you query it immeditely bc RPC nodes are behind | |
const evmAddress = await publicClient.readContract({ | |
address: ADDRESS_PRECOMPILE_ADDRESS, | |
abi: ADDRESS_PRECOMPILE_ABI, | |
functionName: "getSeiAddr", | |
args: [newAccount.address], | |
}); | |
console.log(evmAddress); | |
}; | |
// Associate account using a signed message without gas (only allowed if the account already has funds) | |
const associateGasless = async (signature: `0x${string}`, message: string) => { | |
const parsedSignature = parseSignature(signature); | |
const messageLength = Buffer.from(message, 'utf8').length; | |
const messageToSign = `\x19Ethereum Signed Message:\n${messageLength}${message}`; | |
const request: AssociateRequest = { | |
r: parsedSignature.r, | |
s: parsedSignature.s, | |
v: numberToHex(Number(parsedSignature.v)-27), | |
custom_message: messageToSign | |
}; | |
const response = await client.request<AssociateRequestSchema>({ | |
method: 'sei_associate', | |
params: [request] | |
}); | |
console.log(response); | |
} | |
const main = async () => { | |
associate(); | |
// associateViaPubkey(); | |
// associateGasless(signature, message); | |
} | |
main(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment