Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add grow export e2e & inviter address change 2 btc #3160

Merged
merged 1 commit into from
Jan 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading