Client Examples
Collection of EVM client samples for Security Token v5. For Solana examples, see Solana Client Examples.
See Relayer API utils for the utilities used in the examples.
Grant Role
import { Wallet } from 'ethers'
import { createMetaTx } from './test/utils/cmkv5/transactions/createMetaTx'
import { createTxDataForGrantRole } from './test/utils/cmkv5/transactions/createTxData'
import { sign } from 'tweetnacl'
import { createReqSignature } from './test/utils/api/createReqSignature'
async function main() {
const functionArgs = [
'0x5B7ebc132cC190058A1C153FcE07475db721bd1b', // Wallet address
'16', // Role
]
const contractAddress = '0x4eCe884Cfee1F9FFCE9F46a601E6ED3E0CcBFCeD' // AccessControl contract address
const forwarderAddr = '0x826688fadd6297671f7cB7dd780e825689bed5AA' // Forwarder contract address
const forwarderChainId = 43113 // Avalanche Fuji chain ID
const signerSk = String(
require('fs')
.readFileSync('.example-signer-sk-contract-admin-local', 'utf8')
.trim()
)
const signer = new Wallet(signerSk)
const metaTxWithSig = await createMetaTx(
{
from: signer.address,
to: contractAddress,
value: 0,
gas: 50000000,
nonce: new Date().getTime(),
deadline: Math.floor(new Date().getTime() / 1000) + 1 * 60 * 60,
data: createTxDataForGrantRole({
to: String(functionArgs[0]),
role: parseInt(String(functionArgs[1])),
}),
signature: '',
},
forwarderAddr,
forwarderChainId,
signer
)
console.log(metaTxWithSig)
const callbackUrl =
'https://webhook.site/cdd23e90-9315-4268-a29f-655bb38b38a5'
const timestamp = new Date().getTime()
const requestBody = {
metaTx: metaTxWithSig,
forwarderAddress: forwarderAddr,
callback: {
url: callbackUrl,
},
timestamp,
}
const keyPair = sign.keyPair.fromSecretKey(
Buffer.from(
String(
require('fs').readFileSync('.example-api-key-local', 'utf8').trim()
),
'base64'
)
)
const signature = createReqSignature(requestBody, keyPair.secretKey)
const sigB64 = Buffer.from(signature).toString('base64')
const pkB64 = Buffer.from(keyPair.publicKey).toString('base64')
console.log(requestBody)
console.log(sigB64)
const resp = await fetch(
'https://bi6fxskpk4.execute-api.localhost.localstack.cloud:4566/prod/api/v1/relay_meta_tx',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Request-Pk-B64': pkB64,
'X-Request-Sig-B64': sigB64,
},
body: JSON.stringify(requestBody),
}
)
if (resp.status !== 201) {
throw new Error(`Failed to submit meta tx: ${await resp.text()}`)
}
}
main()
Set Identity
import { Wallet } from 'ethers'
import { createMetaTx } from './test/utils/cmkv5/transactions/createMetaTx'
import { createTxDataForSetIdentity } from './test/utils/cmkv5/transactions/createTxData'
import { sign } from 'tweetnacl'
import { createReqSignature } from './test/utils/api/createReqSignature'
async function main() {
const functionArgs = [
'0x5B7ebc132cC190058A1C153FcE07475db721bd1b', // Wallet address
'1', // Regions
'1', // Accreditation
'1757602105', // AML/KYC Timestamp
'1757602105', // Accreditation Timestamp
'true', // AML/KYC Passed
]
const contractAddress = '0xBc4c6a27141CAB3CC7291725B30079d1CD117116' // IdentityRegistry contract address
const forwarderAddr = '0x826688fadd6297671f7cB7dd780e825689bed5AA' // Forwarder contract address
const forwarderChainId = 43113
const signerSk = String(
require('fs')
.readFileSync('.example-signer-sk-wallets-admin-local', 'utf8')
.trim()
)
const signer = new Wallet(signerSk)
const metaTxWithSig = await createMetaTx(
{
from: signer.address,
to: contractAddress,
value: 0,
gas: 50000000,
nonce: new Date().getTime(),
deadline: Math.floor(new Date().getTime() / 1000) + 1 * 60 * 60,
data: createTxDataForSetIdentity({
destination: String(functionArgs[0]),
identityInfo: {
regions: [parseInt(String(functionArgs[1]))],
accreditationType: parseInt(String(functionArgs[2])),
lastAmlKycChangeTimestamp: parseInt(String(functionArgs[3])),
lastAccreditationChangeTimestamp: parseInt(String(functionArgs[4])),
amlKycPassed: functionArgs[5] === 'true',
},
}),
signature: '',
},
forwarderAddr,
forwarderChainId,
signer
)
console.log(metaTxWithSig)
const callbackUrl =
'https://webhook.site/cdd23e90-9315-4268-a29f-655bb38b38a5'
const timestamp = new Date().getTime()
const requestBody = {
metaTx: metaTxWithSig,
forwarderAddress: forwarderAddr,
callback: {
url: callbackUrl,
},
timestamp,
}
const keyPair = sign.keyPair.fromSecretKey(
Buffer.from(
String(
require('fs').readFileSync('.example-api-key-local', 'utf8').trim()
),
'base64'
)
)
const signature = createReqSignature(requestBody, keyPair.secretKey)
const sigB64 = Buffer.from(signature).toString('base64')
const pkB64 = Buffer.from(keyPair.publicKey).toString('base64')
console.log(requestBody)
console.log(sigB64)
const resp = await fetch(
'https://bi6fxskpk4.execute-api.localhost.localstack.cloud:4566/prod/api/v1/relay_meta_tx',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Request-Pk-B64': pkB64,
'X-Request-Sig-B64': sigB64,
},
body: JSON.stringify(requestBody),
}
)
if (resp.status !== 201) {
throw new Error(`Failed to submit meta tx: ${await resp.text()}`)
}
}
main()
Set Token Type Rule
import { Wallet } from 'ethers'
import { createMetaTx } from './test/utils/cmkv5/transactions/createMetaTx'
import { createTxDataForSetTokenTypeRule } from './test/utils/cmkv5/transactions/createTxData'
import { sign } from 'tweetnacl'
import { createReqSignature } from './test/utils/api/createReqSignature'
async function main() {
const functionArgs = [
'1', // Region
'1', // Accreditation
//
'1', // Token Type
'true', // Requires AML/KYC
'true', // Is Active
]
const contractAddress = '0x2494C44FCA98A67e0248D0687D1F078D7e508bbc' // TransferRules contract address
const forwarderAddr = '0x826688fadd6297671f7cB7dd780e825689bed5AA' // Forwarder contract address
const forwarderChainId = 43113
const signerSk = String(
require('fs')
.readFileSync('.example-signer-sk-transfer-admin-local', 'utf8')
.trim()
)
const signer = new Wallet(signerSk)
const metaTxWithSig = await createMetaTx(
{
from: signer.address,
to: contractAddress,
value: 0,
gas: 50000000,
nonce: new Date().getTime(),
deadline: Math.floor(new Date().getTime() / 1000) + 1 * 60 * 60,
data: createTxDataForSetTokenTypeRule({
region: parseInt(String(functionArgs[0])),
accreditation: parseInt(String(functionArgs[1])),
tokenType: parseInt(String(functionArgs[2])),
requiresAmlKyc: functionArgs[3] === 'true',
isActive: functionArgs[4] === 'true',
}),
signature: '',
},
forwarderAddr,
forwarderChainId,
signer
)
console.log(metaTxWithSig)
const callbackUrl =
'https://webhook.site/cdd23e90-9315-4268-a29f-655bb38b38a5'
const timestamp = new Date().getTime()
const requestBody = {
metaTx: metaTxWithSig,
forwarderAddress: forwarderAddr,
callback: {
url: callbackUrl,
},
timestamp,
}
const keyPair = sign.keyPair.fromSecretKey(
Buffer.from(
String(
require('fs').readFileSync('.example-api-key-local', 'utf8').trim()
),
'base64'
)
)
const signature = createReqSignature(requestBody, keyPair.secretKey)
const sigB64 = Buffer.from(signature).toString('base64')
const pkB64 = Buffer.from(keyPair.publicKey).toString('base64')
console.log(requestBody)
console.log(sigB64)
const resp = await fetch(
'https://bi6fxskpk4.execute-api.localhost.localstack.cloud:4566/prod/api/v1/relay_meta_tx',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Request-Pk-B64': pkB64,
'X-Request-Sig-B64': sigB64,
},
body: JSON.stringify(requestBody),
}
)
if (resp.status !== 201) {
throw new Error(`Failed to submit meta tx: ${await resp.text()}`)
}
}
main()
Mint
import { Wallet } from 'ethers'
import { createMetaTx } from './test/utils/cmkv5/transactions/createMetaTx'
import { createTxDataForMint } from './test/utils/cmkv5/transactions/createTxData'
import { sign } from 'tweetnacl'
import { createReqSignature } from './test/utils/api/createReqSignature'
async function main() {
const functionArgs = [
'0x5B7ebc132cC190058A1C153FcE07475db721bd1b', // Recipient
'100', // Amount
]
const contractAddress = '0x1a35dc5e96A60941cB8cCbD869a897B1f68A7955' // Token contract address
const forwarderAddr = '0x826688fadd6297671f7cB7dd780e825689bed5AA' // Forwarder contract address
const forwarderChainId = 43113
const signerSk = String(
require('fs')
.readFileSync('.example-signer-sk-reserve-admin-local', 'utf8')
.trim()
)
const signer = new Wallet(signerSk)
const metaTxWithSig = await createMetaTx(
{
from: signer.address,
to: contractAddress,
value: 0,
gas: 50000000,
nonce: new Date().getTime(),
deadline: Math.floor(new Date().getTime() / 1000) + 1 * 60 * 60,
data: createTxDataForMint({
to: String(functionArgs[0]),
value: parseInt(String(functionArgs[1])),
}),
signature: '',
},
forwarderAddr,
forwarderChainId,
signer
)
console.log(metaTxWithSig)
const callbackUrl =
'https://webhook.site/cdd23e90-9315-4268-a29f-655bb38b38a5'
const timestamp = new Date().getTime()
const requestBody = {
metaTx: metaTxWithSig,
forwarderAddress: forwarderAddr,
callback: {
url: callbackUrl,
},
timestamp,
}
const keyPair = sign.keyPair.fromSecretKey(
Buffer.from(
String(
require('fs').readFileSync('.example-api-key-local', 'utf8').trim()
),
'base64'
)
)
const signature = createReqSignature(requestBody, keyPair.secretKey)
const sigB64 = Buffer.from(signature).toString('base64')
const pkB64 = Buffer.from(keyPair.publicKey).toString('base64')
console.log(requestBody)
console.log(sigB64)
const resp = await fetch(
'https://bi6fxskpk4.execute-api.localhost.localstack.cloud:4566/prod/api/v1/relay_meta_tx',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Request-Pk-B64': pkB64,
'X-Request-Sig-B64': sigB64,
},
body: JSON.stringify(requestBody),
}
)
if (resp.status !== 201) {
throw new Error(`Failed to submit meta tx: ${await resp.text()}`)
}
}
main()