DApp(PC Web): Anchor使用说明
安装依赖
yarn @amax/anchor-link @amax/anchor-link-browser-transport
初始化
const transport = new AnchorLinkBrowserTransport();
const link = new AnchorLink({
transport,
service: "https://fwd.aplink.app",
chains: [
{
chainId:
"208dacab3cd2e181c86841613cf05d9c60786c677e4ce86b266d0a58884968f7",
nodeUrl: "https://test-chain.ambt.art",
},
],
});
登录
anchor-link-demo
既是scope,也是session_name,可以通过这个关键字取出session信息。session存在则是在登录状态。
注:scope的类型为Name,所以符合Name规范,长度最好不要超过12位,如果输入不合法的字符串,系统会自动处理成合法(Name),比如:anchor-link-demo => anchor.link.d,不合法的字符全部处理成"."符号
const identity = await link.login("anchor-link-demo");
const { account, proof, proofKey, proofValid } = await verifyProof(
link,
identity,
);
setAccount(account);
setSession(identity.session);
验证
export async function verifyProof(link, identity) {
// Generate an array of valid chain IDs from the demo configuration
const chains = blockchains.map(chain => chain.chainId);
// Create a proof helper based on the identity results from anchor-link
const proof = IdentityProof.from(identity.proof);
// Check to see if the chainId from the proof is valid for this demo
const chain = chains.find(id => ChainId.from(id).equals(proof.chainId));
if (!chain) {
throw new Error("Unsupported chain supplied in identity proof");
}
// Load the account data from a blockchain API
let account: API.v1.AccountObject;
try {
account = await link.client.v1.chain.get_account(proof.signer.actor);
} catch (error) {
if (error instanceof APIError && error.code === 0) {
throw new Error("No such account");
} else {
throw error;
}
}
获取登录状态
在页面刷新后,如何重新获取登录状态。anchor-link-demo
是登录时设置的关键字,即session名。如果session存在,说明是在登录状态下。
const session = await link.restoreSession(
"anchor-link-demo"
);
if (session) {
const { actor } = session.auth;
const account = await link.client.v1.chain.get_account(actor);
setSession(session);
setAccount(account);
}
退出登录
async function doLogout() {
await link.current.clearSessions("anchor-link-demo");
setAccount(undefined);
setSession(undefined);
}
侦听退出登录
aplink
断开连接时会触发session.onAppRemoveSession
操作
export async function onAppRemoveSession() {
if (!window.__LINK__) {
return;
}
const session: LinkSession = await window.__LINK__.restoreSession(scope);
if (session) {
(session as LinkChannelSession).onAppRemoveSession(() => {
eventBus.trigger('logout');
});
}
}
如何与后端进行登录验证?
export async function login(dispatch) {
const link = initLink();
const identity = await link.login(scope);
const { account, proof, proofKey, proofValid } = await verifyProof(
link,
identity,
);
const walletAddress = proof.signer.actor.toString();
const authority = proof.signer.permission.toString();
const chainId = network.chainId;
storage.set('walletAddress', walletAddress);
storage.set('authority', authority);
storage.set('chainId', chainId);
// proof信息传给后端进行签名校验,成功返回token,失败则退出link登录。
await dispatch({
type: 'login/login',
params: {
signature: proof.signature.toString(),
message: '',
wallet_address: walletAddress,
authority,
scope: proof.scope.toString(),
expiration: proof.expiration.toString(),
},
callback: async ({ data, code }) => {
if (code === 200) {
updateToken(data.token);
await dispatch({
type: 'global/updateState',
state: {
isLogin: true,
walletAddress,
chainId,
},
});
setTimeout(eventBus.trigger, 400, 'getBalance');
} else {
await link.clearSessions(scope);
storage.remove('walletAddress');
storage.remove('authority');
storage.remove('chainId');
}
},
});
}
发起交易
单个交易,给testuser1
帐号转0.000001 MUSDT
;
注意: broadcast
设置,如果为true
,push_transaction
动作与web发起,即app只负责生成交易签名。如果为false
,则由app发起最终交易。
async function doTransact() {
if (session) {
const action = {
account: "amax.mtoken",
name: "transfer",
authorization: [session.auth],
data: {
"from": session.auth.actor,
"to": "testuser1",
"quantity": "0.000001 MUSDT",
"memo": "",
},
}
session.transact({ action }, { broadcast: false }).then((data) => {
setTransaction(data);
})
} else {
message.warn("请登录");
}
}
多个交易
生成一个NFT,执行了两个动作create
和issue
async function createrNFT() {
if (session) {
const symbol = {
id: 19999,
parent_id: 0,
};
const quantity = 1000;
const createParams = {
issuer: session.auth.actor,
maximum_supply: quantity,
token_uri: "https://kverso.mypinata.cloud/ipfs/QmUVVg7V3a9MBuxpQboc67HEhTX6hDZEunZ1Tm5Gucb6BW/1471",
ipowner: session.auth.actor,
symbol,
};
const issueParams = {
to: session.auth.actor,
quantity: {
amount: quantity,
symbol,
},
memo: "",
};
const actions = [{
account: "amax.ntoken",
name: "create",
authorization: [session.auth],
data: createParams,
}, {
account: "amax.ntoken",
name: "issue",
authorization: [session.auth],
data: issueParams,
}]
session.transact({ actions }, { broadcast: true }).then((data) => {
setTransaction(data);
})
} else {
message.warn("请登录");
}
}
相关文档
最后更新于