tests: example rust contracts moved from warp-wasm-templates
This commit is contained in:
9
crates/pst/deploy/local/deploy-local.js
Normal file
9
crates/pst/deploy/local/deploy-local.js
Normal file
@@ -0,0 +1,9 @@
|
||||
const { deploy } = require('../scripts/deploy');
|
||||
|
||||
deploy(
|
||||
'localhost',
|
||||
1984,
|
||||
'http',
|
||||
'local',
|
||||
'deploy/local/wallet_local.json'
|
||||
).finally();
|
||||
9
crates/pst/deploy/local/interact-balance-local.js
Normal file
9
crates/pst/deploy/local/interact-balance-local.js
Normal file
@@ -0,0 +1,9 @@
|
||||
const { interactBalance } = require('../scripts/interact-balance');
|
||||
|
||||
interactBalance(
|
||||
'localhost',
|
||||
1984,
|
||||
'http',
|
||||
'local',
|
||||
'deploy/local/wallet_local.json'
|
||||
).finally();
|
||||
9
crates/pst/deploy/local/interact-transfer-local.js
Normal file
9
crates/pst/deploy/local/interact-transfer-local.js
Normal file
@@ -0,0 +1,9 @@
|
||||
const { interactTransfer } = require('../scripts/interact-transfer');
|
||||
|
||||
interactTransfer(
|
||||
'localhost',
|
||||
1984,
|
||||
'http',
|
||||
'local',
|
||||
'deploy/local/wallet_local.json'
|
||||
).finally();
|
||||
9
crates/pst/deploy/local/read-contract-state-local.js
Normal file
9
crates/pst/deploy/local/read-contract-state-local.js
Normal file
@@ -0,0 +1,9 @@
|
||||
const { readContractState } = require('../scripts/read-contract-state');
|
||||
|
||||
readContractState(
|
||||
'localhost',
|
||||
1984,
|
||||
'http',
|
||||
'local',
|
||||
'deploy/local/wallet_local.json'
|
||||
).finally();
|
||||
1
crates/pst/deploy/mainnet/contract-tx-id.txt
Normal file
1
crates/pst/deploy/mainnet/contract-tx-id.txt
Normal file
@@ -0,0 +1 @@
|
||||
tom87dg3RgkUGTfOwIO-eNb5WCvoGkFCS44B7koVW_I
|
||||
9
crates/pst/deploy/mainnet/deploy-mainnet.js
Normal file
9
crates/pst/deploy/mainnet/deploy-mainnet.js
Normal file
@@ -0,0 +1,9 @@
|
||||
const { deploy } = require('../scripts/deploy');
|
||||
|
||||
deploy(
|
||||
'arweave.net',
|
||||
443,
|
||||
'https',
|
||||
'mainnet',
|
||||
'deploy/mainnet/wallet_mainnet.json'
|
||||
).finally();
|
||||
9
crates/pst/deploy/mainnet/interact-balance-mainnet.js
Normal file
9
crates/pst/deploy/mainnet/interact-balance-mainnet.js
Normal file
@@ -0,0 +1,9 @@
|
||||
const { interactBalance } = require('../scripts/interact-balance');
|
||||
|
||||
interactBalance(
|
||||
'arweave.net',
|
||||
443,
|
||||
'https',
|
||||
'mainnet',
|
||||
'deploy/mainnet/wallet_mainnet.json'
|
||||
).finally();
|
||||
9
crates/pst/deploy/mainnet/interact-transfer-mainnet.js
Normal file
9
crates/pst/deploy/mainnet/interact-transfer-mainnet.js
Normal file
@@ -0,0 +1,9 @@
|
||||
const { interactTransfer } = require('../scripts/interact-transfer');
|
||||
|
||||
interactTransfer(
|
||||
'arweave.net',
|
||||
443,
|
||||
'https',
|
||||
'mainnet',
|
||||
'deploy/mainnet/wallet_mainnet.json'
|
||||
).finally();
|
||||
9
crates/pst/deploy/mainnet/read-contract-state-mainnet.js
Normal file
9
crates/pst/deploy/mainnet/read-contract-state-mainnet.js
Normal file
@@ -0,0 +1,9 @@
|
||||
const { readContractState } = require('../scripts/read-contract-state');
|
||||
|
||||
readContractState(
|
||||
'arweave.net',
|
||||
443,
|
||||
'https',
|
||||
'mainnet',
|
||||
'deploy/mainnet/wallet_mainnet.json'
|
||||
).finally();
|
||||
56
crates/pst/deploy/scripts/deploy.js
Normal file
56
crates/pst/deploy/scripts/deploy.js
Normal file
@@ -0,0 +1,56 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { WarpFactory, defaultCacheOptions } = require('warp-contracts');
|
||||
const { mineBlock } = require('./utils/mine-block');
|
||||
const { loadWallet, walletAddress } = require('./utils/load-wallet');
|
||||
const { connectArweave } = require('./utils/connect-arweave');
|
||||
|
||||
module.exports.deploy = async function (host, port, protocol, target, walletJwk) {
|
||||
const arweave = connectArweave(host, port, protocol);
|
||||
const warp = module.exports.getWarpInstance(port, target);
|
||||
const wallet = await loadWallet(arweave, walletJwk, target);
|
||||
const walletAddr = await walletAddress(arweave, wallet);
|
||||
const contractSrc = fs.readFileSync(path.join(__dirname, '../../contract/implementation/pkg/rust-contract_bg.wasm'));
|
||||
const stateFromFile = JSON.parse(fs.readFileSync(path.join(__dirname, '../state/init-state.json'), 'utf-8'));
|
||||
|
||||
const initialState = {
|
||||
...stateFromFile,
|
||||
...{
|
||||
owner: walletAddr,
|
||||
balances: {
|
||||
...stateFromFile.balances,
|
||||
[walletAddr]: 10000000,
|
||||
},
|
||||
},
|
||||
};
|
||||
const {contractTxId} = await warp.createContract.deploy(
|
||||
{
|
||||
wallet,
|
||||
initState: JSON.stringify(initialState),
|
||||
src: contractSrc,
|
||||
wasmSrcCodeDir: path.join(__dirname, '../../contract/implementation/src'),
|
||||
wasmGlueCode: path.join(__dirname, '../../contract/implementation/pkg/rust-contract.js'),
|
||||
}
|
||||
);
|
||||
fs.writeFileSync(path.join(__dirname, `../${target}/contract-tx-id.txt`), contractTxId);
|
||||
|
||||
if (target == 'testnet' || target == 'local') {
|
||||
await mineBlock(arweave);
|
||||
}
|
||||
|
||||
if (target == 'testnet') {
|
||||
console.log(`Check contract at https://sonar.warp.cc/#/app/contract/${contractTxId}?network=testnet`);
|
||||
} else {
|
||||
console.log('Contract tx id', contractTxId);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports.getWarpInstance = function (port, target) {
|
||||
if (target == 'local') {
|
||||
return WarpFactory.forLocal(port);
|
||||
} else if (target == 'testnet') {
|
||||
return WarpFactory.forTestnet();
|
||||
} else {
|
||||
return WarpFactory.forMainnet({ ...defaultCacheOptions, inMemory: true });
|
||||
}
|
||||
}
|
||||
23
crates/pst/deploy/scripts/interact-balance.js
Normal file
23
crates/pst/deploy/scripts/interact-balance.js
Normal file
@@ -0,0 +1,23 @@
|
||||
const { loadWallet } = require('./utils/load-wallet');
|
||||
const { connectArweave } = require('./utils/connect-arweave');
|
||||
const { connectPstContract } = require('./utils/connect-pst-contract');
|
||||
const { contractTxId } = require('./utils/contract-tx-id');
|
||||
|
||||
module.exports.interactBalance = async function (
|
||||
host,
|
||||
port,
|
||||
protocol,
|
||||
target,
|
||||
walletJwk
|
||||
) {
|
||||
const arweave = connectArweave(host, port, protocol);
|
||||
const wallet = await loadWallet(arweave, walletJwk, target, true);
|
||||
|
||||
const walletAddress = await arweave.wallets.jwkToAddress(wallet);
|
||||
|
||||
const txId = contractTxId(target);
|
||||
const pst = await connectPstContract(arweave, wallet, txId, target);
|
||||
const balance = await pst.currentBalance(walletAddress);
|
||||
|
||||
console.log(balance);
|
||||
};
|
||||
29
crates/pst/deploy/scripts/interact-transfer.js
Normal file
29
crates/pst/deploy/scripts/interact-transfer.js
Normal file
@@ -0,0 +1,29 @@
|
||||
const { loadWallet } = require('./utils/load-wallet');
|
||||
const { connectArweave } = require('./utils/connect-arweave');
|
||||
const { connectPstContract } = require('./utils/connect-pst-contract');
|
||||
const { contractTxId } = require('./utils/contract-tx-id');
|
||||
const { mineBlock } = require('./utils/mine-block');
|
||||
|
||||
module.exports.interactTransfer = async function (host, port, protocol, target, walletJwk) {
|
||||
const arweave = connectArweave(host, port, protocol);
|
||||
const wallet = await loadWallet(arweave, walletJwk, target, true);
|
||||
const txId = contractTxId(target);
|
||||
const pst = await connectPstContract(arweave, wallet, txId, target);
|
||||
|
||||
const transferId = await pst.transfer({
|
||||
target: 'uhE-QeYS8i4pmUtnxQyHD7dzXFNaJ9oMK-IM-QPNY6M',
|
||||
qty: 555,
|
||||
});
|
||||
|
||||
await mineBlock(arweave);
|
||||
const state = await pst.currentState();
|
||||
|
||||
console.log('Updated state:', state);
|
||||
console.log('Contract tx id', txId);
|
||||
|
||||
if (target == 'testnet') {
|
||||
console.log(`Check transfer interaction at https://sonar.warp.cc/#/app/interaction/${transferId}?network=testnet`);
|
||||
} else {
|
||||
console.log('Transfer tx id', transferId);
|
||||
}
|
||||
};
|
||||
22
crates/pst/deploy/scripts/read-contract-state.js
Normal file
22
crates/pst/deploy/scripts/read-contract-state.js
Normal file
@@ -0,0 +1,22 @@
|
||||
const { loadWallet } = require('./utils/load-wallet');
|
||||
const { connectArweave } = require('./utils/connect-arweave');
|
||||
const { connectContract } = require('./utils/connect-contract');
|
||||
const { contractTxId } = require(`./utils/contract-tx-id`);
|
||||
|
||||
module.exports.readContractState = async function (
|
||||
host,
|
||||
port,
|
||||
protocol,
|
||||
target,
|
||||
walletJwk
|
||||
) {
|
||||
const arweave = connectArweave(host, port, protocol);
|
||||
const wallet = await loadWallet(arweave, walletJwk, target, true);
|
||||
|
||||
const txId = contractTxId(target);
|
||||
const contract = await connectContract(arweave, wallet, txId, target);
|
||||
const { cachedValue } = await contract.readState();
|
||||
|
||||
console.log('Current state:', cachedValue.state);
|
||||
console.log('Contract tx id', txId);
|
||||
};
|
||||
4
crates/pst/deploy/scripts/utils/addFunds.js
Normal file
4
crates/pst/deploy/scripts/utils/addFunds.js
Normal file
@@ -0,0 +1,4 @@
|
||||
module.exports.addFunds = async function (arweave, wallet) {
|
||||
const walletAddress = await arweave.wallets.getAddress(wallet);
|
||||
await arweave.api.get(`/mint/${walletAddress}/1000000000000000`);
|
||||
};
|
||||
9
crates/pst/deploy/scripts/utils/connect-arweave.js
Normal file
9
crates/pst/deploy/scripts/utils/connect-arweave.js
Normal file
@@ -0,0 +1,9 @@
|
||||
const Arweave = require('arweave');
|
||||
|
||||
module.exports.connectArweave = function (host, port, protocol) {
|
||||
return Arweave.init({
|
||||
host: host,
|
||||
port: port,
|
||||
protocol: protocol,
|
||||
});
|
||||
};
|
||||
15
crates/pst/deploy/scripts/utils/connect-contract.js
Normal file
15
crates/pst/deploy/scripts/utils/connect-contract.js
Normal file
@@ -0,0 +1,15 @@
|
||||
const { getWarpInstance } = require("../deploy");
|
||||
|
||||
module.exports.connectContract = async function (
|
||||
arweave,
|
||||
wallet,
|
||||
contractTxId,
|
||||
target
|
||||
) {
|
||||
console.log('Target:', target);
|
||||
|
||||
const warp = getWarpInstance(arweave.api.config.port, target);
|
||||
return warp
|
||||
.contract(contractTxId)
|
||||
.connect(wallet);
|
||||
};
|
||||
14
crates/pst/deploy/scripts/utils/connect-pst-contract.js
Normal file
14
crates/pst/deploy/scripts/utils/connect-pst-contract.js
Normal file
@@ -0,0 +1,14 @@
|
||||
const { getWarpInstance } = require("../deploy");
|
||||
|
||||
module.exports.connectPstContract = async function (
|
||||
arweave,
|
||||
wallet,
|
||||
contractTxId,
|
||||
target
|
||||
) {
|
||||
|
||||
const warp = getWarpInstance(arweave.api.config.port, target);
|
||||
return warp
|
||||
.pst(contractTxId)
|
||||
.connect(wallet);
|
||||
};
|
||||
19
crates/pst/deploy/scripts/utils/contract-tx-id.js
Normal file
19
crates/pst/deploy/scripts/utils/contract-tx-id.js
Normal file
@@ -0,0 +1,19 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
module.exports.contractTxId = function (target) {
|
||||
let txId;
|
||||
try {
|
||||
txId = fs
|
||||
.readFileSync(
|
||||
path.join(__dirname, `../../../deploy/${target}/contract-tx-id.txt`),
|
||||
'utf-8'
|
||||
)
|
||||
.trim();
|
||||
} catch (e) {
|
||||
throw new Error(
|
||||
'Contract tx id file not found! Please run deploy script first.'
|
||||
);
|
||||
}
|
||||
|
||||
return txId;
|
||||
};
|
||||
10
crates/pst/deploy/scripts/utils/create-testnet-wallet.js
Normal file
10
crates/pst/deploy/scripts/utils/create-testnet-wallet.js
Normal file
@@ -0,0 +1,10 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
module.exports.generateWallet = async function (arweave, target) {
|
||||
const wallet = await arweave.wallets.generate();
|
||||
fs.writeFileSync(
|
||||
path.join(__dirname, `../../${target}/wallet_${target}.json`),
|
||||
JSON.stringify(wallet)
|
||||
);
|
||||
};
|
||||
33
crates/pst/deploy/scripts/utils/load-wallet.js
Normal file
33
crates/pst/deploy/scripts/utils/load-wallet.js
Normal file
@@ -0,0 +1,33 @@
|
||||
const fs = require('fs');
|
||||
const { addFunds } = require('./addFunds');
|
||||
const { generateWallet } = require('./create-testnet-wallet');
|
||||
|
||||
const path = require('path');
|
||||
|
||||
module.exports.loadWallet = async function (
|
||||
arweave,
|
||||
walletJwk,
|
||||
target,
|
||||
generated
|
||||
) {
|
||||
let wallet;
|
||||
if (!generated) {
|
||||
await generateWallet(arweave, target);
|
||||
}
|
||||
|
||||
try {
|
||||
wallet = JSON.parse(fs.readFileSync(path.join(walletJwk), 'utf-8'));
|
||||
} catch (e) {
|
||||
throw new Error('Wallet file not found! Please run deploy script first.');
|
||||
}
|
||||
|
||||
if (target == 'testnet' || target == 'local') {
|
||||
await addFunds(arweave, wallet);
|
||||
}
|
||||
|
||||
return wallet;
|
||||
};
|
||||
|
||||
module.exports.walletAddress = async function (arweave, wallet) {
|
||||
return arweave.wallets.getAddress(wallet);
|
||||
};
|
||||
3
crates/pst/deploy/scripts/utils/mine-block.js
Normal file
3
crates/pst/deploy/scripts/utils/mine-block.js
Normal file
@@ -0,0 +1,3 @@
|
||||
module.exports.mineBlock = async function (arweave) {
|
||||
await arweave.api.get('mine');
|
||||
};
|
||||
7
crates/pst/deploy/state/init-state.json
Normal file
7
crates/pst/deploy/state/init-state.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"ticker": "PST TMPL RUST",
|
||||
"name": "PST Template Rust",
|
||||
"balances": {},
|
||||
"canEvolve": true,
|
||||
"evolve": null
|
||||
}
|
||||
1
crates/pst/deploy/testnet/contract-tx-id.txt
Normal file
1
crates/pst/deploy/testnet/contract-tx-id.txt
Normal file
@@ -0,0 +1 @@
|
||||
Y8sad_he0w0ryzxKvS7PGEXQbxBl142KX5OTpiPDYV0
|
||||
9
crates/pst/deploy/testnet/deploy-test.js
Normal file
9
crates/pst/deploy/testnet/deploy-test.js
Normal file
@@ -0,0 +1,9 @@
|
||||
const { deploy } = require('../scripts/deploy');
|
||||
|
||||
deploy(
|
||||
'arweave.net',
|
||||
443,
|
||||
'https',
|
||||
'testnet',
|
||||
'deploy/testnet/wallet_testnet.json'
|
||||
).finally();
|
||||
9
crates/pst/deploy/testnet/interact-balance-testnet.js
Normal file
9
crates/pst/deploy/testnet/interact-balance-testnet.js
Normal file
@@ -0,0 +1,9 @@
|
||||
const { interactBalance } = require('../scripts/interact-balance');
|
||||
|
||||
interactBalance(
|
||||
'testnet.redstone.tools',
|
||||
443,
|
||||
'https',
|
||||
'testnet',
|
||||
'deploy/testnet/wallet_testnet.json'
|
||||
).finally();
|
||||
9
crates/pst/deploy/testnet/interact-transfer-testnet.js
Normal file
9
crates/pst/deploy/testnet/interact-transfer-testnet.js
Normal file
@@ -0,0 +1,9 @@
|
||||
const { interactTransfer } = require('../scripts/interact-transfer');
|
||||
|
||||
interactTransfer(
|
||||
'testnet.redstone.tools',
|
||||
443,
|
||||
'https',
|
||||
'testnet',
|
||||
'deploy/testnet/wallet_testnet.json'
|
||||
).finally();
|
||||
9
crates/pst/deploy/testnet/read-contract-state-testnet.js
Normal file
9
crates/pst/deploy/testnet/read-contract-state-testnet.js
Normal file
@@ -0,0 +1,9 @@
|
||||
const { readContractState } = require('../scripts/read-contract-state');
|
||||
|
||||
readContractState(
|
||||
'testnet.redstone.tools',
|
||||
443,
|
||||
'https',
|
||||
'testnet',
|
||||
'deploy/testnet/wallet_testnet.json'
|
||||
).finally();
|
||||
1
crates/pst/deploy/testnet/wallet_testnet.json
Normal file
1
crates/pst/deploy/testnet/wallet_testnet.json
Normal file
@@ -0,0 +1 @@
|
||||
{"kty":"RSA","n":"zvtUbqKK76RcA1nKTmOjcZgkqLEOw40mLEmWA_Q_TgBYN4NJcZHPfWehS2Vlbalhf6ZiNu_J0Q-zk3tnk12Fkt-UDpje0uxkkigihwxOGmpB2gi6yTRpQfFg4ccG3QY9nx-R2hEOJaY056dXm9UY4gFVI_dYvqZbPt0_N8FmUgNVq9OgtkUVY07PAZA55kiqh2POWycsbv3FPgPt1D7QDj7jDuqRKBfMdHPqZF9qBiEo5kIyAPm8QCbQ0DY-pIjEMY0ENL4b2yTGRQNz-WH0wIAddGFPo9oGma8RdU5Uk82IJWpXxFF2Z4BOqVQnBBnIxXZNJpAN2WQ6xmGDtwRVBnV0l4nfzzpELEOZ98nlyY1YMBqBPqjnKP2_9M2FjdzsV8pnX5kUQE7_SjH0yAKEhRtYXcsvMF7Hy61rAUjD1RgIxqx-aJeJHGugc9I5IpobocX5dzdoRujSOIg_jTT7LzzP6BE2CK71crq-5cYicGje-DkwBoeRxJaRIZbAkp0AOsg1yQnURm3oGZaRw3qoqmcFp1eku5_HVORZJBvG5u2KSxa8giO6sNC0RN1NyD-RsnNLZ82eedpO8sn4rV_9LlTDqFcHgCuoOjt5A8GDYdJN5v6RljqHAcUWIwPC_rC9b4y80WO1vmND1P6j2uUj2wMKKQbOHVphyq2IZTS3skM","e":"AQAB","d":"ehG50uHj5L9fUM6UxLR4wVbEUATUOzo0iCwB4GUdLKiBXoP8PZGL-F60vp2XOxyJFtqO0-2JbdW_x7wg8sVWMK_RRuabi3PFQHmRG2qDaYq_OZKqbl2NsklkJOPXRWUX1I-u2hfy6vth-jk0LwB3g1rb1rFa0l2UNLgRP5W8_aNf1E2kW7rUiVQCO97OduTmRaD0I8gvqWna-N8iVWmSFMS77qEiaK3Yc9mlI_stsV2_HEVv7ila_86kmhdTzH-ojbyn_V8dWJoQoMUPkcVWrm0gcfGuIWlFOUAJoNBIiz7NC5vzFSIiHZqLScwKkp2OTf6eM58Du_EjxLngD4Drjyr-ev_ziEeWVRVd-HgWzhhBplOuFyW7jViKLuJ87mKmArbuA1TpZvpjuraAMi9DNE_2NRuJJn0cYtQLMeDQhZo7TiYVs55jGjEvel2iPLcMAmL_ac6zvLlX2o5XP2MdYv1nfYGyhBz9XO-6toolVsNtXkNPayEDBeU_bPn2igRrjQuGQuuvpbGQMtcNUVgKtUXzzwkJZxji6wt8GVF2D74COPYRFhBYO3TlBNpr_aVI537sJx7P38BPDqH4Tc0MpV72mINqMgJ56mFsepT75UzBAC8BDw5AKeq1rqIE4XoVFTuEXURmLwdDJJhc4Dl_Syc3h0IRiL-bnEZA7usvddE","p":"6_z2eBPZAhMNJ5edjMYW9Zo-zh0y-BCevTQn-4jhKE7z07nNAbofP_PHtEMZYZifSAmkN8QG6TQnyrn-txWfUTGBfE6CwE-GO-AVAJF_OneBZK-9X4W8hNrbRTsGGXRSfF35cuOmMwmqUkqxq03BTnK5pT0PzIHFv2OEm0d5ukq78eC3cd54f1M9QZ9ZUBtOAdvXB0A-EIQBw24m5KtLctJfGB9rGxRyrjyDrvFLSvgUn-G2kjcRnWn_l2mzTPjSct7Niyf1QXjBA11HwT7T98f13-iUY_U29Klk_0DOyL3ynVUHu-SdcPz5JGszetxx9S_gBKAK-FiIWp8sHKsvmQ","q":"4Iir0P8qYme7wRHmDRiOcSSDz9XjrGwYZU8WYbIQK-ff4XOwcXmJs-wq0N1HfjZhYiMaWFRser5oXyT8Xpkw-6gCjfSHIezZ3m6OCUfSeHQ_94OYfLr_CMCA6gOb4fU7x1Y4cqxzWbb7V1W24Kv4gUa9A30hjfnmh-1pT5EMJiu-_1KECgmSmuH0PZQg3OtWfvldJCbx-FltaE9wxQElRzcfulOLDXS7_AksJUnNmY7jWj9IVoG-nmKRvAAjgf0agXOE26icuHiM1dn9oQVAri2AGTbTkmTHWCdSBoZ4G53qwo36wZQvKD4u4TMAFh5ydmlOomn7Px86xi0ciH3KOw","dp":"KC9zaQ84LPpBizRuR8KTtk8F0uN2AngSD_YJuPOeI9cN_kfteRXQrHs-zpt-fvgWZ5X8uOJQqvWOsR7rGRI9hv3_JsPX0Be6rAeEjAw6tiITjqm-fb2wVI9QN4HNkBgW08bM65uIebhzoH_HsXwUJt-ybUjwn8qZefXgZvDM8cQ4LQAvPNy9eDEchUg1VUbRCc_91eZCq11PT5A6X0YsGuln-BuhiYL55GG5qti8EZAdMvykslFeVofuVkJRnhHhBF6ccc3kHboKZCBGT8n7Hn6WiAJ7AmqHaTJPWIgYrmZqIhCQuJY9mTf61RDMO2e-oBn-88qtE40_6u6f_GHKQQ","dq":"eZIGVVaTAEziH5stUBHnreLza2iHqSet3cyAdc0PbHZThaI5-nav1Dcex4_H0dJnz9bpwMGVKrBFmp5P9nhDST6ig3HOaNPw8roxNV0p3AY1TDJ4MbCdvYNdSVdC44kAIOHSFmTA3-ZvF85VAjiaiIRgeq8Zp-GSrC4jQu1qApDVDTEERNsCAdIth9nYIUVaw80IXTao9KqWzk-U41XHdVOnXh81vsdhsQjWWiono-j1uDtjU1NUfjUoav44O31rCIQffz8_-7Fpr7Aj3zcU2jnQjdZdn3npZRWFF_tetLVAEq8FAiLVlZh1kYEnntJFb099P_raCkdCb2KlfFF_WQ","qi":"sxxizN6dhWM8Ww2Vr7Ti-vDV0YqYGdAN_Fy8gAaLtINbhk2YrzBO-q3M_HAXendE8SHFNM2f9xAnpzTJND9aww27MkSmaslY65VVjoLkoh2YONmaePKV8T0MG2ffEl1lnhvS_nq63aJWNBJm7U_wizv0yYbYTi0QI0R7wJiXaWwlA4qFPsBwbUYgzSnxU2_cesjesShbQ-shVkKdscN6QD4feEvI9io28ZDqrpHRc7TrKIYK_RKSj_8DpI1qAMlZ4VUHF-nEAEFeZ__Z4rC3rL0CvgpaCwmSKw8eHidfZCIpnOV7nFm_8_tWVphOdaodRXVXfEfOY2_8qv1UYgEUSQ"}
|
||||
Reference in New Issue
Block a user