diff --git a/examples/__tests__/test-guest-book-borsh.ava.js b/examples/__tests__/test-guest-book-borsh.ava.js new file mode 100644 index 000000000..fb6e247a3 --- /dev/null +++ b/examples/__tests__/test-guest-book-borsh.ava.js @@ -0,0 +1,35 @@ +import { Worker } from 'near-workspaces'; +import test from 'ava'; + +test.before(async (t) => { + // Init the worker and start a Sandbox server + const worker = await Worker.init(); + + // Prepare sandbox for tests, create accounts, deploy contracts, etx. + const root = worker.rootAccount; + + // Deploy the contract. + const guestBook = await root.devDeploy('./build/guest-book-borsh.wasm'); + + // Save state for test runs + t.context.worker = worker; + t.context.accounts = { root, guestBook }; +}); + +test.after.always(async (t) => { + await t.context.worker.tearDown().catch((error) => { + console.log('Failed to tear down the worker:', error); + }); +}); + +test('Root adds non-premium message then gets', async (t) => { + const { guestBook, root } = t.context.accounts; + const messagesBefore = await guestBook.view('get_messages', {}); + t.is(messagesBefore.length, 0); + + await root.call(guestBook, 'add_message', { text: 'Some usual text' }); + + const messagesAfter = await guestBook.view('get_messages', {}); + t.is(messagesAfter.length, 1); + t.is(messagesAfter[0].text, 'Some usual text'); +}); diff --git a/examples/package.json b/examples/package.json index 7ffb6abca..cc87385f7 100644 --- a/examples/package.json +++ b/examples/package.json @@ -20,6 +20,7 @@ "build:cross-contract-call-loop": "near-sdk-js build src/counter.js build/counter.wasm && near-sdk-js build src/cross-contract-call-loop.js build/cross-contract-call-loop.wasm", "build:fungible-token-lockable": "near-sdk-js build src/fungible-token-lockable.js build/fungible-token-lockable.wasm", "build:fungible-token": "near-sdk-js build src/fungible-token.ts build/fungible-token.wasm && near-sdk-js build src/fungible-token-helper.ts build/fungible-token-helper.wasm", + "build:guest-book-borsh": "near-sdk-js build src/guest-book-borsh.ts build/guest-book-borsh.wasm", "build:non-fungible-token": "near-sdk-js build src/non-fungible-token-receiver.js build/non-fungible-token-receiver.wasm && near-sdk-js build src/non-fungible-token.js build/non-fungible-token.wasm", "build:status-message-collections": "near-sdk-js build src/status-message-collections.js build/status-message-collections.wasm", "build:parking-lot": "near-sdk-js build src/parking-lot.ts build/parking-lot.wasm", @@ -50,6 +51,7 @@ "test:cross-contract-call-loop": "ava __tests__/test-cross-contract-call-loop.ava.js", "test:fungible-token-lockable": "ava __tests__/test-fungible-token-lockable.ava.js", "test:fungible-token": "ava __tests__/test-fungible-token.ava.js", + "test:guest-book-borsh": "ava __tests__/test-guest-book-borsh.ava.js", "test:non-fungible-token": "ava __tests__/test-non-fungible-token.ava.js", "test:status-message-collections": "ava __tests__/test-status-message-collections.ava.js", "test:parking-lot": "ava __tests__/test-parking-lot.ava.js", diff --git a/examples/src/guest-book-borsh.ts b/examples/src/guest-book-borsh.ts new file mode 100644 index 000000000..45e77d03d --- /dev/null +++ b/examples/src/guest-book-borsh.ts @@ -0,0 +1,82 @@ +import { NearBindgen, near, call, view, Vector } from 'near-sdk-js'; +import * as borsh from 'borsh'; + +@NearBindgen({ + serializer(value) { + return borsh.serialize(schema, value); + }, + deserializer(value) { + return borsh.deserialize(schema, value); + }, +}) +class GuestBook { + messages: Vector = new Vector('v-uid'); + + @call({ payableFunction: true }) + // Public - Adds a new message. + add_message({ text }: { text: string }) { + // If the user attaches more than 0.1N the message is premium + const premium = near.attachedDeposit() >= BigInt(POINT_ONE); + const sender = near.predecessorAccountId(); + + const message: PostedMessage = { premium, sender, text }; + this.messages.push(message, { + serializer: (value) => borsh.serialize(MessageSchema, value), + }); + } + + @view({}) + // Returns an array of messages. + get_messages({ + from_index = 0, + limit = 10, + }: { + from_index: number; + limit: number; + }): PostedMessage[] { + return this.messages + .toArray({ + deserializer: (value) => borsh.deserialize(MessageSchema, value), + }) + .slice(from_index, from_index + limit); + } + + @view({}) + total_messages(): number { + return this.messages.length; + } +} + +const schema: borsh.Schema = { + struct: { + // Vector's internal info + messages: { + struct: { + prefix: 'string', + length: 'u32', + }, + }, + }, +}; + +const POINT_ONE = '100000000000000000000000'; + +class PostedMessage { + premium: boolean; + sender: string; + text: string; + + constructor({ premium, sender, text }: PostedMessage) { + this.premium = premium; + this.sender = sender; + this.text = text; + } +} + +const MessageSchema: borsh.Schema = { + struct: { + premium: 'bool', + sender: 'string', + text: 'string', + }, +};