Skip to content

Commit

Permalink
add deploy scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
irfi committed Apr 10, 2021
1 parent c0d57f1 commit 3221153
Show file tree
Hide file tree
Showing 5 changed files with 250 additions and 3 deletions.
17 changes: 17 additions & 0 deletions deployContract.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
require('dotenv').config()
const Near = require('./src/helpers/Near')

const deploy = async () => {
const near = new Near()

await near.init()

try {
await near.deployContract()
} catch (err) {
console.log(err)
}
}

deploy()

2 changes: 2 additions & 0 deletions env.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
TESTNET_ROOT_ACCOUNT='{"account_id":"","public_key":"","private_key":""}'
TESTNET_CONTRACT_ACCOUNT='{"account_id":"","public_key":"","private_key":""}'
18 changes: 15 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
"scripts": {
"build": "cargo build --all --target wasm32-unknown-unknown --release",
"postbuild": "cp target/wasm32-unknown-unknown/release/paras_claim_rewards_contract.wasm ./res/",
"dev": "near dev-deploy --wasmFile ./res/paras_claim_rewards_contract.wasm",
"test": "cargo test -- --nocapture --color always"
"test": "cargo test -- --nocapture --color always",
"deploy:contract:dev": "yarn build && NODE_ENV=testnet near dev-deploy --wasmFile ./res/paras_claim_rewards_contract.wasm",
"deploy:contract:testnet": "yarn build && NODE_ENV=testnet node deployContract.js",
"deploy:contract:mainnet": "yarn build && NODE_ENV=mainnet node deployContract.js"
},
"repository": {
"type": "git",
Expand All @@ -19,5 +21,15 @@
"smart-contract"
],
"author": "Paras",
"license": "(MIT AND Apache-2.0)"
"license": "(MIT AND Apache-2.0)",
"dependencies": {
"axios": "^0.21.1",
"blurhash": "^1.1.3",
"body-parser": "^1.19.0",
"bs58": "^4.0.1",
"dotenv": "^8.2.0",
"js-base64": "^3.5.2",
"near-api-js": "^0.31.0",
"sha256": "^0.2.0"
}
}
70 changes: 70 additions & 0 deletions src/configs/near.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
function getConfig(env, contractName) {
if (!contractName) {
throw '[env] contractName not found'
}

switch (env) {
case 'mainnet':
return {
networkId: 'mainnet',
nodeUrl: 'https://rpc.mainnet.near.org',
contractName: contractName,
walletUrl: 'https://wallet.mainnet.near.org',
helperUrl: 'https://helper.mainnet.near.org',
}
case 'development':
case 'testnet':
return {
networkId: 'default',
nodeUrl: 'https://rpc.testnet.near.org',
contractName: contractName,
walletUrl: 'https://wallet.testnet.near.org',
helperUrl: 'https://helper.testnet.near.org',
}
case 'devnet':
return {
networkId: 'devnet',
nodeUrl: 'https://rpc.devnet.near.org',
contractName: contractName,
walletUrl: 'https://wallet.devnet.near.org',
helperUrl: 'https://helper.devnet.near.org',
}
case 'betanet':
return {
networkId: 'betanet',
nodeUrl: 'https://rpc.betanet.near.org',
contractName: contractName,
walletUrl: 'https://wallet.betanet.near.org',
helperUrl: 'https://helper.betanet.near.org',
}
case 'local':
return {
networkId: 'local',
nodeUrl: 'http://localhost:3030',
keyPath: `${process.env.HOME}/.near/validator_key.json`,
walletUrl: 'http://localhost:4000/wallet',
contractName: contractName,
}
case 'test':
case 'ci':
return {
networkId: 'shared-test',
nodeUrl: 'https://rpc.ci-testnet.near.org',
contractName: contractName,
masterAccount: 'test.near',
}
case 'ci-betanet':
return {
networkId: 'shared-test-staging',
nodeUrl: 'https://rpc.ci-betanet.near.org',
contractName: contractName,
masterAccount: 'test.near',
}
default:
throw Error(
`Unconfigured environment '${env}'. Can be configured in src/config.js.`
)
}
}

module.exports = getConfig
146 changes: 146 additions & 0 deletions src/helpers/Near.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
const { Contract, KeyPair, connect } = require('near-api-js')
const { join } = require('path')
const { InMemoryKeyStore } = require('near-api-js').keyStores
const getConfig = require('../configs/near')

const Base64 = require('js-base64').Base64
const nacl = require('tweetnacl')
const bs58 = require('bs58')
const sha256 = require('js-sha256')
const axios = require('axios')

const _hexToArr = (str) => {
try {
return new Uint8Array(
str.match(/.{1,2}/g).map((byte) => parseInt(byte, 16))
)
} catch (err) {
throw err
}
}

const contractConfig = {
changeMethods: [
'new',
'ft_transfer',
'ft_transfer_call',
'ft_resolve_transfer'
],
viewMethods: [
'ft_total_supply',
'ft_balance_of',
'ft_metadata'
]
}

class Near {
constructor() {
this.ctx = null
this.config = null
}

async init() {
console.log('==================================================')
console.log(`ENV: ${process.env.NODE_ENV}`)
const ROOT_ACCOUNT =
process.env[`${process.env.NODE_ENV.toUpperCase()}_ROOT_ACCOUNT`]
const CONTRACT_ACCOUNT =
process.env[`${process.env.NODE_ENV.toUpperCase()}_CONTRACT_ACCOUNT`]

if (!ROOT_ACCOUNT) {
throw '[env] ROOT_ACCOUNT not found'
}
if (!CONTRACT_ACCOUNT) {
throw '[env] CONTRACT_ACCOUNT not found'
}
const rootAccount = JSON.parse(ROOT_ACCOUNT)
const contractAccount = JSON.parse(CONTRACT_ACCOUNT)
console.log(`ROOT ACCOUNT: ${rootAccount.account_id}`)
console.log(`CONTRACT ACCOUNT: ${contractAccount.account_id}`)
console.log('==================================================')
const config = getConfig(
process.env.NODE_ENV || 'testnet',
contractAccount.account_id
)
this.config = config

const keyStore = new InMemoryKeyStore()

// add root account
const rootKeyPair = KeyPair.fromString(
rootAccount.secret_key || rootAccount.private_key
)
await keyStore.setKey(config.networkId, rootAccount.account_id, rootKeyPair)

// add contract account
const contractKeyPair = KeyPair.fromString(
contractAccount.secret_key || contractAccount.private_key
)
await keyStore.setKey(
config.networkId,
contractAccount.account_id,
contractKeyPair
)

const near = await connect({
deps: {
keyStore: keyStore,
},
...config,
})
this.ctx = near
this.masterAccount = await near.account(rootAccount.account_id)
this.contractAccount = await near.account(contractAccount.account_id)
this.contract = new Contract(
this.masterAccount,
this.contractAccount.accountId,
contractConfig
)
}

async deployContract() {
console.log('Setting up and deploying contract')
const contractPath = join(process.cwd(), 'res/paras_claim_rewards_contract.wasm')
await this.contractAccount.deployContract(
require('fs').readFileSync(contractPath)
)

console.log(`Contract ${this.contractAccount.accountId} deployed`)
}

async authSignature(authHeader) {
try {
const decodeAuthHeader = Base64.decode(authHeader)
const [userId, pubKey, signature] = decodeAuthHeader.split('&')
const pubKeyArr = _hexToArr(pubKey)
const signatureArr = _hexToArr(signature)
const hash = new Uint8Array(sha256.sha256.array(userId))
const verify = nacl.sign.detached.verify(hash, signatureArr, pubKeyArr)
if (!verify) {
throw new Error('unauthorized')
}
const b58pubKey = bs58.encode(Buffer.from(pubKey.toUpperCase(), 'hex'))
const response = await axios.post(this.config.nodeUrl, {
jsonrpc: '2.0',
id: 'dontcare',
method: 'query',
params: {
request_type: 'view_access_key',
finality: 'final',
account_id: userId,
public_key: `ed25519:${b58pubKey}`,
},
})

if (response.data.result && response.data.result.error) {
console.log(response.data.result.error)
throw new Error('unauthorized')
}
return userId
} catch (err) {
return null
}
}
}

module.exports = Near

0 comments on commit 3221153

Please sign in to comment.