Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions packages/cli/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# @growae/reactive-cli

## 0.0.5

### Patch Changes

- Release patch bump
- Updated dependencies
- @growae/[email protected]

## 0.0.4

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@growae/reactive-cli",
"version": "0.0.4",
"version": "0.0.5",
"type": "module",
"bin": {
"reactive": "./dist/cli.js",
Expand Down
8 changes: 8 additions & 0 deletions packages/connectors/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# @growae/reactive-connectors

## 0.0.5

### Patch Changes

- Release patch bump
- Updated dependencies
- @growae/[email protected]

## 0.0.4

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/connectors/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@growae/reactive-connectors",
"version": "0.0.4",
"version": "0.0.5",
"type": "module",
"main": "dist/esm/exports/index.js",
"types": "dist/types/exports/index.d.ts",
Expand Down
8 changes: 8 additions & 0 deletions packages/core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# @growae/reactive

## 0.0.5

### Patch Changes

- Release patch bump
- Updated dependencies
- @growae/[email protected]

## 0.0.4

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@growae/reactive",
"version": "0.0.4",
"version": "0.0.5",
"type": "module",
"main": "dist/esm/exports/index.js",
"types": "dist/types/exports/index.d.ts",
Expand Down
32 changes: 32 additions & 0 deletions packages/core/src/actions/callContract.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,38 @@ describe('callContract', () => {
).rejects.toThrow()
})

it('should call connector.getProvider() for signing account, not use string address', async () => {
const mockSigningAccount = { address: 'ak_test', sign: vi.fn() }
const mockConnector = {
getProvider: vi.fn().mockResolvedValue(mockSigningAccount),
}
const mockConnections = new Map([
[
'uid1',
{
activeAccount: 'ak_test',
connector: mockConnector,
networkId: 'ae_uat',
},
],
])
const mockConfig = {
getNodeClient: vi.fn(() => ({})),
state: { current: 'uid1', connections: mockConnections },
}

// Contract.initialize will fail with mock node but getProvider must be called first
await expect(
callContract(mockConfig as any, {
address: 'ct_test',
aci: {},
method: 'greet',
}),
).rejects.toThrow()

expect(mockConnector.getProvider).toHaveBeenCalledOnce()
})

it('should have DEFAULT_TTL of 300 for transaction expiry', () => {
expect(DEFAULT_TTL).toBe(300)
})
Expand Down
8 changes: 5 additions & 3 deletions packages/core/src/actions/callContract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,13 @@ export async function callContract(
throw new CallContractNoAccountError()
}

const signingAccount = connection
? await connection.connector.getProvider()
: undefined

const contractInstance = await Contract.initialize({
onNode: node,
...(connection
? { onAccount: connection.activeAccount as `ak_${string}` }
: {}),
...(signingAccount ? { onAccount: signingAccount } : {}),
aci,
address: address as `ct_${string}`,
} as any)
Expand Down
43 changes: 43 additions & 0 deletions packages/core/src/actions/compileContract.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,55 @@ describe('compileContract', () => {
})
expect(result.bytecode).toBe('cb_bytecode')
expect(result.aci).toEqual({ functions: [] })
expect(result.rawAci).toEqual([{ functions: [] }])
expect(mockCompiler.compileBySourceCode).toHaveBeenCalledWith(
'contract Test = let greet() = "hello"',
undefined,
)
})

it('should normalize array ACI from compiler — extract contract_main entry', async () => {
const mainEntry = {
contract: { kind: 'contract_main', name: 'Token', functions: [] },
}
const nsEntry = { namespace: { name: 'String', typedefs: [] } }
const mockCompiler = {
compileBySourceCode: vi.fn().mockResolvedValue({
bytecode: 'cb_bytecode',
aci: [nsEntry, mainEntry],
}),
}
const mockConfig = {}

const result = await compileContract(mockConfig as any, {
sourceCode: 'contract Token = ...',
onCompiler: mockCompiler as any,
})

expect(result.aci).toEqual(mainEntry)
expect(result.rawAci).toEqual([nsEntry, mainEntry])
expect(result.bytecode).toBe('cb_bytecode')
})

it('should fall back to first entry if no contract_main in ACI array', async () => {
const firstEntry = { namespace: { name: 'String', typedefs: [] } }
const mockCompiler = {
compileBySourceCode: vi.fn().mockResolvedValue({
bytecode: 'cb_bytecode',
aci: [firstEntry],
}),
}
const mockConfig = {}

const result = await compileContract(mockConfig as any, {
sourceCode: 'namespace String = ...',
onCompiler: mockCompiler as any,
})

expect(result.aci).toEqual(firstEntry)
expect(result.rawAci).toEqual([firstEntry])
})

it('should pass fileSystem to compiler', async () => {
const mockCompiler = {
compileBySourceCode: vi.fn().mockResolvedValue({
Expand Down
12 changes: 11 additions & 1 deletion packages/core/src/actions/compileContract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ export type CompileContractParameters = {

export type CompileContractReturnType = {
bytecode: string
/** Normalized single contract_main ACI entry — use this for UI (name, functions). */
aci: unknown
/** Full ACI array from the compiler — pass this to Contract.initialize or deployContract. */
rawAci: unknown[]
}

export type CompileContractErrorType =
Expand All @@ -36,8 +39,15 @@ export async function compileContract(

const result = await onCompiler.compileBySourceCode(sourceCode, fileSystem)

const rawAci: unknown[] = Array.isArray(result.aci)
? result.aci
: [result.aci]
const aci =
rawAci.find((e: any) => e?.contract?.kind === 'contract_main') ?? rawAci[0]

return {
bytecode: result.bytecode,
aci: result.aci,
aci,
rawAci,
}
}
28 changes: 28 additions & 0 deletions packages/core/src/actions/deployContract.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,34 @@ describe('deployContract', () => {
).rejects.toThrow(DeployContractNoAccountError)
})

it('should call connector.getProvider() for signing account, not use string address', async () => {
const mockSigningAccount = { address: 'ak_test', sign: vi.fn() }
const mockConnector = {
getProvider: vi.fn().mockResolvedValue(mockSigningAccount),
}
const mockConnections = new Map([
[
'uid1',
{
activeAccount: 'ak_test',
connector: mockConnector,
networkId: 'ae_uat',
},
],
])
const mockConfig = {
getNodeClient: vi.fn(() => ({})),
state: { current: 'uid1', connections: mockConnections },
}

// Contract.initialize will fail with mock node but getProvider must be called first
await expect(
deployContract(mockConfig as any, { bytecode: 'cb_test' }),
).rejects.toThrow()

expect(mockConnector.getProvider).toHaveBeenCalledOnce()
})

it('should have DEFAULT_TTL of 300 for transaction expiry', () => {
expect(DEFAULT_TTL).toBe(300)
})
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/actions/deployContract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,11 @@ export async function deployContract(
}

const node = config.getNodeClient({ networkId })
const signingAccount = await connection.connector.getProvider()

const contractInstance = await Contract.initialize({
onNode: node,
onAccount: connection.activeAccount as `ak_${string}`,
onAccount: signingAccount,
...(sourceCode ? { sourceCode } : {}),
...(bytecode ? { bytecode: bytecode as `cb_${string}` } : {}),
...(aci ? { aci } : {}),
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/actions/spend.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ test('spend returns Promise<SpendReturnType>', () => {
expectTypeOf(spend).returns.toEqualTypeOf<Promise<SpendReturnType>>()
})

test('SpendParameters has recipientId field', () => {
expectTypeOf<SpendParameters>().toHaveProperty('recipientId')
expectTypeOf<SpendParameters['recipientId']>().toBeString()
test('SpendParameters has recipient field', () => {
expectTypeOf<SpendParameters>().toHaveProperty('recipient')
expectTypeOf<SpendParameters['recipient']>().toBeString()
})

test('SpendParameters has amount field', () => {
Expand Down
12 changes: 6 additions & 6 deletions packages/core/src/actions/spend.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ describe('spend', () => {
await connect(config, { connector })

const result = await spend(config, {
recipientId: 'ak_recipientAddress',
recipient: 'ak_recipientAddress',
amount: 1000000000000000000n,
})

Expand All @@ -61,7 +61,7 @@ describe('spend', () => {
it('should throw when no account is connected', async () => {
const config = createTestConfig()
await expect(
spend(config, { recipientId: 'ak_test', amount: 100n }),
spend(config, { recipient: 'ak_test', amount: 100n }),
).rejects.toThrow('No connected account')
})

Expand All @@ -71,7 +71,7 @@ describe('spend', () => {
await connect(config, { connector })

await spend(config, {
recipientId: 'ak_recipient',
recipient: 'ak_recipient',
amount: 100n,
})

Expand All @@ -84,7 +84,7 @@ describe('spend', () => {
await connect(config, { connector })

await spend(config, {
recipientId: 'ak_recipient',
recipient: 'ak_recipient',
amount: 100n,
})

Expand All @@ -99,7 +99,7 @@ describe('spend', () => {
await connect(config, { connector })

await spend(config, {
recipientId: 'ak_recipient',
recipient: 'ak_recipient',
amount: 100n,
options: { nonce: 42 },
})
Expand All @@ -118,7 +118,7 @@ describe('spend', () => {
await connect(config, { connector })

await spend(config, {
recipientId: 'ak_recipient',
recipient: 'ak_recipient',
amount: 100n,
})

Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/actions/spend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { Config } from '../createConfig'
import type { BaseErrorType, ErrorType } from '../errors/base'

export type SpendParameters = {
recipientId: string
recipient: string
amount: bigint | string
payload?: string | undefined
networkId?: string | undefined
Expand All @@ -27,7 +27,7 @@ export async function spend(
parameters: SpendParameters,
): Promise<SpendReturnType> {
const {
recipientId,
recipient,
amount,
payload,
networkId,
Expand All @@ -50,7 +50,7 @@ export async function spend(
const spendTx = buildTx({
tag: Tag.SpendTx,
senderId,
recipientId,
recipientId: recipient,
amount: BigInt(amount),
payload: payload ?? '',
fee: txOptions.fee ? BigInt(txOptions.fee) : undefined,
Expand Down
Loading
Loading