Advertisement
Akuukis

FIC Network - FIC smart contract 2/2

Jul 11th, 2018
142
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. const StellarSdk = require('stellar-sdk')
  2.  
  3. const LIVE_LOCKUP_0 = 1526425200;  // May 15
  4. const LIVE_LOCKUP_90 = LIVE_LOCKUP_0 + (60 * 60 * 24) * 90; // Mon, 13 Aug 2018 23:00:00 +0000
  5. const LIVE_LOCKUP_180 = LIVE_LOCKUP_0 + (60 * 60 * 24) * 180; // Sun, 11 Nov 2018 23:00:00 +0000
  6.  
  7. const TEST_LOCKUP_0 = 1531116000;  // Mon, 09 Jul 2018 12:00:00 +0000
  8. const TEST_LOCKUP_90 = TEST_LOCKUP_0 + (60 * 60 * 24) * 5; // Fri, 14 Jul 2018 6:00:00 +0000
  9. const TEST_LOCKUP_180 = TEST_LOCKUP_0 + (60 * 60 * 24) * 10; // Wed, 19 Jul 2018 6:00:00 +0000
  10.  
  11. // Queried from "https://s3.amazonaws.com/ficnetwork-public/ico.json" where we will update FIC coin distribution state.
  12. const ficDistributorAddress = "GAWLROE3Z6TKZ76VE5COZIO4PBI4YZ6STXGNRQF4HDRASKIXDMHJ7MDP";
  13.  
  14. const Unlock = (ficAddress, lockupAddress, lockup) => async () => {
  15.   const SUBMIT = async (te) => StellarApi.server.submitTransaction(te).catch((e)=>e).then((res)=>res)
  16.   let lockupAccount;
  17.   try {
  18.     lockupAccount = await StellarApi.server.loadAccount(lockupAddress);
  19.     lockupAccount._baseAccount.sequence.minus(2);
  20.   } catch(e) {
  21.     if(e instanceof StellarSdk.NotFoundError) throw new Error(`Already unlocked (${lockupAddress})`);
  22.     throw e;
  23.   }
  24.   // console.log(`Lockup account ${lockupAddress} sequence & balance:`, lockupAccount.sequenceNumber(), lockupAccount.balances)
  25.   let timebounds;
  26.   switch(SettingFactory.getCurrentNetwork().networkPassphrase) {
  27.     case(SettingFactory.NETWORKS.ficTest.networkPassphrase): {
  28.       timebounds = {minTime: ({0: TEST_LOCKUP_0, 1: TEST_LOCKUP_90, 2: TEST_LOCKUP_180})[lockup], maxTime: Number.MAX_SAFE_INTEGER}
  29.       break;
  30.     }
  31.     case(SettingFactory.NETWORKS.fic.networkPassphrase): {
  32.       timebounds = {minTime: ({0: LIVE_LOCKUP_0, 1: LIVE_LOCKUP_90, 2: LIVE_LOCKUP_180})[lockup], maxTime: Number.MAX_SAFE_INTEGER}
  33.       break;
  34.     }
  35.     default: {
  36.       timebounds = undefined;
  37.       break;
  38.     }
  39.   }
  40.   const prete1 = new StellarSdk.TransactionBuilder(lockupAccount, { timebounds })
  41.     .addOperation(StellarSdk.Operation.createAccount({
  42.       source: lockupAddress,
  43.       destination: ficAddress,
  44.       startingBalance: '400',
  45.     }))
  46.     .build();
  47.   const prete2 = new StellarSdk.TransactionBuilder(lockupAccount, { timebounds })
  48.     .addOperation(StellarSdk.Operation.accountMerge({
  49.       source: lockupAddress,
  50.       destination: ficAddress,
  51.     }))
  52.     .build();
  53.   const resultCreate = await SUBMIT(prete1); // Create user account ${ficAddress}
  54.   const resultUnlock = await SUBMIT(prete2); // Merge into user account ${ficAddress}
  55.   return {
  56.     resultCreate,
  57.     resultUnlock,
  58.   }
  59. }
  60.  
  61. const getFicTxs = async (userAddress) => {
  62.   const directoryResponse = await fetch(`${StellarApi.server.serverURL}/accounts/${ficDistributorAddress}`);
  63.   const directory = await directoryResponse.json();
  64.   const lockupAddressMap = directory.data;
  65.   const userLockups = Object.keys(lockupAddressMap).filter((key)=>key.slice(0,56) === userAddress);
  66.   const responses = [];
  67.   for(const key of userLockups) {
  68.     const lockupAddress = Buffer.from(lockupAddressMap[key], 'base64').toString();
  69.     const res = await fetch(`${StellarApi.server.serverURL}/accounts/${lockupAddress}/transactions?order=desc&limit=4`);
  70.     const json = await res.json();
  71.     const transactions = json._embedded.records;
  72.     transactions.forEach((transaction) => transaction.envelope = new StellarSdk.Transaction(transaction.envelope_xdr));
  73.     const creationTransation = transactions.find((tx)=>tx.source_account==ficDistributorAddress && tx.envelope.operations.find((op)=>op.type === 'createAccount'))
  74.     const setupTransaction = transactions.find((tx)=>tx.source_account==ficDistributorAddress && tx.envelope.operations.find((op)=>op.type === 'setOptions'));
  75.     const createTransaction = transactions.find((tx)=>tx.source_account==lockupAddress && tx.envelope.operations.find((op)=>op.type === 'createAccount'));
  76.     const mergeTransaction = transactions.find((tx)=>tx.source_account==lockupAddress && tx.envelope.operations.find((op)=>op.type === 'accountMerge'));
  77.     const lockupCode = creationTransation.envelope.memo.value.readInt8(31);
  78.     const lockup = ({0: '0', 1:'90', 2:'180'})[lockupCode];
  79.     const r = {
  80.       lockupAddress,
  81.       ficNonce: key.slice(57),
  82.       ethAddress: creationTransation.envelope.memo.value.slice(0, 20).toString('hex'),
  83.       lockup,
  84.       amount: creationTransation.envelope.operations[0].startingBalance.split('.')[0],  // Ghetto rounding to integers.
  85.       ethTxHash: setupTransaction && setupTransaction.envelope.memo.value.toString('hex'),
  86.       tx1: creationTransation && {timestamp: creationTransation.created_at, txId: creationTransation.id},
  87.       tx2: setupTransaction   && {timestamp: setupTransaction.created_at  , txId: setupTransaction.id  },
  88.       tx3: createTransaction  && {timestamp: createTransaction.created_at , txId: createTransaction.id },
  89.       tx4: mergeTransaction   && {timestamp: mergeTransaction.created_at  , txId: mergeTransaction.id  },
  90.       unlock: Unlock(userAddress, lockupAddress, lockupCode),
  91.     };
  92.     responses.push(r);
  93.   }
  94.   return responses;
  95. }
  96.  
  97. // Claim all of them! Note that claiming already unlocked FIC coins will give error;
  98. Promise.all(getFicTxs(myFicAddress).map((ficTx)=>unlock()))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement