Skip to content

Commit

Permalink
add grow export e2e & inviter address change 2 btc (#3160)
Browse files Browse the repository at this point in the history
  • Loading branch information
wow-sven authored Jan 8, 2025
1 parent 9f95827 commit 53e1ec7
Show file tree
Hide file tree
Showing 6 changed files with 216 additions and 30 deletions.
5 changes: 3 additions & 2 deletions infra/rooch-portal-v2/src/sections/inviter/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@

import { useEffect } from 'react';

import { isValidAddress } from '@roochnetwork/rooch-sdk';
import { useRouter } from '../../routes/hooks';
import { INVITER_ADDRESS_KEY } from '../../utils/inviter';

export function InviterView({ inviterAddress }: { inviterAddress?: string }) {
const router = useRouter();

useEffect(() => {
if (inviterAddress) {
if (inviterAddress && isValidAddress(inviterAddress)) {
window.localStorage.setItem(INVITER_ADDRESS_KEY, inviterAddress);
router.push(`/settings`);
}
router.push('/settings');
}, [inviterAddress, router]);

return <></>;
Expand Down
30 changes: 25 additions & 5 deletions infra/rooch-portal-v2/src/sections/settings/view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@
import axios from 'axios';
import { useState, useEffect, useCallback } from 'react';
import { CopyToClipboard } from 'react-copy-to-clipboard';
import { Args, toHEX, Transaction, stringToBytes } from '@roochnetwork/rooch-sdk';
import {
Args,
toHEX,
Transaction,
stringToBytes,
BitcoinAddress,
isValidRoochAddress,
} from '@roochnetwork/rooch-sdk';
import {
useRoochClient,
SessionKeyGuard,
Expand All @@ -14,7 +21,16 @@ import {
} from '@roochnetwork/rooch-sdk-kit';

import { LoadingButton } from '@mui/lab';
import { Card , Chip, Stack, Button, TextField, CardHeader, Typography, CardContent } from '@mui/material';
import {
Card,
Chip,
Stack,
Button,
TextField,
CardHeader,
Typography,
CardContent,
} from '@mui/material';

import { sleep } from 'src/utils/common';

Expand All @@ -36,7 +52,7 @@ export function SettingsView() {
const wallet = useCurrentWallet();
const faucetUrl = useNetworkVariable('faucet').url;
const twitterOracleAddress = useNetworkVariable('roochMultiSigAddr');
const inviter = useNetworkVariable('inviter')
const inviter = useNetworkVariable('inviter');
const [tweetStatus, setTweetStatus] = useState('');
const [twitterId, setTwitterId] = useState<string>();
const [verifying, setVerifying] = useState(false);
Expand Down Expand Up @@ -172,8 +188,12 @@ export function SettingsView() {
const sign = await wallet.wallet?.sign(stringToBytes('utf8', signMsg));
const pk = wallet.wallet!.getPublicKey().toBytes();

const inviterRoochAddr = isValidRoochAddress(inviterAddr)
? inviterAddr
: new BitcoinAddress(inviterAddr).genRoochAddress().toStr();

const payload = JSON.stringify({
inviter: inviterAddr,
inviter: inviterRoochAddr,
tweet_id: pureTweetId,
claimer_sign: toHEX(sign!),
public_key: toHEX(pk),
Expand Down Expand Up @@ -204,7 +224,7 @@ export function SettingsView() {

// step 2, check inviter
const inviterAddr = window.localStorage.getItem(INVITER_ADDRESS_KEY);
if (inviterAddr && inviterAddr !== '') {
if (inviterAddr && inviterAddr !== '' && inviterAddr !== address?.toStr()) {
// check invite is open
const result = await client.queryObjectStates({
filter: {
Expand Down
17 changes: 9 additions & 8 deletions infra/rooch-portal-v2/src/utils/inviter.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import type { NetworkType, ThirdPartyAddress } from "@roochnetwork/rooch-sdk"
import type { NetworkType, ThirdPartyAddress } from '@roochnetwork/rooch-sdk';

export const INVITER_ADDRESS_KEY = 'inviter-address'
export const INVITER_ADDRESS_KEY = 'inviter-address';

export const getTwitterShareText = (network: NetworkType, address?: ThirdPartyAddress) => {
const networkText = network === 'mainnet' ? 'PreMainnet' : 'Testnet'
return `BTC:${address?.toStr()}
const networkText = network === 'mainnet' ? 'PreMainnet' : 'Testnet';
return `BTC:${address?.toStr()}
Rooch ${networkText} is live! Bind your Twitter to earn RGas, and visit https://${network === 'mainnet' ? '':'test-'}grow.rooch.network to earn rewards with your BTC.
Rooch ${networkText} is live! Bind your Twitter to earn RGas, and visit https://${network === 'mainnet' ? '' : 'test-'}grow.rooch.network to earn rewards with your BTC.
Join Rooch:
${getShareLink(network, address)}
#RoochNetwork #${networkText}`
}
#RoochNetwork #${networkText}`;
};

export const getShareLink = (network: NetworkType, address?: ThirdPartyAddress) => `https://${network === 'mainnet' ? '':'test-'}portal.rooch.network/inviter/${address?.genRoochAddress().toBech32Address()}`
export const getShareLink = (network: NetworkType, address?: ThirdPartyAddress) =>
`https://${network === 'mainnet' ? '' : 'test-'}portal.rooch.network/inviter/${address?.toStr()}`;
21 changes: 10 additions & 11 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

165 changes: 165 additions & 0 deletions sdk/typescript/rooch-sdk/test-e2e/case/grow.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
// Copyright (c) RoochNetwork
// SPDX-License-Identifier: Apache-2.0

import { beforeAll, describe, it, afterAll } from 'vitest'
import { TestBox } from '../setup.js'
import { Args, bcs } from '../../src/bcs/index.js'
import { BitcoinAddress, BitcoinNetowkType, fromHEX, getRoochNodeUrl, RoochAddress, StateKVView } from "../../src";

describe('Checkpoints Transfer API', () => {
let testBox: TestBox

beforeAll(async () => {
testBox = TestBox.setup(getRoochNodeUrl('mainnet'))
})

afterAll(async () => {
testBox.cleanEnv()
})

type VoterInfo = {
voteTime: number
address: string
value: number
}

it('export all votes', async () => {
let votes: VoterInfo[] = []

// find 2025-1-5-20 the closest deal
// const txResult = await testBox.getClient().queryTransactions({
// filter: {
// time_range: {
// start_time: (1736078340*1000).toString(),
// end_time: (1736078400 * 1000).toString()
// }
// }
// })
//
// txResult.data.sort((a, b) => Number(a.transaction.sequence_info.tx_timestamp) - Number(b.transaction.sequence_info.tx_timestamp))
// tx order 72730361
// tx hash 0x54adf5ddc03b1083f9146645e1d7ecaa5b272a66c449a96ec82f38073713c382
// state root 0x42d23fdaaf5ec6cd62c7f6f2ba527e397ea3d45d8c1f9d5956054aa8b8122271
const getAllVoters = async (table: string, cursor?: string) => {
const result = await testBox.getClient().listStates({
accessPath: `/table/${table}`,
stateOption: {
stateRoot: '0x42d23fdaaf5ec6cd62c7f6f2ba527e397ea3d45d8c1f9d5956054aa8b8122271',
},
cursor,
limit: '200',
})

const items = result.data.map((item) => {
//0x292467201e8b21f9188f722df170854e97681353da66ec16586817abaad96c36a301000000000000000000000000000000000000000000000000000000000000
const d = bcs.struct('xxx', {
address: bcs.bytes(32),
value: bcs.u256(),
})

const view = item.state.value
const decode = d.parse(fromHEX(view))
return {
voteTime: Number(item.state.created_at),
address: new RoochAddress(decode.address).toHexAddress(),
value: Number(decode.value),
}
})
votes = votes.concat(items).sort((a, b) => b.value - a.value)
if (result.has_next_page) {
await getAllVoters(table, result.next_cursor || undefined)
} else {
}
}

await getAllVoters('0x8b9d2a598a1f2d9cbdec84a479360afb8431ef5b19f871bf36d9de8ad19d9041')

const endTime = 1736078400 * 1000
votes = votes.filter((item) => item.voteTime < endTime)

const with1000 = votes.slice(0, 1000)

const resultAddressMap = await testBox.getClient().executeViewFunction({
target: '0x3::address_mapping::resolve_bitcoin_batch',
args: [
Args.vec(
'address',
with1000.map((item) => item.address),
),
],
})

const warpWith1000 = with1000.map((item, i) => {
const tmp = (resultAddressMap.return_values![0].decoded_value as any).value[i][0]
const btcAddress = new BitcoinAddress(tmp, BitcoinNetowkType.Bitcoin).toStr()
return {
...item,
btcAddress,
roochAddress: new RoochAddress(item.address).toBech32Address(),
}
})

const json = JSON.stringify(warpWith1000)

console.log(json)
})

it('export all register', async () => {
// const result = await testBox.getClient().queryObjectStates({
// filter: {
// object_type: '0x701c21bf1c8cd5af8c42983890d8ca55e7a820171b8e744c13f2d9998bf76cc3::grow_registration::Registration'
// }
// })

//main 0xa1e5d1779e9764839a0526e35d5972d28584d3dcfac1d2305e231b6490a59740
//test 0xa21c5dd091454a554bacde8210bfe0aed7d392af04b04d26a155c8f8cfeac9dc
let votes: StateKVView[] = []
let nextCursor: string | undefined | null = undefined
while (true) {
const result = await testBox.getClient().listStates({
accessPath: '/table/0xa1e5d1779e9764839a0526e35d5972d28584d3dcfac1d2305e231b6490a59740',
limit: '200',
cursor: nextCursor
})
nextCursor = result.next_cursor
votes = votes.concat(result.data)

if (!result.has_next_page) {
break
}
}

const formatVotes = votes.map((item) => {
const view = item.state.decoded_value!.value! as any
return {
address: view.name,
roochAddress: new RoochAddress(view.name).toBech32Address(),
voteCount: view.value!.value!.amount,
recipientAddress: view.value!.value!.register_info,
}
})

const resultAddressMap = await testBox.getClient().executeViewFunction({
target: '0x3::address_mapping::resolve_bitcoin_batch',
args: [
Args.vec(
'address',
formatVotes.map((item) => item.address),
),
],
})

const finalVotes = formatVotes.map((item, i) => {
const tmp = (resultAddressMap.return_values![0].decoded_value as any).value[i][0]
const btcAddress = new BitcoinAddress(tmp, BitcoinNetowkType.Bitcoin).toStr()
return {
...item,
btcAddress: btcAddress,
}
})

const json = JSON.stringify(finalVotes)

console.log(json)
})
})
8 changes: 4 additions & 4 deletions sdk/typescript/rooch-sdk/test-e2e/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ export class TestBox extends TestBoxA {
private client: RoochClient
keypair: Secp256k1Keypair

constructor(keypair: Secp256k1Keypair) {
constructor(keypair: Secp256k1Keypair, url?: string) {
super()
this.keypair = keypair
this.client = new RoochClient({ url: DEFAULT_NODE_URL })
this.client = new RoochClient({ url: url || DEFAULT_NODE_URL })
}

static setup(): TestBox {
static setup(url?: string): TestBox {
const kp = Secp256k1Keypair.generate()
return new TestBox(kp)
return new TestBox(kp, url)
}

async loadRoochEnv(
Expand Down

0 comments on commit 53e1ec7

Please sign in to comment.