mirror of
https://github.com/AtHeartEngineer/farcaster_change_custody.git
synced 2026-01-09 20:48:07 -05:00
Merge pull request #1 from jacque006/main
Fix TS typings, add README & CI
This commit is contained in:
19
.github/workflows/main.yml
vendored
Normal file
19
.github/workflows/main.yml
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
name: main
|
||||
|
||||
on:
|
||||
push:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build project
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "18.x"
|
||||
cache: "npm"
|
||||
|
||||
- run: npm ci
|
||||
- run: npm run build
|
||||
29
README.md
Normal file
29
README.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# farcaster_chnage_custody
|
||||
|
||||
Web app implementing https://docs.farcaster.xyz/developers/guides/accounts/change-custody
|
||||
|
||||
## setup
|
||||
|
||||
### deps
|
||||
|
||||
[NodeJS](https://nodejs.org)
|
||||
|
||||
### install
|
||||
|
||||
```sh
|
||||
npm i
|
||||
```
|
||||
|
||||
## commands
|
||||
|
||||
### build
|
||||
|
||||
```sh
|
||||
npm run build
|
||||
```
|
||||
|
||||
### run
|
||||
|
||||
```sh
|
||||
npm run start
|
||||
```
|
||||
8
package-lock.json
generated
8
package-lock.json
generated
@@ -10,7 +10,7 @@
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@farcaster/core": "^0.14.0",
|
||||
"viem": "^2.7.9"
|
||||
"viem": "^2.7.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"http-server": "^14.1.1",
|
||||
@@ -826,9 +826,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/viem": {
|
||||
"version": "2.7.9",
|
||||
"resolved": "https://registry.npmjs.org/viem/-/viem-2.7.9.tgz",
|
||||
"integrity": "sha512-iDfc8TwaZFp1K95zlsxYh6Cs0OWCt35Tqs8uYgXKSxtz7w075mZ0H5SJ8zSyJGoEaticVDhtdmRRX6TtcW9EeQ==",
|
||||
"version": "2.7.10",
|
||||
"resolved": "https://registry.npmjs.org/viem/-/viem-2.7.10.tgz",
|
||||
"integrity": "sha512-mpm/A3Rbq6hhRovOw6btkrLeDe0DlEGLoCmO2LCbH/MuTQgLNd0cWJSIov9TL/8/Pz+qC2e+bh9zohQnKA+6PQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@farcaster/core": "^0.14.0",
|
||||
"viem": "^2.7.9"
|
||||
"viem": "^2.7.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"http-server": "^14.1.1",
|
||||
|
||||
23
src/Viem.ts
23
src/Viem.ts
@@ -1,23 +0,0 @@
|
||||
import { ID_REGISTRY_EIP_712_TYPES, idRegistryABI, ID_GATEWAY_ADDRESS } from '@farcaster/core';
|
||||
import { walletClient, account } from './clients';
|
||||
import { readNonce, getDeadline } from './helpers';
|
||||
|
||||
const nonce = await readNonce();
|
||||
const deadline = getDeadline();
|
||||
const IdContract = {
|
||||
abi: idRegistryABI,
|
||||
address: ID_GATEWAY_ADDRESS,
|
||||
chain: optimism
|
||||
};
|
||||
|
||||
export const signature = await walletClient.signTypedData({
|
||||
account,
|
||||
...ID_REGISTRY_EIP_712_TYPES,
|
||||
primaryType: 'Transfer',
|
||||
message: {
|
||||
fid: 1n,
|
||||
to: account,
|
||||
nonce,
|
||||
deadline
|
||||
}
|
||||
});
|
||||
@@ -1,5 +1,4 @@
|
||||
import { createWalletClient, createPublicClient, custom, http } from 'viem';
|
||||
import { privateKeyToAccount } from 'viem/accounts';
|
||||
import { optimism } from 'viem/chains';
|
||||
|
||||
export const publicClient = createPublicClient({
|
||||
@@ -12,8 +11,8 @@ export const walletClient = createWalletClient({
|
||||
transport: custom(window.ethereum)
|
||||
});
|
||||
|
||||
// JSON-RPC Account
|
||||
//export const [account] = await walletClient.getAddresses();
|
||||
export const getAccountAddress = async () => {
|
||||
const [firstAddress] = await walletClient.getAddresses();
|
||||
return firstAddress;
|
||||
};
|
||||
|
||||
// Local Account
|
||||
export const account = privateKeyToAccount('0x...');
|
||||
|
||||
6
src/contract.ts
Normal file
6
src/contract.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { ID_GATEWAY_ADDRESS, idRegistryABI } from "@farcaster/core";
|
||||
|
||||
export const idContract = {
|
||||
abi: idRegistryABI,
|
||||
address: ID_GATEWAY_ADDRESS,
|
||||
};
|
||||
@@ -1,17 +1,19 @@
|
||||
import { ID_REGISTRY_ADDRESS, idRegistryABI } from '@farcaster/core';
|
||||
import { publicClient, account } from './clients';
|
||||
import { Address } from 'viem';
|
||||
import { publicClient } from './client';
|
||||
|
||||
// Returns one hour from now, in seconds
|
||||
export const getDeadline = () => {
|
||||
const now = Math.floor(Date.now() / 1000);
|
||||
const oneHour = 60 * 60;
|
||||
return now + oneHour;
|
||||
return BigInt(now + oneHour);
|
||||
};
|
||||
|
||||
export const readNonce = async () => {
|
||||
return await publicClient.readContract({
|
||||
export const readNonce = async (account: Address) => {
|
||||
return publicClient.readContract({
|
||||
address: ID_REGISTRY_ADDRESS,
|
||||
abi: idRegistryABI,
|
||||
functionName: 'nonce',
|
||||
functionName: 'nonces',
|
||||
args: [account]
|
||||
});
|
||||
};
|
||||
|
||||
57
src/index.ts
57
src/index.ts
@@ -1,22 +1,41 @@
|
||||
import { ViemWalletEip712Signer } from '@farcaster/core';
|
||||
import { walletClient, account } from './clients';
|
||||
import { readNonce, getDeadline } from './helpers';
|
||||
import { Address, bytesToHex } from 'viem';
|
||||
import { walletClient, publicClient, getAccountAddress } from './client';
|
||||
import { idContract } from './contract';
|
||||
import { readNonce, getDeadline } from './helper';
|
||||
|
||||
const nonce = await readNonce();
|
||||
const deadline = getDeadline();
|
||||
/**
|
||||
* Transfers Farcaster account to a new owner.
|
||||
*
|
||||
* @param fid ID of farcaster account
|
||||
* @param to Account address to trasnfer ownership to
|
||||
*/
|
||||
export const transferAccount = async (fid: bigint, to: Address) => {
|
||||
// TODO fix 'any' typing, signer constrcutor expeting wallet client with netowrk prop.
|
||||
const eip712Signer = new ViemWalletEip712Signer(walletClient as any);
|
||||
|
||||
const eip712Signer = new ViemWalletEip712Signer(walletClient);
|
||||
const signature = await eip712Signer.signTransfer({
|
||||
fid: 1n,
|
||||
to: account,
|
||||
nonce,
|
||||
deadline
|
||||
});
|
||||
|
||||
const { request: transferRequest } = await walletClient.simulateContract({
|
||||
...IdContract,
|
||||
functionName: 'transfer',
|
||||
args: [account, deadline, signature] // to, deadline, signature
|
||||
});
|
||||
|
||||
await walletClient.writeContract(transferRequest);
|
||||
const account = await getAccountAddress();
|
||||
const nonce = await readNonce(account);
|
||||
const deadline = getDeadline();
|
||||
|
||||
const sigRes = await eip712Signer.signTransfer({
|
||||
fid,
|
||||
to,
|
||||
nonce,
|
||||
deadline
|
||||
});
|
||||
// See https://github.com/supermacro/neverthrow/wiki/Basic-Usage-Examples#asynchronous-api for neverthrow pattern
|
||||
if (sigRes.isErr()) {
|
||||
throw sigRes.error;
|
||||
}
|
||||
const signature = bytesToHex(sigRes.value);
|
||||
|
||||
const { request: transferRequest } = await publicClient.simulateContract({
|
||||
...idContract,
|
||||
account,
|
||||
functionName: 'transfer',
|
||||
args: [account, deadline, signature] // to, deadline, signature
|
||||
});
|
||||
|
||||
await walletClient.writeContract(transferRequest);
|
||||
};
|
||||
|
||||
5
src/window.d.ts
vendored
Normal file
5
src/window.d.ts
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
import { EIP1193Provider } from "viem";
|
||||
|
||||
declare global {
|
||||
interface Window { ethereum: EIP1193Provider; }
|
||||
}
|
||||
Reference in New Issue
Block a user